index.js
1 'use strict'; 2 3 var traverse = module.exports = function (schema, opts, cb) { 4 // Legacy support for v0.3.1 and earlier. 5 if (typeof opts == 'function') { 6 cb = opts; 7 opts = {}; 8 } 9 10 cb = opts.cb || cb; 11 var pre = (typeof cb == 'function') ? cb : cb.pre || function() {}; 12 var post = cb.post || function() {}; 13 14 _traverse(opts, pre, post, schema, '', schema); 15 }; 16 17 18 traverse.keywords = { 19 additionalItems: true, 20 items: true, 21 contains: true, 22 additionalProperties: true, 23 propertyNames: true, 24 not: true, 25 if: true, 26 then: true, 27 else: true 28 }; 29 30 traverse.arrayKeywords = { 31 items: true, 32 allOf: true, 33 anyOf: true, 34 oneOf: true 35 }; 36 37 traverse.propsKeywords = { 38 $defs: true, 39 definitions: true, 40 properties: true, 41 patternProperties: true, 42 dependencies: true 43 }; 44 45 traverse.skipKeywords = { 46 default: true, 47 enum: true, 48 const: true, 49 required: true, 50 maximum: true, 51 minimum: true, 52 exclusiveMaximum: true, 53 exclusiveMinimum: true, 54 multipleOf: true, 55 maxLength: true, 56 minLength: true, 57 pattern: true, 58 format: true, 59 maxItems: true, 60 minItems: true, 61 uniqueItems: true, 62 maxProperties: true, 63 minProperties: true 64 }; 65 66 67 function _traverse(opts, pre, post, schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) { 68 if (schema && typeof schema == 'object' && !Array.isArray(schema)) { 69 pre(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex); 70 for (var key in schema) { 71 var sch = schema[key]; 72 if (Array.isArray(sch)) { 73 if (key in traverse.arrayKeywords) { 74 for (var i=0; i<sch.length; i++) 75 _traverse(opts, pre, post, sch[i], jsonPtr + '/' + key + '/' + i, rootSchema, jsonPtr, key, schema, i); 76 } 77 } else if (key in traverse.propsKeywords) { 78 if (sch && typeof sch == 'object') { 79 for (var prop in sch) 80 _traverse(opts, pre, post, sch[prop], jsonPtr + '/' + key + '/' + escapeJsonPtr(prop), rootSchema, jsonPtr, key, schema, prop); 81 } 82 } else if (key in traverse.keywords || (opts.allKeys && !(key in traverse.skipKeywords))) { 83 _traverse(opts, pre, post, sch, jsonPtr + '/' + key, rootSchema, jsonPtr, key, schema); 84 } 85 } 86 post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex); 87 } 88 } 89 90 91 function escapeJsonPtr(str) { 92 return str.replace(/~/g, '~0').replace(/\//g, '~1'); 93 }