You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					155 lines
				
				4.9 KiB
			
		
		
			
		
	
	
					155 lines
				
				4.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"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
							 |