Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for joi-schema labels. Support for function typed schemas #184

Merged
merged 7 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

strategy:
matrix:
node-version: [12, 14, 16]
node-version: [14, 16, 18]

steps:
- uses: actions/checkout@v2
Expand Down
45 changes: 39 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ exports.plugin = {
resolvedSchemasObject[path] = await handler(request);
}

const schema = internals.routeMap.get(internals.createRouteMethodString(request.route.path, request.route.method));
let schema = internals.routeMap.get(internals.createRouteMethodString(request.route.path, request.route.method));

if (typeof schema === 'function') {
schema = schema(request.response.source, request, true);
}

const { headerQueryMap, dataset } = internals.processSchema(schema, resolvedSchemasObject, request.response.source, options.resultKey);

// If the dataset isn't an array or object, we have to return it, as it is
Expand Down Expand Up @@ -186,12 +191,23 @@ internals.parseSchema = (joiSchema, dynamicSchemas, keyName, path, parentIsArray
const key = Object.keys(child)[0];
child[key].unshift(keyName);

const label = joiSchema.keys[key]?.flags?.label;
// If the previous call was not for a joi schema of type array, we alter the keys to prefix them with the keyName
if (!parentIsArray) {
const name = `${keyName}.${key}`;
child[name] = child[key];
const name = label || `${keyName}.${key}`;

if (name !== key) {
child[name] = child[key];
delete child[key];
}
}
else if (label) {
const name = label;

delete child[key];
if (name !== key) {
child[name] = child[key];
delete child[key];
}
}

return child;
Expand All @@ -202,6 +218,7 @@ internals.parseSchema = (joiSchema, dynamicSchemas, keyName, path, parentIsArray

// FUTURE: Make it work for arrays with multiple item definitions/alternatives
const item = joiSchema.items[0];
const label = item.flags?.label;
const parsedItem = internals.parseSchema(item, dynamicSchemas, keyName, path, true);

if (keyName && parsedItem) {
Expand All @@ -211,7 +228,17 @@ internals.parseSchema = (joiSchema, dynamicSchemas, keyName, path, parentIsArray
prefixedItemArray.push(parsedItem.map((headerQuery) => {

const key = Object.keys(headerQuery)[0];
const name = parsedItem.length === 1 ? `${keyName}_${i}` : `${keyName}_${i}.${key}`;
let name;
if (label === '_') {
name = parsedItem.length === 1 ? `${keyName}${i === 0 ? '' : ` ${i + 1}`}` : `${key}${i === 0 ? '' : ` ${i + 1}`}`;
}
else if (label) {
name = parsedItem.length === 1 ? `${label}${i === 0 ? '' : ` ${i + 1}`}` : `${label}${i === 0 ? '' : ` ${i + 1}`} ${key}`;
}
else {
name = parsedItem.length === 1 ? `${keyName} ${i + 1}` : `${keyName} ${i + 1} ${key}`;
}

const sliced = headerQuery[key].slice();

// We splice the index after the array key
Expand All @@ -227,6 +254,11 @@ internals.parseSchema = (joiSchema, dynamicSchemas, keyName, path, parentIsArray
return parsedItem;
}

// Check if the key is in the root by checking if the path is composed
if (!path.includes('.')) {
return [{ [joiSchema.flags?.label || keyName]: [keyName] }];
}

// First square brackets are used to convert to String, second brackets are used to convert to an array
return [{ [keyName]: [keyName] }];
};
Expand Down Expand Up @@ -384,7 +416,8 @@ internals.escapeQuotesInString = (str) => {
internals.dateToISOString = (str) => {

if (str instanceof Date) {
return str.toISOString();
const dateParts = str.toISOString().split('T');
return `${dateParts[0]} ${dateParts[1].split('.')[0]}`;
}

return str;
Expand Down
Loading
Loading