json-schema-library 5.2.1 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.prettierignore +1 -0
  2. package/.prettierrc +7 -0
  3. package/README.md +9 -8
  4. package/dist/index.d.ts +13 -44
  5. package/dist/jsonSchemaLibrary.js +1 -1
  6. package/dist/lib/addValidator.d.ts +2 -1
  7. package/dist/lib/compile/index.d.ts +11 -0
  8. package/dist/lib/config/strings.d.ts +1 -39
  9. package/dist/lib/cores/CoreInterface.d.ts +28 -9
  10. package/dist/lib/cores/Draft04.d.ts +2 -2
  11. package/dist/lib/cores/Draft06.d.ts +15 -0
  12. package/dist/lib/cores/Draft07.d.ts +15 -0
  13. package/dist/lib/cores/JsonEditor.d.ts +2 -2
  14. package/dist/lib/draft06/addSchema.d.ts +7 -0
  15. package/dist/lib/draft06/compile/index.d.ts +15 -0
  16. package/dist/lib/draft06/validation/keyword.d.ts +3 -0
  17. package/dist/lib/draft06/validation/type.d.ts +17 -0
  18. package/dist/lib/draft06/validation/typeKeywordMapping.d.ts +13 -0
  19. package/dist/lib/getChildSchemaSelection.d.ts +7 -5
  20. package/dist/lib/getSchema.d.ts +1 -1
  21. package/dist/lib/getTemplate.d.ts +5 -1
  22. package/dist/lib/getTypeOf.d.ts +2 -1
  23. package/dist/lib/schema/getTypeId.d.ts +1 -1
  24. package/dist/lib/step.d.ts +4 -4
  25. package/dist/lib/types.d.ts +10 -2
  26. package/dist/lib/utils/filter.d.ts +0 -1
  27. package/dist/lib/utils/merge.d.ts +3 -0
  28. package/dist/lib/validate.d.ts +1 -1
  29. package/dist/lib/validation/format.d.ts +6 -0
  30. package/dist/lib/validation/keyword.d.ts +2 -27
  31. package/dist/lib/validation/type.d.ts +3 -10
  32. package/dist/lib/validation/typeKeywordMapping.d.ts +4 -4
  33. package/dist/module/index.js +13 -6
  34. package/dist/module/lib/addValidator.js +3 -4
  35. package/dist/module/lib/compile/getRef.js +1 -1
  36. package/dist/module/lib/compile/index.js +11 -0
  37. package/dist/module/lib/config/strings.js +15 -2
  38. package/dist/module/lib/cores/CoreInterface.js +22 -0
  39. package/dist/module/lib/cores/Draft06.js +61 -0
  40. package/dist/module/lib/cores/Draft07.js +61 -0
  41. package/dist/module/lib/createSchemaOf.js +1 -1
  42. package/dist/module/lib/draft06/addSchema.js +11 -0
  43. package/dist/module/lib/draft06/compile/index.js +65 -0
  44. package/dist/module/lib/draft06/validation/keyword.js +156 -0
  45. package/dist/module/lib/draft06/validation/type.js +30 -0
  46. package/dist/module/lib/draft06/validation/typeKeywordMapping.js +15 -0
  47. package/dist/module/lib/each.js +1 -1
  48. package/dist/module/lib/eachSchema.js +3 -3
  49. package/dist/module/lib/getChildSchemaSelection.js +7 -6
  50. package/dist/module/lib/getSchema.js +2 -1
  51. package/dist/module/lib/getTemplate.js +57 -23
  52. package/dist/module/lib/resolveAllOf.js +3 -4
  53. package/dist/module/lib/resolveOneOf.fuzzy.js +13 -3
  54. package/dist/module/lib/resolveOneOf.strict.js +11 -2
  55. package/dist/module/lib/resolveRef.strict.js +8 -0
  56. package/dist/module/lib/schema/getTypeDefs.js +12 -1
  57. package/dist/module/lib/schema/getTypeId.js +1 -1
  58. package/dist/module/lib/step.js +62 -11
  59. package/dist/module/lib/types.js +7 -1
  60. package/dist/module/lib/utils/filter.js +3 -5
  61. package/dist/module/lib/utils/merge.js +3 -0
  62. package/dist/module/lib/validate.js +33 -8
  63. package/dist/module/lib/validateAsync.js +7 -7
  64. package/dist/module/lib/validation/errors.js +15 -2
  65. package/dist/module/lib/validation/format.js +105 -4
  66. package/dist/module/lib/validation/keyword.js +77 -30
  67. package/dist/module/lib/validation/type.js +2 -1
  68. package/dist/module/remotes/draft06.json +155 -0
  69. package/dist/module/remotes/draft07.json +172 -0
  70. package/dist/module/remotes/index.js +0 -1
  71. package/dist/remotes/index.d.ts +0 -1
  72. package/index.ts +14 -5
  73. package/lib/addValidator.ts +5 -5
  74. package/lib/compile/getRef.ts +1 -1
  75. package/lib/compile/index.ts +11 -1
  76. package/lib/config/strings.ts +17 -3
  77. package/lib/cores/CoreInterface.ts +37 -10
  78. package/lib/cores/Draft04.ts +2 -4
  79. package/lib/cores/Draft06.ts +76 -0
  80. package/lib/cores/Draft07.ts +75 -0
  81. package/lib/cores/JsonEditor.ts +2 -4
  82. package/lib/createSchemaOf.ts +1 -3
  83. package/lib/draft06/addSchema.ts +14 -0
  84. package/lib/draft06/compile/index.ts +68 -0
  85. package/lib/draft06/validation/keyword.ts +177 -0
  86. package/lib/draft06/validation/type.ts +43 -0
  87. package/lib/draft06/validation/typeKeywordMapping.ts +15 -0
  88. package/lib/each.ts +8 -3
  89. package/lib/eachSchema.ts +3 -3
  90. package/lib/getChildSchemaSelection.ts +14 -7
  91. package/lib/getSchema.ts +15 -7
  92. package/lib/getTemplate.ts +148 -38
  93. package/lib/getTypeOf.ts +2 -1
  94. package/lib/resolveAllOf.ts +9 -5
  95. package/lib/resolveOneOf.fuzzy.ts +25 -8
  96. package/lib/resolveOneOf.strict.ts +17 -4
  97. package/lib/resolveRef.strict.ts +9 -0
  98. package/lib/schema/getTypeDefs.ts +14 -1
  99. package/lib/schema/getTypeId.ts +2 -2
  100. package/lib/step.ts +103 -22
  101. package/lib/types.ts +21 -4
  102. package/lib/utils/filter.ts +4 -6
  103. package/lib/utils/merge.ts +4 -0
  104. package/lib/validate.ts +45 -15
  105. package/lib/validateAsync.ts +13 -12
  106. package/lib/validation/errors.ts +15 -2
  107. package/lib/validation/format.ts +113 -4
  108. package/lib/validation/keyword.ts +147 -78
  109. package/lib/validation/type.ts +5 -1
  110. package/package.json +73 -63
  111. package/remotes/draft06.json +155 -0
  112. package/remotes/draft07.json +172 -0
  113. package/remotes/draft2019-09.json +86 -0
  114. package/remotes/index.ts +0 -2
  115. package/tsconfig.json +2 -9
@@ -0,0 +1,177 @@
1
+ import Keywords from "../../validation/keyword";
2
+ import getTypeOf from "../../getTypeOf";
3
+ import { JSONValidator } from "../../types";
4
+
5
+ const KeywordValidation: Record<string, JSONValidator> = {
6
+ ...Keywords,
7
+ // @draft >= 6
8
+ contains: (core, schema, value, pointer) => {
9
+ if (schema.contains === false) {
10
+ return core.errors.containsArrayError({ pointer, value });
11
+ }
12
+
13
+ if (schema.contains === true) {
14
+ if (Array.isArray(value) && value.length === 0) {
15
+ return core.errors.containsAnyError({ pointer });
16
+ }
17
+ return undefined;
18
+ }
19
+
20
+ if (getTypeOf(schema.contains) !== "object") {
21
+ // ignore invalid schema
22
+ return undefined;
23
+ }
24
+
25
+ for (let i = 0; i < value.length; i += 1) {
26
+ if (core.isValid(value[i], schema.contains)) {
27
+ return undefined;
28
+ }
29
+ }
30
+ return core.errors.containsError({ pointer, schema: JSON.stringify(schema.contains) });
31
+ },
32
+ exclusiveMaximum: (core, schema, value, pointer) => {
33
+ if (isNaN(schema.exclusiveMaximum)) {
34
+ return undefined;
35
+ }
36
+ if (schema.exclusiveMaximum <= value) {
37
+ return core.errors.maximumError({ maximum: schema.exclusiveMaximum, length: value, pointer });
38
+ }
39
+ return undefined;
40
+ },
41
+ exclusiveMinimum: (core, schema, value, pointer) => {
42
+ if (isNaN(schema.exclusiveMinimum)) {
43
+ return undefined;
44
+ }
45
+ if (schema.exclusiveMinimum >= value) {
46
+ return core.errors.minimumError({ minimum: schema.exclusiveMinimum, length: value, pointer });
47
+ }
48
+ return undefined;
49
+ },
50
+ if: (core, schema, value, pointer) => {
51
+ if (schema.if == null) {
52
+ return undefined;
53
+ }
54
+
55
+ const ifErrors = core.validate(value, schema.if, pointer);
56
+ // console.log("if Errors", value, ifErrors);
57
+
58
+ if (ifErrors.length === 0 && schema.then) {
59
+ return core.validate(value, schema.then, pointer);
60
+ }
61
+
62
+ if (ifErrors.length !== 0 && schema.else) {
63
+ return core.validate(value, schema.else, pointer);
64
+ }
65
+ },
66
+ maximum: (core, schema, value, pointer) => {
67
+ if (isNaN(schema.maximum)) {
68
+ return undefined;
69
+ }
70
+ if (schema.maximum && schema.maximum < value) {
71
+ return core.errors.maximumError({ maximum: schema.maximum, length: value, pointer });
72
+ }
73
+ return undefined;
74
+ },
75
+ minimum: (core, schema, value, pointer) => {
76
+ if (isNaN(schema.minimum)) {
77
+ return undefined;
78
+ }
79
+ if (schema.minimum > value) {
80
+ return core.errors.minimumError({ minimum: schema.minimum, length: value, pointer });
81
+ }
82
+ return undefined;
83
+ },
84
+ patternProperties: (core, schema, value, pointer) => {
85
+ const properties = schema.properties || {};
86
+ const pp = schema.patternProperties;
87
+ if (getTypeOf(pp) !== "object") {
88
+ return undefined;
89
+ }
90
+
91
+ const errors = [];
92
+ const keys = Object.keys(value);
93
+ const patterns = Object.keys(pp).map(expr => ({
94
+ regex: new RegExp(expr),
95
+ patternSchema: pp[expr]
96
+ }));
97
+
98
+ keys.forEach(key => {
99
+ let patternFound = false;
100
+
101
+ for (let i = 0, l = patterns.length; i < l; i += 1) {
102
+ if (patterns[i].regex.test(key)) {
103
+ patternFound = true;
104
+
105
+ // for a boolean schema `false`, always invalidate
106
+ if (patterns[i].patternSchema === false) {
107
+ errors.push(core.errors.patternPropertiesError({
108
+ key, pointer, patterns: Object.keys(pp).join(",")
109
+ }));
110
+ return;
111
+ }
112
+
113
+ const valErrors = core.validate(value[key], patterns[i].patternSchema, `${pointer}/${key}`);
114
+ if (valErrors && valErrors.length > 0) {
115
+ errors.push(...valErrors);
116
+ }
117
+ }
118
+ }
119
+
120
+ if (properties[key]) {
121
+ return;
122
+ }
123
+
124
+ if (patternFound === false && schema.additionalProperties === false) {
125
+ // this is an arrangement with additionalProperties
126
+ errors.push(core.errors.patternPropertiesError({
127
+ key, pointer, patterns: Object.keys(pp).join(",")
128
+ }));
129
+ }
130
+ });
131
+
132
+ return errors;
133
+ },
134
+ // @draft >= 6
135
+ propertyNames: (core, schema, value, pointer) => {
136
+ // bool schema
137
+ if (schema.propertyNames === false) {
138
+ // empty objects are valid
139
+ if (Object.keys(value).length === 0) {
140
+ return undefined;
141
+ }
142
+ return core.errors.invalidPropertyNameError({
143
+ property: Object.keys(value),
144
+ pointer,
145
+ value
146
+ });
147
+ }
148
+
149
+ if (schema.propertyNames === true) {
150
+ return undefined;
151
+ }
152
+
153
+ if (getTypeOf(schema.propertyNames) !== "object") {
154
+ // ignore invalid schema
155
+ return undefined;
156
+ }
157
+
158
+ const errors = [];
159
+ const properties = Object.keys(value);
160
+ const propertySchema = { ...schema.propertyNames, type: "string" };
161
+ properties.forEach(prop => {
162
+ const validationResult = core.validate(prop, propertySchema, `${pointer}/${prop}`);
163
+ if (validationResult.length > 0) {
164
+ errors.push(core.errors.invalidPropertyNameError({
165
+ property: prop,
166
+ pointer,
167
+ validationError: validationResult[0],
168
+ value: value[prop]
169
+ }))
170
+ }
171
+ });
172
+
173
+ return errors;
174
+ }
175
+ }
176
+
177
+ export default KeywordValidation;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @todo: type is also a keyword, as is properties, items, etc
3
+ *
4
+ * An instance has one of six primitive types (http://json-schema.org/latest/json-schema-core.html#rfc.section.4.2)
5
+ * or seven in case of ajv https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#type
6
+ * 1 null, 2 boolean, 3 object, 4 array, 5 number, 6 string (7 integer)
7
+ */
8
+ export default {
9
+
10
+ array: (core, schema, value, pointer) => core.typeKeywords.array
11
+ .filter(key => schema && schema[key] != null)
12
+ .map(key => core.validateKeyword[key](core, schema, value, pointer)),
13
+
14
+ object: (core, schema, value, pointer) =>
15
+ core.typeKeywords.object
16
+ .filter(key => schema && schema[key] != null)
17
+ .map(key => core.validateKeyword[key](core, schema, value, pointer)),
18
+
19
+ string: (core, schema, value, pointer) =>
20
+ core.typeKeywords.string
21
+ .filter(key => schema && schema[key] != null)
22
+ .map(key => core.validateKeyword[key](core, schema, value, pointer)),
23
+
24
+ integer: (core, schema, value, pointer) =>
25
+ core.typeKeywords.number
26
+ .filter(key => schema && schema[key] != null)
27
+ .map(key => core.validateKeyword[key](core, schema, value, pointer)),
28
+
29
+ number: (core, schema, value, pointer) =>
30
+ core.typeKeywords.number
31
+ .filter(key => schema && schema[key] != null)
32
+ .map(key => core.validateKeyword[key](core, schema, value, pointer)),
33
+
34
+ "boolean": (core, schema, value, pointer) =>
35
+ core.typeKeywords.boolean
36
+ .filter(key => schema && schema[key] != null)
37
+ .map(key => core.validateKeyword[key](core, schema, value, pointer)),
38
+
39
+ "null": (core, schema, value, pointer) =>
40
+ core.typeKeywords.null
41
+ .filter(key => schema && schema[key] != null)
42
+ .map(key => core.validateKeyword[key](core, schema, value, pointer))
43
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Mapping, used in type validation to iterate over type-specific keywords to validate
3
+ * - overview https://epoberezkin.github.io/ajv/keywords.html
4
+ */
5
+ export default {
6
+ array: ["enum", "contains", "items", "minItems", "maxItems", "uniqueItems", "not", "if"],
7
+ boolean: ["enum", "not"],
8
+ object: [
9
+ "additionalProperties", "dependencies", "enum", "format", "minProperties", "maxProperties",
10
+ "patternProperties", "properties", "propertyNames", "required", "not", "oneOf", "allOf", "anyOf", "if"
11
+ ],
12
+ string: ["enum", "format", "maxLength", "minLength", "pattern", "not", "oneOf", "allOf", "anyOf", "if"],
13
+ number: ["enum", "exclusiveMaximum", "exclusiveMinimum", "format", "maximum", "minimum", "multipleOf", "not", "oneOf", "allOf", "anyOf", "if"],
14
+ null: ["enum", "format", "not", "oneOf", "allOf", "anyOf"]
15
+ };
package/lib/each.ts CHANGED
@@ -2,7 +2,6 @@ import Core from "./cores/CoreInterface";
2
2
  import getTypeOf from "./getTypeOf";
3
3
  import { JSONSchema, JSONPointer } from "./types";
4
4
 
5
-
6
5
  /**
7
6
  * Iterates over data, retrieving its schema
8
7
  *
@@ -12,12 +11,18 @@ import { JSONSchema, JSONPointer } from "./types";
12
11
  * @param [schema] - the schema matching the data. Defaults to rootSchema
13
12
  * @param [pointer] - pointer to current data. Default to rootPointer
14
13
  */
15
- export default function each(core: Core, data: any, callback, schema: JSONSchema = core.rootSchema, pointer: JSONPointer = "#") {
14
+ export default function each(
15
+ core: Core,
16
+ data: any,
17
+ callback,
18
+ schema: JSONSchema = core.rootSchema,
19
+ pointer: JSONPointer = "#"
20
+ ) {
16
21
  callback(schema, data, pointer);
17
22
  const dataType = getTypeOf(data);
18
23
 
19
24
  if (dataType === "object") {
20
- Object.keys(data).forEach(key => {
25
+ Object.keys(data).forEach((key) => {
21
26
  const nextSchema = core.step(key, schema, data, pointer); // not save
22
27
  const next = data[key]; // save
23
28
  core.each(next, callback, nextSchema, `${pointer}/${key}`);
package/lib/eachSchema.ts CHANGED
@@ -30,11 +30,11 @@ function nextTypeDefs(schema: JSONSchema, pointer: JSONPointer) {
30
30
  function eachDefinition(walk: Walker, schema: JSONSchema, pointer: JSONPointer) {
31
31
  Object.keys(schema.definitions)
32
32
  .forEach(defId => {
33
- if (!isObject(schema.definitions[defId])) {
34
- console.log(`Invalid schema in ${pointer}/definitions/${defId}`);
33
+ if (schema.definitions[defId] === false || isObject(schema.definitions[defId])) {
34
+ walk.nextTypeDefs(schema.definitions[defId], gp.join(pointer, "definitions", defId, false));
35
35
  return;
36
36
  }
37
- walk.nextTypeDefs(schema.definitions[defId], gp.join(pointer, "definitions", defId, false));
37
+ console.log(`Invalid schema in ${pointer}/definitions/${defId}`);
38
38
  });
39
39
  }
40
40
 
@@ -1,19 +1,26 @@
1
+ import CoreInterface from "./cores/CoreInterface";
2
+ import { isJSONError, JSONError, JSONSchema } from "./types";
3
+
1
4
  /**
2
5
  * Returns a list of possible child-schemas for the given property key. In case of a oneOf selection, multiple schemas
3
6
  * could be added at the given property (e.g. item-index), thus an array of options is returned. In all other cases
4
7
  * a list with a single item will be returned
5
8
  *
6
- * @param {Core} core - core to use
7
- * @param {String} property - parent schema of following property
8
- * @param {Object} [schema] - parent schema of following property
9
- * @return {Object}
9
+ * @param core - core to use
10
+ * @param property - parent schema of following property
11
+ * @param [schema] - parent schema of following property
12
+ * @return
10
13
  */
11
- export default function getChildSchemaSelection(core, property, schema = core.rootSchema) {
14
+ export default function getChildSchemaSelection(
15
+ core: CoreInterface,
16
+ property: string | number,
17
+ schema: JSONSchema = core.rootSchema
18
+ ): JSONSchema[] | JSONError {
12
19
  const result = core.step(property, schema, {}, "#");
13
20
 
14
- if (result.type === "error") {
21
+ if (isJSONError(result)) {
15
22
  if (result.code === "one-of-error") {
16
- return result.data.oneOf.map(item => core.resolveRef(item));
23
+ return result.data.oneOf.map((item) => core.resolveRef(item));
17
24
  }
18
25
  return result;
19
26
  }
package/lib/getSchema.ts CHANGED
@@ -1,11 +1,9 @@
1
1
  import gp from "gson-pointer";
2
- import { JSONSchema, JSONPointer } from "./types";
2
+ import { JSONSchema, JSONPointer, isJSONError } from "./types";
3
3
  import Core from "./cores/CoreInterface";
4
4
 
5
-
6
5
  const emptyObject = {};
7
6
 
8
-
9
7
  /**
10
8
  * Returns the json-schema of a data-json-pointer.
11
9
  *
@@ -19,20 +17,30 @@ const emptyObject = {};
19
17
  * @param [schema] - the json schema to iterate. Defaults to core.rootSchema
20
18
  * @return json schema object of the json-pointer or an error
21
19
  */
22
- export default function getSchema(core: Core, pointer: JSONPointer, data?: any, schema: JSONSchema = core.rootSchema): JSONSchema {
20
+ export default function getSchema(
21
+ core: Core,
22
+ pointer: JSONPointer,
23
+ data?: unknown,
24
+ schema: JSONSchema = core.rootSchema
25
+ ): JSONSchema {
23
26
  const frags = gp.split(pointer);
24
27
  return _get(core, schema, frags, pointer, data);
25
28
  }
26
29
 
27
-
28
- function _get(core: Core, schema: JSONSchema, frags: Array<string>, pointer: JSONPointer, data: any = emptyObject): JSONSchema {
30
+ function _get(
31
+ core: Core,
32
+ schema: JSONSchema,
33
+ frags: Array<string>,
34
+ pointer: JSONPointer,
35
+ data: unknown = emptyObject
36
+ ): JSONSchema {
29
37
  if (frags.length === 0) {
30
38
  return schema;
31
39
  }
32
40
 
33
41
  const key = frags.shift(); // step key
34
42
  schema = core.step(key, schema, data, pointer); // step schema
35
- if (schema && schema.type === "error") {
43
+ if (isJSONError(schema)) {
36
44
  return schema;
37
45
  }
38
46
  data = data[key]; // step data