"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSchemaRefs = exports.resolveUrl = exports.normalizeId = exports._getFullPath = exports.getFullPath = exports.inlineRef = void 0; const util_1 = require("./util"); const equal = require("fast-deep-equal"); const traverse = require("json-schema-traverse"); // TODO refactor to use keyword definitions const SIMPLE_INLINED = new Set([ "type", "format", "pattern", "maxLength", "minLength", "maxProperties", "minProperties", "maxItems", "minItems", "maximum", "minimum", "uniqueItems", "multipleOf", "required", "enum", "const", ]); function inlineRef(schema, limit = true) { if (typeof schema == "boolean") return true; if (limit === true) return !hasRef(schema); if (!limit) return false; return countKeys(schema) <= limit; } exports.inlineRef = inlineRef; const REF_KEYWORDS = new Set([ "$ref", "$recursiveRef", "$recursiveAnchor", "$dynamicRef", "$dynamicAnchor", ]); function hasRef(schema) { for (const key in schema) { if (REF_KEYWORDS.has(key)) return true; const sch = schema[key]; if (Array.isArray(sch) && sch.some(hasRef)) return true; if (typeof sch == "object" && hasRef(sch)) return true; } return false; } function countKeys(schema) { let count = 0; for (const key in schema) { if (key === "$ref") return Infinity; count++; if (SIMPLE_INLINED.has(key)) continue; if (typeof schema[key] == "object") { (0, util_1.eachItem)(schema[key], (sch) => (count += countKeys(sch))); } if (count === Infinity) return Infinity; } return count; } function getFullPath(resolver, id = "", normalize) { if (normalize !== false) id = normalizeId(id); const p = resolver.parse(id); return _getFullPath(resolver, p); } exports.getFullPath = getFullPath; function _getFullPath(resolver, p) { const serialized = resolver.serialize(p); return serialized.split("#")[0] + "#"; } exports._getFullPath = _getFullPath; const TRAILING_SLASH_HASH = /#\/?$/; function normalizeId(id) { return id ? id.replace(TRAILING_SLASH_HASH, "") : ""; } exports.normalizeId = normalizeId; function resolveUrl(resolver, baseId, id) { id = normalizeId(id); return resolver.resolve(baseId, id); } exports.resolveUrl = resolveUrl; const ANCHOR = /^[a-z_][-a-z0-9._]*$/i; function getSchemaRefs(schema, baseId) { if (typeof schema == "boolean") return {}; const { schemaId, uriResolver } = this.opts; const schId = normalizeId(schema[schemaId] || baseId); const baseIds = { "": schId }; const pathPrefix = getFullPath(uriResolver, schId, false); const localRefs = {}; const schemaRefs = new Set(); traverse(schema, { allKeys: true }, (sch, jsonPtr, _, parentJsonPtr) => { if (parentJsonPtr === undefined) return; const fullPath = pathPrefix + jsonPtr; let baseId = baseIds[parentJsonPtr]; if (typeof sch[schemaId] == "string") baseId = addRef.call(this, sch[schemaId]); addAnchor.call(this, sch.$anchor); addAnchor.call(this, sch.$dynamicAnchor); baseIds[jsonPtr] = baseId; function addRef(ref) { // eslint-disable-next-line @typescript-eslint/unbound-method const _resolve = this.opts.uriResolver.resolve; ref = normalizeId(baseId ? _resolve(baseId, ref) : ref); if (schemaRefs.has(ref)) throw ambiguos(ref); schemaRefs.add(ref); let schOrRef = this.refs[ref]; if (typeof schOrRef == "string") schOrRef = this.refs[schOrRef]; if (typeof schOrRef == "object") { checkAmbiguosRef(sch, schOrRef.schema, ref); } else if (ref !== normalizeId(fullPath)) { if (ref[0] === "#") { checkAmbiguosRef(sch, localRefs[ref], ref); localRefs[ref] = sch; } else { this.refs[ref] = fullPath; } } return ref; } function addAnchor(anchor) { if (typeof anchor == "string") { if (!ANCHOR.test(anchor)) throw new Error(`invalid anchor "${anchor}"`); addRef.call(this, `#${anchor}`); } } }); return localRefs; function checkAmbiguosRef(sch1, sch2, ref) { if (sch2 !== undefined && !equal(sch1, sch2)) throw ambiguos(ref); } function ambiguos(ref) { return new Error(`reference "${ref}" resolves to more than one schema`); } } exports.getSchemaRefs = getSchemaRefs; //# sourceMappingURL=resolve.js.map