@langchain/core
Version:
Core LangChain.js abstractions and schemas
168 lines (167 loc) • 5.45 kB
JavaScript
import { encodePointer } from "./pointer.js";
export const schemaKeyword = {
additionalItems: true,
unevaluatedItems: true,
items: true,
contains: true,
additionalProperties: true,
unevaluatedProperties: true,
propertyNames: true,
not: true,
if: true,
then: true,
else: true,
};
export const schemaArrayKeyword = {
prefixItems: true,
items: true,
allOf: true,
anyOf: true,
oneOf: true,
};
export const schemaMapKeyword = {
$defs: true,
definitions: true,
properties: true,
patternProperties: true,
dependentSchemas: true,
};
export const ignoredKeyword = {
id: true,
$id: true,
$ref: true,
$schema: true,
$anchor: true,
$vocabulary: true,
$comment: true,
default: true,
enum: true,
const: true,
required: true,
type: true,
maximum: true,
minimum: true,
exclusiveMaximum: true,
exclusiveMinimum: true,
multipleOf: true,
maxLength: true,
minLength: true,
pattern: true,
format: true,
maxItems: true,
minItems: true,
uniqueItems: true,
maxProperties: true,
minProperties: true,
};
/**
* Default base URI for schemas without an $id.
* https://json-schema.org/draft/2019-09/json-schema-core.html#initial-base
* https://tools.ietf.org/html/rfc3986#section-5.1
*/
export let initialBaseURI =
// @ts-ignore
typeof self !== "undefined" &&
self.location &&
self.location.origin !== "null"
? //@ts-ignore
/* #__PURE__ */ new URL(self.location.origin + self.location.pathname + location.search)
: /* #__PURE__ */ new URL("https://github.com/cfworker");
export function dereference(schema, lookup = Object.create(null), baseURI = initialBaseURI, basePointer = "") {
if (schema && typeof schema === "object" && !Array.isArray(schema)) {
const id = schema.$id || schema.id;
if (id) {
const url = new URL(id, baseURI.href);
if (url.hash.length > 1) {
lookup[url.href] = schema;
}
else {
url.hash = ""; // normalize hash https://url.spec.whatwg.org/#dom-url-hash
if (basePointer === "") {
baseURI = url;
}
else {
dereference(schema, lookup, baseURI);
}
}
}
}
else if (schema !== true && schema !== false) {
return lookup;
}
// compute the schema's URI and add it to the mapping.
const schemaURI = baseURI.href + (basePointer ? "#" + basePointer : "");
if (lookup[schemaURI] !== undefined) {
throw new Error(`Duplicate schema URI "${schemaURI}".`);
}
lookup[schemaURI] = schema;
// exit early if this is a boolean schema.
if (schema === true || schema === false) {
return lookup;
}
// set the schema's absolute URI.
if (schema.__absolute_uri__ === undefined) {
Object.defineProperty(schema, "__absolute_uri__", {
enumerable: false,
value: schemaURI,
});
}
// if a $ref is found, resolve it's absolute URI.
if (schema.$ref && schema.__absolute_ref__ === undefined) {
const url = new URL(schema.$ref, baseURI.href);
url.hash = url.hash; // normalize hash https://url.spec.whatwg.org/#dom-url-hash
Object.defineProperty(schema, "__absolute_ref__", {
enumerable: false,
value: url.href,
});
}
// if a $recursiveRef is found, resolve it's absolute URI.
if (schema.$recursiveRef && schema.__absolute_recursive_ref__ === undefined) {
const url = new URL(schema.$recursiveRef, baseURI.href);
url.hash = url.hash; // normalize hash https://url.spec.whatwg.org/#dom-url-hash
Object.defineProperty(schema, "__absolute_recursive_ref__", {
enumerable: false,
value: url.href,
});
}
// if an $anchor is found, compute it's URI and add it to the mapping.
if (schema.$anchor) {
const url = new URL("#" + schema.$anchor, baseURI.href);
lookup[url.href] = schema;
}
// process subschemas.
for (let key in schema) {
if (ignoredKeyword[key]) {
continue;
}
const keyBase = `${basePointer}/${encodePointer(key)}`;
const subSchema = schema[key];
if (Array.isArray(subSchema)) {
if (schemaArrayKeyword[key]) {
const length = subSchema.length;
for (let i = 0; i < length; i++) {
dereference(subSchema[i], lookup, baseURI, `${keyBase}/${i}`);
}
}
}
else if (schemaMapKeyword[key]) {
for (let subKey in subSchema) {
dereference(subSchema[subKey], lookup, baseURI, `${keyBase}/${encodePointer(subKey)}`);
}
}
else {
dereference(subSchema, lookup, baseURI, keyBase);
}
}
return lookup;
}
// schema identification examples
// https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.appendix.A
// $ref delegation
// https://github.com/json-schema-org/json-schema-spec/issues/514
// output format
// https://json-schema.org/draft/2019-09/json-schema-core.html#output
// JSON pointer
// https://tools.ietf.org/html/rfc6901
// JSON relative pointer
// https://tools.ietf.org/html/draft-handrews-relative-json-pointer-01