"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/is-my-json-valid/index.js" (7 Feb 2017, 16936 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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       if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name))
  518 
  519       validate('if (%s %s %d) {', name, node.exclusiveMinimum ? '<=' : '<', node.minimum)
  520       error('is less than minimum')
  521       validate('}')
  522 
  523       if (type !== 'number' && type !== 'integer') validate('}')
  524     }
  525 
  526     if (node.maximum !== undefined) {
  527       if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name))
  528 
  529       validate('if (%s %s %d) {', name, node.exclusiveMaximum ? '>=' : '>', node.maximum)
  530       error('is more than maximum')
  531       validate('}')
  532 
  533       if (type !== 'number' && type !== 'integer') validate('}')
  534     }
  535 
  536     if (properties) {
  537       Object.keys(properties).forEach(function(p) {
  538         if (Array.isArray(type) && type.indexOf('null') !== -1) validate('if (%s !== null) {', name)
  539 
  540         visit(genobj(name, p), properties[p], reporter, filter)
  541 
  542         if (Array.isArray(type) && type.indexOf('null') !== -1) validate('}')
  543       })
  544     }
  545 
  546     while (indent--) validate('}')
  547   }
  548 
  549   var validate = genfun
  550     ('function validate(data) {')
  551       // Since undefined is not a valid JSON value, we coerce to null and other checks will catch this
  552       ('if (data === undefined) data = null')
  553       ('validate.errors = null')
  554       ('var errors = 0')
  555 
  556   visit('data', schema, reporter, opts && opts.filter)
  557 
  558   validate
  559       ('return errors === 0')
  560     ('}')
  561 
  562   validate = validate.toFunction(scope)
  563   validate.errors = null
  564 
  565   if (Object.defineProperty) {
  566     Object.defineProperty(validate, 'error', {
  567       get: function() {
  568         if (!validate.errors) return ''
  569         return validate.errors.map(function(err) {
  570           return err.field + ' ' + err.message;
  571         }).join('\n')
  572       }
  573     })
  574   }
  575 
  576   validate.toJSON = function() {
  577     return schema
  578   }
  579 
  580   return validate
  581 }
  582 
  583 module.exports = function(schema, opts) {
  584   if (typeof schema === 'string') schema = JSON.parse(schema)
  585   return compile(schema, {}, schema, true, opts)
  586 }
  587 
  588 module.exports.filter = function(schema, opts) {
  589   var validate = module.exports(schema, xtend(opts, {filter: true}))
  590   return function(sch) {
  591     validate(sch)
  592     return sch
  593   }
  594 }