@redocly/openapi-core
Version:
See https://github.com/Redocly/redocly-cli
53 lines • 2.78 kB
JavaScript
import { resolveSchema } from '../utils.js';
export const SpecDiscriminatorDefaultMapping = () => {
let componentsSchemaNames = [];
return {
Root: {
enter(root) {
// Starting from the Root to ensure it runs before other visitors that might use componentsSchemaNames.
componentsSchemaNames = Object.keys(root.components?.schemas || {});
},
},
Schema: {
leave(schema, ctx) {
const discriminatedPropertyName = schema.discriminator?.propertyName;
if (!discriminatedPropertyName)
return;
const defaultMapping = schema.discriminator?.defaultMapping;
if (defaultMapping === undefined) {
const visited = new Set();
const isDiscriminatorPropertyRequired = (schemaOrRef, resolveFrom) => {
const resolved = resolveSchema(schemaOrRef, ctx, resolveFrom);
if (!resolved.schema || visited.has(resolved.schema)) {
return true;
}
visited.add(resolved.schema);
if (resolved.schema.required?.includes(discriminatedPropertyName) ||
resolved.schema.allOf?.some((s) => isDiscriminatorPropertyRequired(s, resolved.location)) ||
resolved.schema.oneOf?.every((s) => isDiscriminatorPropertyRequired(s, resolved.location)) ||
resolved.schema.anyOf?.every((s) => isDiscriminatorPropertyRequired(s, resolved.location))) {
return true;
}
return false;
};
if (!isDiscriminatorPropertyRequired(schema)) {
ctx.report({
message: `Discriminator with optional property '${discriminatedPropertyName}' must include a defaultMapping field.`,
location: ctx.location.child('discriminator'),
});
}
}
else {
if (ctx.resolve({ $ref: defaultMapping }).node === undefined &&
!componentsSchemaNames.includes(defaultMapping)) {
ctx.report({
message: `defaultMapping value '${defaultMapping}' does not point to an existing schema component.`,
location: ctx.location.child(['discriminator', 'defaultMapping']),
});
}
}
},
},
};
};
//# sourceMappingURL=spec-discriminator-defaultMapping.js.map