@redocly/openapi-core
Version:
See https://github.com/Redocly/redocly-cli
64 lines • 3.11 kB
JavaScript
import { getOwn } from '../../utils/get-own.js';
import { isNotEmptyArray } from '../../utils/is-not-empty-array.js';
import { resolveSchema } from '../utils.js';
export const NoRequiredSchemaPropertiesUndefined = () => {
const parents = [];
return {
Schema: {
leave(_) {
parents.pop();
},
enter(currentSchema, ctx) {
parents.push(currentSchema);
if (!currentSchema.required)
return;
const hasProperty = (schemaOrRef, propertyName, visited, resolveFrom) => {
const { schema, location } = resolveSchema(schemaOrRef, ctx, resolveFrom);
if (!schema || visited.has(schema))
return false;
visited.add(schema);
if (schema.properties && getOwn(schema.properties, propertyName) !== undefined) {
return true;
}
if (schema.allOf?.some((s) => hasProperty(s, propertyName, visited, location))) {
return true;
}
if (isNotEmptyArray(schema.anyOf) &&
schema.anyOf.every((s) => hasProperty(s, propertyName, new Set(visited), location))) {
return true;
}
if (isNotEmptyArray(schema.oneOf) &&
schema.oneOf.every((s) => hasProperty(s, propertyName, new Set(visited), location))) {
return true;
}
return false;
};
const isCompositionChild = (parent, child) => {
const matchesChild = (s) => resolveSchema(s, ctx).schema === child;
return !!(parent.allOf?.some(matchesChild) ||
parent.anyOf?.some(matchesChild) ||
parent.oneOf?.some(matchesChild));
};
const findCompositionRoot = (i, child) => {
if (i < 0)
return undefined;
const parent = parents[i];
return isCompositionChild(parent, child)
? (findCompositionRoot(i - 1, parent) ?? parent)
: undefined;
};
const compositionRoot = findCompositionRoot(parents.length - 2, currentSchema);
for (const [i, requiredProperty] of currentSchema.required.entries()) {
if (!hasProperty(currentSchema, requiredProperty, new Set()) &&
!hasProperty(compositionRoot, requiredProperty, new Set())) {
ctx.report({
message: `Required property '${requiredProperty}' is not defined.`,
location: ctx.location.child(['required', i]),
});
}
}
},
},
};
};
//# sourceMappingURL=no-required-schema-properties-undefined.js.map