| "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"); |
| const URI = require("uri-js"); |
| // 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(id = "", normalize) { |
| if (normalize !== false) |
| id = normalizeId(id); |
| const p = URI.parse(id); |
| return _getFullPath(p); |
| } |
| exports.getFullPath = getFullPath; |
| function _getFullPath(p) { |
| return URI.serialize(p).split("#")[0] + "#"; |
| } |
| exports._getFullPath = _getFullPath; |
| const TRAILING_SLASH_HASH = /#\/?$/; |
| function normalizeId(id) { |
| return id ? id.replace(TRAILING_SLASH_HASH, "") : ""; |
| } |
| exports.normalizeId = normalizeId; |
| function resolveUrl(baseId, id) { |
| id = normalizeId(id); |
| return URI.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 } = this.opts; |
| const schId = normalizeId(schema[schemaId] || baseId); |
| const baseIds = { "": schId }; |
| const pathPrefix = getFullPath(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) { |
| ref = normalizeId(baseId ? URI.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 |