80 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			80 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | var util = require('./_util'); | ||
|  | 
 | ||
|  | module.exports = function defFunc(ajv) { | ||
|  |   if (!ajv._opts.$data) { | ||
|  |     console.warn('keyword select requires $data option'); | ||
|  |     return ajv; | ||
|  |   } | ||
|  |   var metaSchemaRef = util.metaSchemaRef(ajv); | ||
|  |   var compiledCaseSchemas = []; | ||
|  | 
 | ||
|  |   defFunc.definition = { | ||
|  |     validate: function v(schema, data, parentSchema) { | ||
|  |       if (parentSchema.selectCases === undefined) | ||
|  |         throw new Error('keyword "selectCases" is absent'); | ||
|  |       var compiled = getCompiledSchemas(parentSchema, false); | ||
|  |       var validate = compiled.cases[schema]; | ||
|  |       if (validate === undefined) validate = compiled.default; | ||
|  |       if (typeof validate == 'boolean') return validate; | ||
|  |       var valid = validate(data); | ||
|  |       if (!valid) v.errors = validate.errors; | ||
|  |       return valid; | ||
|  |     }, | ||
|  |     $data: true, | ||
|  |     metaSchema: { type: ['string', 'number', 'boolean', 'null'] } | ||
|  |   }; | ||
|  | 
 | ||
|  |   ajv.addKeyword('select', defFunc.definition); | ||
|  |   ajv.addKeyword('selectCases', { | ||
|  |     compile: function (schemas, parentSchema) { | ||
|  |       var compiled = getCompiledSchemas(parentSchema); | ||
|  |       for (var value in schemas) | ||
|  |         compiled.cases[value] = compileOrBoolean(schemas[value]); | ||
|  |       return function() { return true; }; | ||
|  |     }, | ||
|  |     valid: true, | ||
|  |     metaSchema: { | ||
|  |       type: 'object', | ||
|  |       additionalProperties: metaSchemaRef | ||
|  |     } | ||
|  |   }); | ||
|  |   ajv.addKeyword('selectDefault', { | ||
|  |     compile: function (schema, parentSchema) { | ||
|  |       var compiled = getCompiledSchemas(parentSchema); | ||
|  |       compiled.default = compileOrBoolean(schema); | ||
|  |       return function() { return true; }; | ||
|  |     }, | ||
|  |     valid: true, | ||
|  |     metaSchema: metaSchemaRef | ||
|  |   }); | ||
|  |   return ajv; | ||
|  | 
 | ||
|  | 
 | ||
|  |   function getCompiledSchemas(parentSchema, create) { | ||
|  |     var compiled; | ||
|  |     compiledCaseSchemas.some(function (c) { | ||
|  |       if (c.parentSchema === parentSchema) { | ||
|  |         compiled = c; | ||
|  |         return true; | ||
|  |       } | ||
|  |     }); | ||
|  |     if (!compiled && create !== false) { | ||
|  |       compiled = { | ||
|  |         parentSchema: parentSchema, | ||
|  |         cases: {}, | ||
|  |         default: true | ||
|  |       }; | ||
|  |       compiledCaseSchemas.push(compiled); | ||
|  |     } | ||
|  |     return compiled; | ||
|  |   } | ||
|  | 
 | ||
|  |   function compileOrBoolean(schema) { | ||
|  |     return typeof schema == 'boolean' | ||
|  |             ? schema | ||
|  |             : ajv.compile(schema); | ||
|  |   } | ||
|  | }; |