deepProperties.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. 'use strict';
  2. var util = require('./_util');
  3. module.exports = function defFunc(ajv) {
  4. defFunc.definition = {
  5. type: 'object',
  6. macro: function (schema) {
  7. var schemas = [];
  8. for (var pointer in schema)
  9. schemas.push(getSchema(pointer, schema[pointer]));
  10. return { 'allOf': schemas };
  11. },
  12. metaSchema: {
  13. type: 'object',
  14. propertyNames: {
  15. type: 'string',
  16. format: 'json-pointer'
  17. },
  18. additionalProperties: util.metaSchemaRef(ajv)
  19. }
  20. };
  21. ajv.addKeyword('deepProperties', defFunc.definition);
  22. return ajv;
  23. };
  24. function getSchema(jsonPointer, schema) {
  25. var segments = jsonPointer.split('/');
  26. var rootSchema = {};
  27. var pointerSchema = rootSchema;
  28. for (var i=1; i<segments.length; i++) {
  29. var segment = segments[i];
  30. var isLast = i == segments.length - 1;
  31. segment = unescapeJsonPointer(segment);
  32. var properties = pointerSchema.properties = {};
  33. var items = undefined;
  34. if (/[0-9]+/.test(segment)) {
  35. var count = +segment;
  36. items = pointerSchema.items = [];
  37. while (count--) items.push({});
  38. }
  39. pointerSchema = isLast ? schema : {};
  40. properties[segment] = pointerSchema;
  41. if (items) items.push(pointerSchema);
  42. }
  43. return rootSchema;
  44. }
  45. function unescapeJsonPointer(str) {
  46. return str.replace(/~1/g, '/').replace(/~0/g, '~');
  47. }