deepProperties.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. 'use strict';
  2. module.exports = function defFunc(ajv) {
  3. defFunc.definition = {
  4. type: 'object',
  5. macro: function (schema) {
  6. var schemas = [];
  7. for (var pointer in schema)
  8. schemas.push(getSchema(pointer, schema[pointer]));
  9. return { 'allOf': schemas };
  10. },
  11. metaSchema: {
  12. type: 'object',
  13. patternProperties: {
  14. '^(\\/([^~\\/]|~0|~1)*)*(\\/)?$': {
  15. $ref: ajv._opts.v5
  16. ? 'https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#'
  17. : 'http://json-schema.org/draft-04/schema#'
  18. }
  19. },
  20. additionalProperties: false
  21. }
  22. };
  23. ajv.addKeyword('deepProperties', defFunc.definition);
  24. return ajv;
  25. };
  26. function getSchema(jsonPointer, schema) {
  27. var segments = jsonPointer.split('/');
  28. var rootSchema = {};
  29. var pointerSchema = rootSchema;
  30. for (var i=1; i<segments.length; i++) {
  31. var segment = segments[i];
  32. var isLast = i == segments.length - 1;
  33. segment = unescapeJsonPointer(segment);
  34. var properties = pointerSchema.properties = {};
  35. var items = undefined;
  36. if (/[0-9]+/.test(segment)) {
  37. var count = +segment;
  38. items = pointerSchema.items = [];
  39. while (count--) items.push({});
  40. }
  41. pointerSchema = isLast ? schema : {};
  42. properties[segment] = pointerSchema;
  43. if (items) items.push(pointerSchema);
  44. }
  45. return rootSchema;
  46. }
  47. function unescapeJsonPointer(str) {
  48. return str.replace(/~1/g, '/').replace(/~0/g, '~');
  49. }