index.js 2.3 KB

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