88 lines
2.0 KiB
TypeScript
88 lines
2.0 KiB
TypeScript
import { JsonSchema, JsonSchema1 } from '@nx/nx-dev/models-package';
|
|
import { get as pointerGet } from 'jsonpointer';
|
|
|
|
/**
|
|
* @param reference '#' is root
|
|
* @param lookup Instantiated Lookup class
|
|
*/
|
|
export function getSchemaFromReference(
|
|
reference: string,
|
|
lookup: Lookup
|
|
): JsonSchema | undefined {
|
|
return getSchemaFromResult(loadReference(reference, lookup));
|
|
}
|
|
|
|
export function loadReference(reference: string, lookup: Lookup): LookupResult {
|
|
return lookup.getSchema({ $ref: reference });
|
|
}
|
|
|
|
export function getSchemaFromResult(
|
|
result: LookupResult
|
|
): JsonSchema | undefined {
|
|
return result === undefined ? undefined : result.schema;
|
|
}
|
|
|
|
export type LookupResult =
|
|
| undefined
|
|
| {
|
|
schema: JsonSchema;
|
|
baseReference?: string;
|
|
};
|
|
|
|
function isReference(s: JsonSchema1): boolean {
|
|
return s.$ref !== undefined;
|
|
}
|
|
|
|
export interface Lookup {
|
|
getSchema: (schema: JsonSchema) => LookupResult;
|
|
}
|
|
|
|
export class IdLookup {
|
|
getSchema(schema: JsonSchema): LookupResult {
|
|
if (typeof schema === 'boolean') {
|
|
return { schema };
|
|
}
|
|
|
|
if (isReference(schema)) {
|
|
return undefined;
|
|
}
|
|
|
|
return { schema };
|
|
}
|
|
}
|
|
|
|
export class InternalLookup {
|
|
constructor(private schema: JsonSchema) {}
|
|
|
|
getSchema(schema: JsonSchema): LookupResult {
|
|
if (schema === undefined) {
|
|
return undefined;
|
|
}
|
|
|
|
if (typeof schema === 'boolean') return { schema };
|
|
|
|
if (schema.$ref === undefined) return { schema };
|
|
|
|
const ref = schema.$ref;
|
|
if (!ref.startsWith('#')) {
|
|
// We do not support non-internal references
|
|
console.error(
|
|
'[SCHEMA] The schema appears to have non-internal references which is not supported:',
|
|
ref
|
|
);
|
|
return undefined;
|
|
}
|
|
|
|
const result = pointerGet(this.schema, ref.slice(1));
|
|
if (result === undefined) return undefined;
|
|
|
|
const subResult = this.getSchema(result);
|
|
if (subResult === undefined) return undefined;
|
|
|
|
return {
|
|
schema: subResult.schema,
|
|
baseReference: subResult.baseReference ?? ref,
|
|
};
|
|
}
|
|
}
|