botbook/node_modules/json-schema-library/lib/compile/getRef.ts
Rodrigo Rodriguez 6ae15fe3e5 Updated.
2024-09-04 13:13:15 -03:00

83 lines
2.4 KiB
TypeScript

import { get } from "@sagold/json-pointer";
import splitRef from "./splitRef";
import getTypeOf from "../getTypeOf";
import { JsonSchema } from "../types";
import { Context } from "./types";
const suffixes = /(#|\/)+$/g;
const isObject = (val: unknown): val is Record<string, any> => getTypeOf(val) === "object";
// 1. combined is known
// 2. base or pointer is known
// 3. base + pointer is known
export default function getRef(context: Context, rootSchema: JsonSchema, $ref: string): JsonSchema {
if (isObject($ref)) {
$ref = $ref.__ref || $ref.$ref;
}
if ($ref == null) {
return rootSchema;
}
let schema;
// is it a known $ref?
const $remote = $ref.replace(suffixes, "");
if (context.remotes[$remote]) {
schema = context.remotes[$remote];
if (schema && schema.$ref) {
return getRef(context, rootSchema, schema.$ref);
}
return schema;
}
if (context.ids[$ref]) {
schema = get(rootSchema, context.ids[$ref]);
if (schema && schema.$ref) {
return getRef(context, rootSchema, schema.$ref);
}
return schema;
}
// is it a ref with host/pointer?
const fragments = splitRef($ref);
if (fragments.length === 0) {
return rootSchema;
}
if (fragments.length === 1) {
$ref = fragments[0];
if (context.remotes[$ref]) {
schema = context.remotes[$ref];
return getRef(context, rootSchema, schema.$ref);
}
if (context.ids[$ref]) {
schema = get(rootSchema, context.ids[$ref]);
if (schema && schema.$ref) {
return getRef(context, rootSchema, schema.$ref);
}
return schema;
}
}
if (fragments.length === 2) {
const base = fragments[0];
$ref = fragments[1];
if (context.remotes[base]) {
if (context.remotes[base].getRef) {
return context.remotes[base].getRef($ref);
}
// console.log("warning: uncompiled remote - context may be wrong", base);
return getRef(context, context.remotes[base], $ref);
}
if (context.ids[base]) {
return getRef(context, get(rootSchema, context.ids[base]), $ref);
}
}
schema = get(rootSchema, context.ids[$ref] || $ref);
if (schema && schema.$ref) {
return getRef(context, rootSchema, schema.$ref);
}
return schema;
}