72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import { deepCopy, json, schema } from '@angular-devkit/core';
|
|
import { visitJsonSchema } from '@angular-devkit/core/src/json/schema';
|
|
import * as Ajv from 'ajv';
|
|
import * as Url from 'url';
|
|
|
|
export interface SchemaFlattener {
|
|
flatten: (schema) => json.JsonObject;
|
|
}
|
|
|
|
function _resolver(
|
|
ref: string,
|
|
validate?: Ajv.ValidateFunction
|
|
): { context?: Ajv.ValidateFunction; schema?: json.JsonObject } {
|
|
if (!validate || !ref) {
|
|
return {};
|
|
}
|
|
|
|
const schema = (validate as any).schemaEnv.root.schema;
|
|
const id = typeof schema === 'object' ? schema.$id : null;
|
|
|
|
let fullReference = ref;
|
|
if (typeof id === 'string') {
|
|
fullReference = Url.resolve(id, ref);
|
|
|
|
if (ref.startsWith('#')) {
|
|
fullReference = id + fullReference;
|
|
}
|
|
}
|
|
|
|
if (fullReference.startsWith('#')) {
|
|
fullReference = fullReference.slice(0, -1);
|
|
}
|
|
const resolvedSchema = this._ajv.getSchema(fullReference);
|
|
|
|
return {
|
|
context: resolvedSchema?.schemaEnv.validate,
|
|
schema: resolvedSchema?.schema as json.JsonObject,
|
|
};
|
|
}
|
|
|
|
export function createSchemaFlattener(
|
|
formats: schema.SchemaFormat[] = []
|
|
): SchemaFlattener {
|
|
const ajv = new Ajv({ passContext: true });
|
|
for (const format of formats) {
|
|
ajv.addFormat(format.name, format.formatter as any);
|
|
}
|
|
return {
|
|
flatten: function (schema) {
|
|
const validate = ajv.removeSchema(schema).compile(schema);
|
|
function visitor(current, pointer, parentSchema, index) {
|
|
if (
|
|
current &&
|
|
parentSchema &&
|
|
index &&
|
|
json.isJsonObject(current) &&
|
|
current.hasOwnProperty('$ref') &&
|
|
typeof current['$ref'] == 'string'
|
|
) {
|
|
const resolved = _resolver(current['$ref'], validate);
|
|
if (resolved.schema) {
|
|
parentSchema[index] = resolved.schema;
|
|
}
|
|
}
|
|
}
|
|
const schemaCopy = deepCopy(validate.schema) as json.JsonObject;
|
|
visitJsonSchema(schemaCopy, visitor);
|
|
return schemaCopy;
|
|
},
|
|
};
|
|
}
|