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

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);
}