/* SPDX-License-Identifier: MIT * * jsonschema is licensed under MIT license. * * Copyright (C) 2012-2015 Tom de Grunt <tom@degrunt.nl> * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #IMPORT common/jsonschema/urllib_mock.js AS urilib #IMPORT common/jsonschema/helpers.js function SchemaScanResult(found, ref){ this.id = found; this.ref = ref; } #EXPORT SchemaScanResult /** * Adds a schema with a certain urn to the Validator instance. * @param string uri * @param object schema * @return {Object} */ function scan(base, schema){ function scanSchema(baseuri, schema){ if(!schema || typeof schema!='object') return; // Mark all referenced schemas so we can tell later which schemas are referred to, but never defined if(schema.$ref){ var resolvedUri = urilib.resolve(baseuri, schema.$ref); ref[resolvedUri] = ref[resolvedUri] ? ref[resolvedUri]+1 : 0; return; } var id = schema.$id || schema.id; var ourBase = id ? urilib.resolve(baseuri, id) : baseuri; if (ourBase) { // If there's no fragment, append an empty one if(ourBase.indexOf('#')<0) ourBase += '#'; if(found[ourBase]){ if(!helpers.deepCompareStrict(found[ourBase], schema)){ throw new Error('Schema <'+ourBase+'> already exists with different definition'); } return found[ourBase]; } found[ourBase] = schema; // strip trailing fragment if(ourBase[ourBase.length-1]=='#'){ found[ourBase.substring(0, ourBase.length-1)] = schema; } } scanArray(ourBase+'/items', (Array.isArray(schema.items)?schema.items:[schema.items])); scanArray(ourBase+'/extends', (Array.isArray(schema.extends)?schema.extends:[schema.extends])); scanSchema(ourBase+'/additionalItems', schema.additionalItems); scanObject(ourBase+'/properties', schema.properties); scanSchema(ourBase+'/additionalProperties', schema.additionalProperties); scanObject(ourBase+'/definitions', schema.definitions); scanObject(ourBase+'/patternProperties', schema.patternProperties); scanObject(ourBase+'/dependencies', schema.dependencies); scanArray(ourBase+'/disallow', schema.disallow); scanArray(ourBase+'/allOf', schema.allOf); scanArray(ourBase+'/anyOf', schema.anyOf); scanArray(ourBase+'/oneOf', schema.oneOf); scanSchema(ourBase+'/not', schema.not); } function scanArray(baseuri, schemas){ if(!Array.isArray(schemas)) return; for(var i=0; i<schemas.length; i++){ scanSchema(baseuri+'/'+i, schemas[i]); } } function scanObject(baseuri, schemas){ if(!schemas || typeof schemas!='object') return; for(var p in schemas){ scanSchema(baseuri+'/'+p, schemas[p]); } } var found = {}; var ref = {}; scanSchema(base, schema); return new SchemaScanResult(found, ref); }; #EXPORT scan