]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/node_modules/request/node_modules/har-validator/node_modules/is-my-json-valid/index.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / node_modules / request / node_modules / har-validator / node_modules / is-my-json-valid / index.js
1 var genobj = require('generate-object-property')
2 var genfun = require('generate-function')
3 var jsonpointer = require('jsonpointer')
4 var xtend = require('xtend')
5 var formats = require('./formats')
6
7 var get = function(obj, additionalSchemas, ptr) {
8
9   var visit = function(sub) {
10     if (sub && sub.id === ptr) return sub
11     if (typeof sub !== 'object' || !sub) return null
12     return Object.keys(sub).reduce(function(res, k) {
13       return res || visit(sub[k])
14     }, null)
15   }
16
17   var res = visit(obj)
18   if (res) return res
19
20   ptr = ptr.replace(/^#/, '')
21   ptr = ptr.replace(/\/$/, '')
22
23   try {
24     return jsonpointer.get(obj, decodeURI(ptr))
25   } catch (err) {
26     var end = ptr.indexOf('#')
27     var other
28     // external reference
29     if (end !== 0) {
30       // fragment doesn't exist.
31       if (end === -1) {
32         other = additionalSchemas[ptr]
33       } else {
34         var ext = ptr.slice(0, end)
35         other = additionalSchemas[ext]
36         var fragment = ptr.slice(end).replace(/^#/, '')
37         try {
38           return jsonpointer.get(other, fragment)
39         } catch (err) {}
40       }
41     } else {
42       other = additionalSchemas[ptr]
43     }
44     return other || null
45   }
46 }
47
48 var formatName = function(field) {
49   field = JSON.stringify(field)
50   var pattern = /\[([^\[\]"]+)\]/
51   while (pattern.test(field)) field = field.replace(pattern, '."+$1+"')
52   return field
53 }
54
55 var types = {}
56
57 types.any = function() {
58   return 'true'
59 }
60
61 types.null = function(name) {
62   return name+' === null'
63 }
64
65 types.boolean = function(name) {
66   return 'typeof '+name+' === "boolean"'
67 }
68
69 types.array = function(name) {
70   return 'Array.isArray('+name+')'
71 }
72
73 types.object = function(name) {
74   return 'typeof '+name+' === "object" && '+name+' && !Array.isArray('+name+')'
75 }
76
77 types.number = function(name) {
78   return 'typeof '+name+' === "number"'
79 }
80
81 types.integer = function(name) {
82   return 'typeof '+name+' === "number" && (Math.floor('+name+') === '+name+' || '+name+' > 9007199254740992 || '+name+' < -9007199254740992)'
83 }
84
85 types.string = function(name) {
86   return 'typeof '+name+' === "string"'
87 }
88
89 var unique = function(array) {
90   var list = []
91   for (var i = 0; i < array.length; i++) {
92     list.push(typeof array[i] === 'object' ? JSON.stringify(array[i]) : array[i])
93   }
94   for (var i = 1; i < list.length; i++) {
95     if (list.indexOf(list[i]) !== i) return false
96   }
97   return true
98 }
99
100 var isMultipleOf = function(name, multipleOf) {
101   var res;
102   var factor = ((multipleOf | 0) !== multipleOf) ? Math.pow(10, multipleOf.toString().split('.').pop().length) : 1
103   if (factor > 1) {
104     var factorName = ((name | 0) !== name) ? Math.pow(10, name.toString().split('.').pop().length) : 1
105     if (factorName > factor) res = true
106     else res = Math.round(factor * name) % (factor * multipleOf)
107   }
108   else res = name % multipleOf;
109   return !res;
110 }
111
112 var toType = function(node) {
113   return node.type
114 }
115
116 var compile = function(schema, cache, root, reporter, opts) {
117   var fmts = opts ? xtend(formats, opts.formats) : formats
118   var scope = {unique:unique, formats:fmts, isMultipleOf:isMultipleOf}
119   var verbose = opts ? !!opts.verbose : false;
120   var greedy = opts && opts.greedy !== undefined ?
121     opts.greedy : false;
122
123   var syms = {}
124   var gensym = function(name) {
125     return name+(syms[name] = (syms[name] || 0)+1)
126   }
127
128   var reversePatterns = {}
129   var patterns = function(p) {
130     if (reversePatterns[p]) return reversePatterns[p]
131     var n = gensym('pattern')
132     scope[n] = new RegExp(p)
133     reversePatterns[p] = n
134     return n
135   }
136
137   var vars = ['i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','z']
138   var genloop = function() {
139     var v = vars.shift()
140     vars.push(v+v[0])
141     return v
142   }
143
144   var visit = function(name, node, reporter, filter) {
145     var properties = node.properties
146     var type = node.type
147     var tuple = false
148
149     if (Array.isArray(node.items)) { // tuple type
150       properties = {}
151       node.items.forEach(function(item, i) {
152         properties[i] = item
153       })
154       type = 'array'
155       tuple = true
156     }
157
158     var indent = 0
159     var error = function(msg, prop, value) {
160       validate('errors++')
161       if (reporter === true) {
162         validate('if (validate.errors === null) validate.errors = []')
163         if (verbose) {
164           validate('validate.errors.push({field:%s,message:%s,value:%s,type:%s})', formatName(prop || name), JSON.stringify(msg), value || name, JSON.stringify(type))
165         } else {
166           validate('validate.errors.push({field:%s,message:%s})', formatName(prop || name), JSON.stringify(msg))
167         }
168       }
169     }
170
171     if (node.required === true) {
172       indent++
173       validate('if (%s === undefined) {', name)
174       error('is required')
175       validate('} else {')
176     } else {
177       indent++
178       validate('if (%s !== undefined) {', name)
179     }
180
181     var valid = [].concat(type)
182       .map(function(t) {
183         return types[t || 'any'](name)
184       })
185       .join(' || ') || 'true'
186
187     if (valid !== 'true') {
188       indent++
189       validate('if (!(%s)) {', valid)
190       error('is the wrong type')
191       validate('} else {')
192     }
193
194     if (tuple) {
195       if (node.additionalItems === false) {
196         validate('if (%s.length > %d) {', name, node.items.length)
197         error('has additional items')
198         validate('}')
199       } else if (node.additionalItems) {
200         var i = genloop()
201         validate('for (var %s = %d; %s < %s.length; %s++) {', i, node.items.length, i, name, i)
202         visit(name+'['+i+']', node.additionalItems, reporter, filter)
203         validate('}')
204       }
205     }
206
207     if (node.format && fmts[node.format]) {
208       if (type !== 'string' && formats[node.format]) validate('if (%s) {', types.string(name))
209       var n = gensym('format')
210       scope[n] = fmts[node.format]
211
212       if (typeof scope[n] === 'function') validate('if (!%s(%s)) {', n, name)
213       else validate('if (!%s.test(%s)) {', n, name)
214       error('must be '+node.format+' format')
215       validate('}')
216       if (type !== 'string' && formats[node.format]) validate('}')
217     }
218
219     if (Array.isArray(node.required)) {
220       var isUndefined = function(req) {
221         return genobj(name, req) + ' === undefined'
222       }
223
224       var checkRequired = function (req) {
225         var prop = genobj(name, req);
226         validate('if (%s === undefined) {', prop)
227         error('is required', prop)
228         validate('missing++')
229         validate('}')
230       }
231       validate('if ((%s)) {', type !== 'object' ? types.object(name) : 'true')
232       validate('var missing = 0')
233       node.required.map(checkRequired)
234       validate('}');
235       if (!greedy) {
236         validate('if (missing === 0) {')
237         indent++
238       }
239     }
240
241     if (node.uniqueItems) {
242       if (type !== 'array') validate('if (%s) {', types.array(name))
243       validate('if (!(unique(%s))) {', name)
244       error('must be unique')
245       validate('}')
246       if (type !== 'array') validate('}')
247     }
248
249     if (node.enum) {
250       var complex = node.enum.some(function(e) {
251         return typeof e === 'object'
252       })
253
254       var compare = complex ?
255         function(e) {
256           return 'JSON.stringify('+name+')'+' !== JSON.stringify('+JSON.stringify(e)+')'
257         } :
258         function(e) {
259           return name+' !== '+JSON.stringify(e)
260         }
261
262       validate('if (%s) {', node.enum.map(compare).join(' && ') || 'false')
263       error('must be an enum value')
264       validate('}')
265     }
266
267     if (node.dependencies) {
268       if (type !== 'object') validate('if (%s) {', types.object(name))
269
270       Object.keys(node.dependencies).forEach(function(key) {
271         var deps = node.dependencies[key]
272         if (typeof deps === 'string') deps = [deps]
273
274         var exists = function(k) {
275           return genobj(name, k) + ' !== undefined'
276         }
277
278         if (Array.isArray(deps)) {
279           validate('if (%s !== undefined && !(%s)) {', genobj(name, key), deps.map(exists).join(' && ') || 'true')
280           error('dependencies not set')
281           validate('}')
282         }
283         if (typeof deps === 'object') {
284           validate('if (%s !== undefined) {', genobj(name, key))
285           visit(name, deps, reporter, filter)
286           validate('}')
287         }
288       })
289
290       if (type !== 'object') validate('}')
291     }
292
293     if (node.additionalProperties || node.additionalProperties === false) {
294       if (type !== 'object') validate('if (%s) {', types.object(name))
295
296       var i = genloop()
297       var keys = gensym('keys')
298
299       var toCompare = function(p) {
300         return keys+'['+i+'] !== '+JSON.stringify(p)
301       }
302
303       var toTest = function(p) {
304         return '!'+patterns(p)+'.test('+keys+'['+i+'])'
305       }
306
307       var additionalProp = Object.keys(properties || {}).map(toCompare)
308         .concat(Object.keys(node.patternProperties || {}).map(toTest))
309         .join(' && ') || 'true'
310
311       validate('var %s = Object.keys(%s)', keys, name)
312         ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i)
313           ('if (%s) {', additionalProp)
314
315       if (node.additionalProperties === false) {
316         if (filter) validate('delete %s', name+'['+keys+'['+i+']]')
317         error('has additional properties', null, JSON.stringify(name+'.') + ' + ' + keys + '['+i+']')
318       } else {
319         visit(name+'['+keys+'['+i+']]', node.additionalProperties, reporter, filter)
320       }
321
322       validate
323           ('}')
324         ('}')
325
326       if (type !== 'object') validate('}')
327     }
328
329     if (node.$ref) {
330       var sub = get(root, opts && opts.schemas || {}, node.$ref)
331       if (sub) {
332         var fn = cache[node.$ref]
333         if (!fn) {
334           cache[node.$ref] = function proxy(data) {
335             return fn(data)
336           }
337           fn = compile(sub, cache, root, false, opts)
338         }
339         var n = gensym('ref')
340         scope[n] = fn
341         validate('if (!(%s(%s))) {', n, name)
342         error('referenced schema does not match')
343         validate('}')
344       }
345     }
346
347     if (node.not) {
348       var prev = gensym('prev')
349       validate('var %s = errors', prev)
350       visit(name, node.not, false, filter)
351       validate('if (%s === errors) {', prev)
352       error('negative schema matches')
353       validate('} else {')
354         ('errors = %s', prev)
355       ('}')
356     }
357
358     if (node.items && !tuple) {
359       if (type !== 'array') validate('if (%s) {', types.array(name))
360
361       var i = genloop()
362       validate('for (var %s = 0; %s < %s.length; %s++) {', i, i, name, i)
363       visit(name+'['+i+']', node.items, reporter, filter)
364       validate('}')
365
366       if (type !== 'array') validate('}')
367     }
368
369     if (node.patternProperties) {
370       if (type !== 'object') validate('if (%s) {', types.object(name))
371       var keys = gensym('keys')
372       var i = genloop()
373       validate
374         ('var %s = Object.keys(%s)', keys, name)
375         ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i)
376
377       Object.keys(node.patternProperties).forEach(function(key) {
378         var p = patterns(key)
379         validate('if (%s.test(%s)) {', p, keys+'['+i+']')
380         visit(name+'['+keys+'['+i+']]', node.patternProperties[key], reporter, filter)
381         validate('}')
382       })
383
384       validate('}')
385       if (type !== 'object') validate('}')
386     }
387
388     if (node.pattern) {
389       var p = patterns(node.pattern)
390       if (type !== 'string') validate('if (%s) {', types.string(name))
391       validate('if (!(%s.test(%s))) {', p, name)
392       error('pattern mismatch')
393       validate('}')
394       if (type !== 'string') validate('}')
395     }
396
397     if (node.allOf) {
398       node.allOf.forEach(function(sch) {
399         visit(name, sch, reporter, filter)
400       })
401     }
402
403     if (node.anyOf && node.anyOf.length) {
404       var prev = gensym('prev')
405
406       node.anyOf.forEach(function(sch, i) {
407         if (i === 0) {
408           validate('var %s = errors', prev)
409         } else {
410           validate('if (errors !== %s) {', prev)
411             ('errors = %s', prev)
412         }
413         visit(name, sch, false, false)
414       })
415       node.anyOf.forEach(function(sch, i) {
416         if (i) validate('}')
417       })
418       validate('if (%s !== errors) {', prev)
419       error('no schemas match')
420       validate('}')
421     }
422
423     if (node.oneOf && node.oneOf.length) {
424       var prev = gensym('prev')
425       var passes = gensym('passes')
426
427       validate
428         ('var %s = errors', prev)
429         ('var %s = 0', passes)
430
431       node.oneOf.forEach(function(sch, i) {
432         visit(name, sch, false, false)
433         validate('if (%s === errors) {', prev)
434           ('%s++', passes)
435         ('} else {')
436           ('errors = %s', prev)
437         ('}')
438       })
439
440       validate('if (%s !== 1) {', passes)
441       error('no (or more than one) schemas match')
442       validate('}')
443     }
444
445     if (node.multipleOf !== undefined) {
446       if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name))
447
448       validate('if (!isMultipleOf(%s, %d)) {', name, node.multipleOf)
449
450       error('has a remainder')
451       validate('}')
452
453       if (type !== 'number' && type !== 'integer') validate('}')
454     }
455
456     if (node.maxProperties !== undefined) {
457       if (type !== 'object') validate('if (%s) {', types.object(name))
458
459       validate('if (Object.keys(%s).length > %d) {', name, node.maxProperties)
460       error('has more properties than allowed')
461       validate('}')
462
463       if (type !== 'object') validate('}')
464     }
465
466     if (node.minProperties !== undefined) {
467       if (type !== 'object') validate('if (%s) {', types.object(name))
468
469       validate('if (Object.keys(%s).length < %d) {', name, node.minProperties)
470       error('has less properties than allowed')
471       validate('}')
472
473       if (type !== 'object') validate('}')
474     }
475
476     if (node.maxItems !== undefined) {
477       if (type !== 'array') validate('if (%s) {', types.array(name))
478
479       validate('if (%s.length > %d) {', name, node.maxItems)
480       error('has more items than allowed')
481       validate('}')
482
483       if (type !== 'array') validate('}')
484     }
485
486     if (node.minItems !== undefined) {
487       if (type !== 'array') validate('if (%s) {', types.array(name))
488
489       validate('if (%s.length < %d) {', name, node.minItems)
490       error('has less items than allowed')
491       validate('}')
492
493       if (type !== 'array') validate('}')
494     }
495
496     if (node.maxLength !== undefined) {
497       if (type !== 'string') validate('if (%s) {', types.string(name))
498
499       validate('if (%s.length > %d) {', name, node.maxLength)
500       error('has longer length than allowed')
501       validate('}')
502
503       if (type !== 'string') validate('}')
504     }
505
506     if (node.minLength !== undefined) {
507       if (type !== 'string') validate('if (%s) {', types.string(name))
508
509       validate('if (%s.length < %d) {', name, node.minLength)
510       error('has less length than allowed')
511       validate('}')
512
513       if (type !== 'string') validate('}')
514     }
515
516     if (node.minimum !== undefined) {
517       validate('if (%s %s %d) {', name, node.exclusiveMinimum ? '<=' : '<', node.minimum)
518       error('is less than minimum')
519       validate('}')
520     }
521
522     if (node.maximum !== undefined) {
523       validate('if (%s %s %d) {', name, node.exclusiveMaximum ? '>=' : '>', node.maximum)
524       error('is more than maximum')
525       validate('}')
526     }
527
528     if (properties) {
529       Object.keys(properties).forEach(function(p) {
530         if (Array.isArray(type) && type.indexOf('null') !== -1) validate('if (%s !== null) {', name)
531
532         visit(genobj(name, p), properties[p], reporter, filter)
533
534         if (Array.isArray(type) && type.indexOf('null') !== -1) validate('}')
535       })
536     }
537
538     while (indent--) validate('}')
539   }
540
541   var validate = genfun
542     ('function validate(data) {')
543       ('validate.errors = null')
544       ('var errors = 0')
545
546   visit('data', schema, reporter, opts && opts.filter)
547
548   validate
549       ('return errors === 0')
550     ('}')
551
552   validate = validate.toFunction(scope)
553   validate.errors = null
554
555   if (Object.defineProperty) {
556     Object.defineProperty(validate, 'error', {
557       get: function() {
558         if (!validate.errors) return ''
559         return validate.errors.map(function(err) {
560           return err.field + ' ' + err.message;
561         }).join('\n')
562       }
563     })
564   }
565
566   validate.toJSON = function() {
567     return schema
568   }
569
570   return validate
571 }
572
573 module.exports = function(schema, opts) {
574   if (typeof schema === 'string') schema = JSON.parse(schema)
575   return compile(schema, {}, schema, true, opts)
576 }
577
578 module.exports.filter = function(schema, opts) {
579   var validate = module.exports(schema, xtend(opts, {filter: true}))
580   return function(sch) {
581     validate(sch)
582     return sch
583   }
584 }