@apidevtools/json-schema-ref-parser
Version:
Parse, Resolve, and Dereference JSON Schema $ref pointers
83 lines (82 loc) • 2.99 kB
JavaScript
import * as url from "./url.js";
export function getSchemaBasePath(basePath, value, legacyId = false) {
const schemaId = getSchemaId(value, legacyId);
return schemaId ? url.resolve(basePath, schemaId) : basePath;
}
export function usesDynamicIdScope(value) {
if (!value || typeof value !== "object" || ArrayBuffer.isView(value)) {
return false;
}
// A schema can omit `$schema`, but an explicit identifier still establishes
// a base URI for references inside that resource.
if (getSchemaId(value)) {
return true;
}
const schema = value.$schema;
if (typeof schema === "string" &&
(schema.includes("draft-04/") ||
schema.includes("draft-06/") ||
schema.includes("draft-07/") ||
schema.includes("draft/2019-09/") ||
schema.includes("draft/2020-12/") ||
schema.includes("oas/3.1/"))) {
return true;
}
const openapi = value.openapi;
return typeof openapi === "string" && /^3\.1(?:\.|$)/.test(openapi);
}
export function registerSchemaResources($refs, basePath, value, pathType, dynamicIdScope = false) {
if (!dynamicIdScope) {
return;
}
const seen = new Set();
const visit = (node, scopeBase, inheritedLegacyId) => {
if (!node || typeof node !== "object" || ArrayBuffer.isView(node) || seen.has(node)) {
return;
}
seen.add(node);
const legacyId = getSchemaIdMode(node, inheritedLegacyId);
const nextScopeBase = getSchemaBasePath(scopeBase, node, legacyId);
if (nextScopeBase !== scopeBase) {
$refs._addAlias(nextScopeBase, node, pathType, dynamicIdScope, legacyId);
}
for (const key of Object.keys(node)) {
visit(node[key], nextScopeBase, legacyId);
}
};
visit(value, basePath, false);
}
export function getSchemaId(value, inheritedLegacyId = false) {
if (!value || typeof value !== "object") {
return undefined;
}
const legacyId = getSchemaIdMode(value, inheritedLegacyId);
const schemaId = legacyId ? value.id : value.$id;
if (typeof schemaId === "string" && schemaId.length > 0) {
return schemaId;
}
return undefined;
}
export function getSchemaIdMode(value, inheritedLegacyId = false) {
if (!value || typeof value !== "object") {
return inheritedLegacyId;
}
const schema = value.$schema;
if (typeof schema === "string") {
if (schema.includes("draft-04/")) {
return true;
}
if (schema.includes("draft-06/") ||
schema.includes("draft-07/") ||
schema.includes("draft/2019-09/") ||
schema.includes("draft/2020-12/") ||
schema.includes("oas/3.1/")) {
return false;
}
}
const openapi = value.openapi;
if (typeof openapi === "string" && /^3\.1(?:\.|$)/.test(openapi)) {
return false;
}
return inheritedLegacyId;
}