in packages/extensions/core/src/lib/plugins/subset-schemas-deduplicator.ts [61:139]
visitSchemas<T>(container: ProxyObject<Record<string, T>>, originalNodes: () => Iterable<Node>) {
const xMsMetadata = "x-ms-metadata";
const updatedSchemas: any = {};
// get all the schemas and associate them with their uid
// this will allow us to place the value in the right place at the end
const schemas: Array<AnyObject> = [];
for (const { key, value } of originalNodes()) {
if (value.type === "object" || value.type === undefined) {
// only do subset reduction on objects
schemas.push({ value, uid: key });
} else {
updatedSchemas[key] = value;
}
}
// sort by apiVersion from latest to oldest
schemas.sort((a, b) => {
const aMaxVersion = maximum(a.value[xMsMetadata].apiVersions);
const bMaxVersion = maximum(b.value[xMsMetadata].apiVersions);
return gt(aMaxVersion, bMaxVersion) ? -1 : lt(aMaxVersion, bMaxVersion) ? 1 : 0;
});
// deduplicate/reduce
for (const { value: currentSchema } of visit(schemas)) {
for (const { value: anotherSchema } of visit(schemas)) {
const currentSchemaName = currentSchema.value[xMsMetadata].name;
const anotherSchemaName = anotherSchema.value[xMsMetadata].name;
if (currentSchemaName === anotherSchemaName && currentSchema.uid !== anotherSchema.uid) {
const skipList = ["description", "enum", "readOnly", "required", "x-ms-original", "x-ms-examples"];
const additiveFieldsList = ["properties", "allOf", "required"];
// filter out metadata
const { "x-ms-metadata": metadataAnotherSchema, ...filteredAnotherSchema } = anotherSchema.value;
const { "x-ms-metadata": metadataCurrentSchema, ...filteredCurrentSchema } = currentSchema.value;
const subsetRelation = getSubsetRelation(
filteredAnotherSchema,
filteredCurrentSchema,
additiveFieldsList,
skipList,
);
if (subsetRelation.isSubset !== false) {
const supersetEquivSchema = getSupersetSchema(
filteredAnotherSchema,
filteredCurrentSchema,
additiveFieldsList,
subsetRelation,
`#/components/schemas/${anotherSchema.uid}`,
);
const subsetEquivSchema = getSubsetSchema(filteredAnotherSchema, subsetRelation);
// gs: added -- ensure that properties left beg
if (currentSchema.value.required && supersetEquivSchema.properties) {
const sesNames = Object.getOwnPropertyNames(supersetEquivSchema.properties);
supersetEquivSchema.required = currentSchema.value.required.filter(
(each: any) => sesNames.indexOf(each) > -1,
);
}
// replace with equivalent schema and put back metadata.
currentSchema.value = { "x-ms-metadata": metadataCurrentSchema, ...supersetEquivSchema };
anotherSchema.value = { "x-ms-metadata": metadataAnotherSchema, ...subsetEquivSchema };
}
}
}
}
// get back updated schemas
for (const schema of schemas) {
updatedSchemas[schema.uid] = schema.value;
}
// finish up
for (const { key, pointer } of originalNodes()) {
container[key] = { value: updatedSchemas[key], pointer, recurse: true };
}
}