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.
74 lines
2.6 KiB
74 lines
2.6 KiB
|
|
var urilib = require('url'); |
|
var helpers = require('./helpers'); |
|
|
|
module.exports.SchemaScanResult = SchemaScanResult; |
|
function SchemaScanResult(found, ref){ |
|
this.id = found; |
|
this.ref = ref; |
|
} |
|
|
|
/** |
|
* Adds a schema with a certain urn to the Validator instance. |
|
* @param string uri |
|
* @param object schema |
|
* @return {Object} |
|
*/ |
|
module.exports.scan = 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 ourBase = schema.id ? urilib.resolve(baseuri, schema.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 <'+schema+'> 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', ((schema.items instanceof Array)?schema.items:[schema.items])); |
|
scanArray(ourBase+'/extends', ((schema.extends instanceof Array)?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(!(schemas instanceof Array)) 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 = {}; |
|
var schemaUri = base; |
|
scanSchema(base, schema); |
|
return new SchemaScanResult(found, ref); |
|
}
|
|
|