validate.jst (7743B)
1 {{# def.definitions }} 2 {{# def.errors }} 3 {{# def.defaults }} 4 {{# def.coerce }} 5 6 {{ /** 7 * schema compilation (render) time: 8 * it = { schema, RULES, _validate, opts } 9 * it.validate - this template function, 10 * it is used recursively to generate code for subschemas 11 * 12 * runtime: 13 * "validate" is a variable name to which this function will be assigned 14 * validateRef etc. are defined in the parent scope in index.js 15 */ }} 16 17 {{ 18 var $async = it.schema.$async === true 19 , $refKeywords = it.util.schemaHasRulesExcept(it.schema, it.RULES.all, '$ref') 20 , $id = it.self._getId(it.schema); 21 }} 22 23 {{ 24 if (it.opts.strictKeywords) { 25 var $unknownKwd = it.util.schemaUnknownRules(it.schema, it.RULES.keywords); 26 if ($unknownKwd) { 27 var $keywordsMsg = 'unknown keyword: ' + $unknownKwd; 28 if (it.opts.strictKeywords === 'log') it.logger.warn($keywordsMsg); 29 else throw new Error($keywordsMsg); 30 } 31 } 32 }} 33 34 {{? it.isTop }} 35 var validate = {{?$async}}{{it.async = true;}}async {{?}}function(data, dataPath, parentData, parentDataProperty, rootData) { 36 'use strict'; 37 {{? $id && (it.opts.sourceCode || it.opts.processCode) }} 38 {{= '/\*# sourceURL=' + $id + ' */' }} 39 {{?}} 40 {{?}} 41 42 {{? typeof it.schema == 'boolean' || !($refKeywords || it.schema.$ref) }} 43 {{ var $keyword = 'false schema'; }} 44 {{# def.setupKeyword }} 45 {{? it.schema === false}} 46 {{? it.isTop}} 47 {{ $breakOnError = true; }} 48 {{??}} 49 var {{=$valid}} = false; 50 {{?}} 51 {{# def.error:'false schema' }} 52 {{??}} 53 {{? it.isTop}} 54 {{? $async }} 55 return data; 56 {{??}} 57 validate.errors = null; 58 return true; 59 {{?}} 60 {{??}} 61 var {{=$valid}} = true; 62 {{?}} 63 {{?}} 64 65 {{? it.isTop}} 66 }; 67 return validate; 68 {{?}} 69 70 {{ return out; }} 71 {{?}} 72 73 74 {{? it.isTop }} 75 {{ 76 var $top = it.isTop 77 , $lvl = it.level = 0 78 , $dataLvl = it.dataLevel = 0 79 , $data = 'data'; 80 it.rootId = it.resolve.fullPath(it.self._getId(it.root.schema)); 81 it.baseId = it.baseId || it.rootId; 82 delete it.isTop; 83 84 it.dataPathArr = [undefined]; 85 86 if (it.schema.default !== undefined && it.opts.useDefaults && it.opts.strictDefaults) { 87 var $defaultMsg = 'default is ignored in the schema root'; 88 if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg); 89 else throw new Error($defaultMsg); 90 } 91 }} 92 93 var vErrors = null; {{ /* don't edit, used in replace */ }} 94 var errors = 0; {{ /* don't edit, used in replace */ }} 95 if (rootData === undefined) rootData = data; {{ /* don't edit, used in replace */ }} 96 {{??}} 97 {{ 98 var $lvl = it.level 99 , $dataLvl = it.dataLevel 100 , $data = 'data' + ($dataLvl || ''); 101 102 if ($id) it.baseId = it.resolve.url(it.baseId, $id); 103 104 if ($async && !it.async) throw new Error('async schema in sync schema'); 105 }} 106 107 var errs_{{=$lvl}} = errors; 108 {{?}} 109 110 {{ 111 var $valid = 'valid' + $lvl 112 , $breakOnError = !it.opts.allErrors 113 , $closingBraces1 = '' 114 , $closingBraces2 = ''; 115 116 var $errorKeyword; 117 var $typeSchema = it.schema.type 118 , $typeIsArray = Array.isArray($typeSchema); 119 120 if ($typeSchema && it.opts.nullable && it.schema.nullable === true) { 121 if ($typeIsArray) { 122 if ($typeSchema.indexOf('null') == -1) 123 $typeSchema = $typeSchema.concat('null'); 124 } else if ($typeSchema != 'null') { 125 $typeSchema = [$typeSchema, 'null']; 126 $typeIsArray = true; 127 } 128 } 129 130 if ($typeIsArray && $typeSchema.length == 1) { 131 $typeSchema = $typeSchema[0]; 132 $typeIsArray = false; 133 } 134 }} 135 136 {{## def.checkType: 137 {{ 138 var $schemaPath = it.schemaPath + '.type' 139 , $errSchemaPath = it.errSchemaPath + '/type' 140 , $method = $typeIsArray ? 'checkDataTypes' : 'checkDataType'; 141 }} 142 143 if ({{= it.util[$method]($typeSchema, $data, true) }}) { 144 #}} 145 146 {{? it.schema.$ref && $refKeywords }} 147 {{? it.opts.extendRefs == 'fail' }} 148 {{ throw new Error('$ref: validation keywords used in schema at path "' + it.errSchemaPath + '" (see option extendRefs)'); }} 149 {{?? it.opts.extendRefs !== true }} 150 {{ 151 $refKeywords = false; 152 it.logger.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"'); 153 }} 154 {{?}} 155 {{?}} 156 157 {{? it.schema.$comment && it.opts.$comment }} 158 {{= it.RULES.all.$comment.code(it, '$comment') }} 159 {{?}} 160 161 {{? $typeSchema }} 162 {{? it.opts.coerceTypes }} 163 {{ var $coerceToTypes = it.util.coerceToTypes(it.opts.coerceTypes, $typeSchema); }} 164 {{?}} 165 166 {{ var $rulesGroup = it.RULES.types[$typeSchema]; }} 167 {{? $coerceToTypes || $typeIsArray || $rulesGroup === true || 168 ($rulesGroup && !$shouldUseGroup($rulesGroup)) }} 169 {{ 170 var $schemaPath = it.schemaPath + '.type' 171 , $errSchemaPath = it.errSchemaPath + '/type'; 172 }} 173 {{# def.checkType }} 174 {{? $coerceToTypes }} 175 {{# def.coerceType }} 176 {{??}} 177 {{# def.error:'type' }} 178 {{?}} 179 } 180 {{?}} 181 {{?}} 182 183 184 {{? it.schema.$ref && !$refKeywords }} 185 {{= it.RULES.all.$ref.code(it, '$ref') }} 186 {{? $breakOnError }} 187 } 188 if (errors === {{?$top}}0{{??}}errs_{{=$lvl}}{{?}}) { 189 {{ $closingBraces2 += '}'; }} 190 {{?}} 191 {{??}} 192 {{~ it.RULES:$rulesGroup }} 193 {{? $shouldUseGroup($rulesGroup) }} 194 {{? $rulesGroup.type }} 195 if ({{= it.util.checkDataType($rulesGroup.type, $data) }}) { 196 {{?}} 197 {{? it.opts.useDefaults }} 198 {{? $rulesGroup.type == 'object' && it.schema.properties }} 199 {{# def.defaultProperties }} 200 {{?? $rulesGroup.type == 'array' && Array.isArray(it.schema.items) }} 201 {{# def.defaultItems }} 202 {{?}} 203 {{?}} 204 {{~ $rulesGroup.rules:$rule }} 205 {{? $shouldUseRule($rule) }} 206 {{ var $code = $rule.code(it, $rule.keyword, $rulesGroup.type); }} 207 {{? $code }} 208 {{= $code }} 209 {{? $breakOnError }} 210 {{ $closingBraces1 += '}'; }} 211 {{?}} 212 {{?}} 213 {{?}} 214 {{~}} 215 {{? $breakOnError }} 216 {{= $closingBraces1 }} 217 {{ $closingBraces1 = ''; }} 218 {{?}} 219 {{? $rulesGroup.type }} 220 } 221 {{? $typeSchema && $typeSchema === $rulesGroup.type && !$coerceToTypes }} 222 else { 223 {{ 224 var $schemaPath = it.schemaPath + '.type' 225 , $errSchemaPath = it.errSchemaPath + '/type'; 226 }} 227 {{# def.error:'type' }} 228 } 229 {{?}} 230 {{?}} 231 232 {{? $breakOnError }} 233 if (errors === {{?$top}}0{{??}}errs_{{=$lvl}}{{?}}) { 234 {{ $closingBraces2 += '}'; }} 235 {{?}} 236 {{?}} 237 {{~}} 238 {{?}} 239 240 {{? $breakOnError }} {{= $closingBraces2 }} {{?}} 241 242 {{? $top }} 243 {{? $async }} 244 if (errors === 0) return data; {{ /* don't edit, used in replace */ }} 245 else throw new ValidationError(vErrors); {{ /* don't edit, used in replace */ }} 246 {{??}} 247 validate.errors = vErrors; {{ /* don't edit, used in replace */ }} 248 return errors === 0; {{ /* don't edit, used in replace */ }} 249 {{?}} 250 }; 251 252 return validate; 253 {{??}} 254 var {{=$valid}} = errors === errs_{{=$lvl}}; 255 {{?}} 256 257 {{# def.cleanUp }} 258 259 {{? $top }} 260 {{# def.finalCleanUp }} 261 {{?}} 262 263 {{ 264 function $shouldUseGroup($rulesGroup) { 265 var rules = $rulesGroup.rules; 266 for (var i=0; i < rules.length; i++) 267 if ($shouldUseRule(rules[i])) 268 return true; 269 } 270 271 function $shouldUseRule($rule) { 272 return it.schema[$rule.keyword] !== undefined || 273 ($rule.implements && $ruleImplementsSomeKeyword($rule)); 274 } 275 276 function $ruleImplementsSomeKeyword($rule) { 277 var impl = $rule.implements; 278 for (var i=0; i < impl.length; i++) 279 if (it.schema[impl[i]] !== undefined) 280 return true; 281 } 282 }}