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
@@ -4,28 +4,44 @@ import getTypeOf from "./getTypeOf";
4
4
  import merge from "./utils/merge";
5
5
  import copy from "./utils/copy";
6
6
  import settings from "./config/settings";
7
- import { JSONSchema, JSONPointer } from "./types";
7
+ import { JSONSchema, JSONPointer, isJSONError } from "./types";
8
8
  import Core from "./cores/CoreInterface";
9
9
 
10
+ interface TemplateOptions {
11
+ /** Add all properties (required and optional) to the generated data */
12
+ addOptionalProps: boolean;
13
+ }
14
+
15
+ const defaultOptions: TemplateOptions = {
16
+ addOptionalProps: true
17
+ };
10
18
 
11
19
  let cache;
12
20
  function shouldResolveRef(schema: JSONSchema, pointer: JSONPointer) {
13
21
  // ensure we refactored consistently
14
- if (pointer == null) { throw new Error("Missing pointer"); }
22
+ if (pointer == null) {
23
+ throw new Error("Missing pointer");
24
+ }
15
25
 
16
26
  const { $ref } = schema;
17
- if ($ref == null) { return true; }
27
+ if ($ref == null) {
28
+ return true;
29
+ }
18
30
 
19
- const value = (cache[pointer] == null || cache[pointer][$ref] == null) ? 0 : cache[pointer][$ref];
31
+ const value = cache[pointer] == null || cache[pointer][$ref] == null ? 0 : cache[pointer][$ref];
20
32
  return value < settings.GET_TEMPLATE_RECURSION_LIMIT;
21
33
  }
22
34
 
23
35
  function resolveRef(core: Core, schema: JSONSchema, pointer: JSONPointer) {
24
36
  // ensure we refactored consistently
25
- if (pointer == null) { throw new Error(`missing pointer ${pointer}`); }
37
+ if (pointer == null) {
38
+ throw new Error(`missing pointer ${pointer}`);
39
+ }
26
40
 
27
41
  const { $ref } = schema;
28
- if ($ref == null) { return schema; }
42
+ if ($ref == null) {
43
+ return schema;
44
+ }
29
45
 
30
46
  // @todo pointer + ref is redundant?
31
47
  cache[pointer] = cache[pointer] || {};
@@ -34,7 +50,6 @@ function resolveRef(core: Core, schema: JSONSchema, pointer: JSONPointer) {
34
50
  return core.resolveRef(schema);
35
51
  }
36
52
 
37
-
38
53
  function convertValue(type: string, value: any) {
39
54
  if (type === "string") {
40
55
  return JSON.stringify(value);
@@ -59,13 +74,20 @@ function convertValue(type: string, value: any) {
59
74
  * @param pointer
60
75
  * @return resolved json-schema or input-schema
61
76
  */
62
- function createTemplateSchema(core: Core, schema: JSONSchema, data, pointer: JSONPointer): JSONSchema|false {
77
+ function createTemplateSchema(
78
+ core: Core,
79
+ schema: JSONSchema,
80
+ data,
81
+ pointer: JSONPointer
82
+ ): JSONSchema | false {
63
83
  // invalid schema
64
84
  if (getTypeOf(schema) !== "object") {
65
85
  return Object.assign({ pointer }, schema);
66
86
  }
67
87
  // return if reached recursion limit
68
- if (shouldResolveRef(schema, pointer) === false && data == null) { return false; }
88
+ if (shouldResolveRef(schema, pointer) === false && data == null) {
89
+ return false;
90
+ }
69
91
 
70
92
  // resolve $ref and copy schema
71
93
  let templateSchema = copy(resolveRef(core, schema, pointer));
@@ -86,7 +108,10 @@ function createTemplateSchema(core: Core, schema: JSONSchema, data, pointer: JSO
86
108
  for (let i = 0, l = schema.allOf.length; i < l; i += 1) {
87
109
  // test if we may resolve
88
110
  if (shouldResolveRef(schema.allOf[i], `${pointer}/allOf/${i}`)) {
89
- templateSchema = merge(templateSchema, resolveRef(core, schema.allOf[i], `${pointer}/allOf/${i}`));
111
+ templateSchema = merge(
112
+ templateSchema,
113
+ resolveRef(core, schema.allOf[i], `${pointer}/allOf/${i}`)
114
+ );
90
115
  // add pointer return-value, if any
91
116
  templateSchema.pointer = schema.allOf[i].$ref || templateSchema.pointer;
92
117
  }
@@ -108,21 +133,37 @@ const isJSONSchema = (template): template is JSONSchema => template && typeof te
108
133
  * @param [schema] - json schema, defaults to rootSchema
109
134
  * @return created template data
110
135
  */
111
- function getTemplate(core, data, _schema: JSONSchema, pointer: JSONPointer) {
112
- if (_schema == null) { throw new Error(`getTemplate: missing schema for data: ${JSON.stringify(data)}`); }
113
- if (pointer == null) { throw new Error("Missing pointer"); }
136
+ function getTemplate(
137
+ core: Core,
138
+ data?: unknown,
139
+ _schema?: JSONSchema,
140
+ pointer?: JSONPointer,
141
+ opts?: TemplateOptions
142
+ ) {
143
+ if (_schema == null) {
144
+ throw new Error(`getTemplate: missing schema for data: ${JSON.stringify(data)}`);
145
+ }
146
+ if (pointer == null) {
147
+ throw new Error("Missing pointer");
148
+ }
114
149
 
115
150
  // resolve $ref references, allOf and first anyOf definitions
116
151
  let schema = createTemplateSchema(core, _schema, data, pointer);
117
- if (!isJSONSchema(schema)) { return undefined; }
152
+ if (!isJSONSchema(schema)) {
153
+ return undefined;
154
+ }
118
155
  pointer = schema.pointer;
119
156
 
157
+ if (schema?.const) {
158
+ return schema.const;
159
+ }
160
+
120
161
  if (schema.oneOf) {
121
162
  // find correct schema for data
122
163
  const resolvedSchema = resolveOneOfFuzzy(core, data, schema);
123
- if (data == null && resolvedSchema.type === "error") {
164
+ if (data == null && isJSONError(resolvedSchema)) {
124
165
  schema = schema.oneOf[0];
125
- } else if (resolvedSchema.type === "error") {
166
+ } else if (isJSONError(resolvedSchema.type)) {
126
167
  // @todo - check: do not return schema, but either input-data or undefined (clearing wrong data)
127
168
  return data;
128
169
  } else {
@@ -130,6 +171,10 @@ function getTemplate(core, data, _schema: JSONSchema, pointer: JSONPointer) {
130
171
  }
131
172
  }
132
173
 
174
+ // @todo Array.isArray(schema.type)
175
+ // -> hasDefault? return
176
+ // if not -> pick first type
177
+
133
178
  if (!isJSONSchema(schema) || schema.type == null) {
134
179
  return undefined;
135
180
  }
@@ -139,41 +184,83 @@ function getTemplate(core, data, _schema: JSONSchema, pointer: JSONPointer) {
139
184
  data = convertValue(schema.type, data);
140
185
  }
141
186
 
142
- if (TYPE[schema.type] == null) { // eslint-disable-line no-use-before-define
187
+ if (TYPE[schema.type] == null) {
188
+ // eslint-disable-line no-use-before-define
143
189
  throw new Error(`Unsupported type '${schema.type} in ${JSON.stringify(schema)}'`);
144
190
  }
145
191
 
146
- const templateData = TYPE[schema.type](core, schema, data, pointer); // eslint-disable-line no-use-before-define
192
+ const templateData = TYPE[schema.type](core, schema, data, pointer, opts); // eslint-disable-line no-use-before-define
147
193
  return templateData;
148
194
  }
149
195
 
150
-
151
196
  const TYPE = {
152
- "string": (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, ""),
153
- "number": (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, 0),
154
- "integer": (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, 0),
155
- "boolean": (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, false),
156
- "object": (core: Core, schema: JSONSchema, data: any, pointer: JSONPointer) => {
197
+ null: (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, null),
198
+ string: (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, ""),
199
+ number: (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, 0),
200
+ integer: (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, 0),
201
+ boolean: (core: Core, schema: JSONSchema, data: any) => getDefault(schema, data, false),
202
+ object: (
203
+ core: Core,
204
+ schema: JSONSchema,
205
+ data: any,
206
+ pointer: JSONPointer,
207
+ opts: TemplateOptions
208
+ ) => {
157
209
  const template = schema.default === undefined ? {} : schema.default;
158
210
  const d = {}; // do not assign data here, to keep ordering from json-schema
159
211
 
160
212
  if (schema.properties) {
161
- Object.keys(schema.properties).forEach(key => {
162
- const value = (data == null || data[key] == null) ? template[key] : data[key];
163
- d[key] = getTemplate(core, value, schema.properties[key], `${pointer}/properties/${key}`);
213
+ Object.keys(schema.properties).forEach((key) => {
214
+ const value = data == null || data[key] == null ? template[key] : data[key];
215
+ const isRequired = Array.isArray(schema.required) && schema.required.includes(key);
216
+
217
+ // Omit adding a property if it is not required or optional props should be added
218
+ if (value != null || isRequired || opts.addOptionalProps) {
219
+ d[key] = getTemplate(
220
+ core,
221
+ value,
222
+ schema.properties[key],
223
+ `${pointer}/properties/${key}`,
224
+ opts
225
+ );
226
+ }
227
+ });
228
+ }
229
+
230
+ if (schema.dependencies) {
231
+ Object.keys(schema.dependencies).forEach((key) => {
232
+ const dependency = schema.dependencies[key];
233
+ if (getTypeOf(dependency) !== "object") {
234
+ return;
235
+ }
236
+ if (d[key] === undefined) {
237
+ return;
238
+ }
239
+
240
+ const result = getTemplate(
241
+ core,
242
+ data,
243
+ { ...dependency, type: "object" },
244
+ `${pointer}/dependencies/${key}`,
245
+ opts
246
+ );
247
+
248
+ if (result && !isJSONError(result)) {
249
+ Object.assign(d, result);
250
+ }
164
251
  });
165
252
  }
166
253
 
167
254
  if (data) {
168
255
  // merge any missing data (additionals) to resulting object
169
- Object.keys(data).forEach(key => (d[key] == null && (d[key] = data[key])));
256
+ Object.keys(data).forEach((key) => d[key] == null && (d[key] = data[key]));
170
257
  }
171
258
 
172
259
  // returns object, which is ordered by json-schema
173
260
  return d;
174
261
  },
175
262
  // build array type of items, ignores additionalItems
176
- "array": (core: Core, schema: JSONSchema, data, pointer: JSONPointer) => {
263
+ array: (core: Core, schema: JSONSchema, data, pointer: JSONPointer, opts: TemplateOptions) => {
177
264
  const template = schema.default === undefined ? [] : schema.default;
178
265
  const d = data || [];
179
266
  schema.minItems = schema.minItems || 0;
@@ -186,7 +273,13 @@ const TYPE = {
186
273
  // build defined set of items
187
274
  if (Array.isArray(schema.items)) {
188
275
  for (let i = 0, l = Math.min(schema.minItems, schema.items.length); i < l; i += 1) {
189
- d[i] = getTemplate(core, d[i] == null ? template[i] : d[i], schema.items[i], `${pointer}/items/${i}`);
276
+ d[i] = getTemplate(
277
+ core,
278
+ d[i] == null ? template[i] : d[i],
279
+ schema.items[i],
280
+ `${pointer}/items/${i}`,
281
+ opts
282
+ );
190
283
  }
191
284
  return d;
192
285
  }
@@ -207,7 +300,13 @@ const TYPE = {
207
300
  if (templateSchema.oneOf && d.length === 0) {
208
301
  const oneOfSchema = templateSchema.oneOf[0];
209
302
  for (let i = 0; i < schema.minItems; i += 1) {
210
- d[i] = getTemplate(core, d[i] == null ? template[i] : d[i], oneOfSchema, `${pointer}/oneOf/0`);
303
+ d[i] = getTemplate(
304
+ core,
305
+ d[i] == null ? template[i] : d[i],
306
+ oneOfSchema,
307
+ `${pointer}/oneOf/0`,
308
+ opts
309
+ );
211
310
  }
212
311
  return d;
213
312
  }
@@ -218,7 +317,7 @@ const TYPE = {
218
317
  const value = d[i] == null ? template[i] : d[i];
219
318
  const one = resolveOneOfFuzzy(core, value, templateSchema);
220
319
  if (one) {
221
- d[i] = getTemplate(core, value, one, `${pointer}/oneOf/${i}`);
320
+ d[i] = getTemplate(core, value, one, `${pointer}/oneOf/${i}`, opts);
222
321
  } else {
223
322
  d[i] = value;
224
323
  }
@@ -229,7 +328,13 @@ const TYPE = {
229
328
  // build items-definition
230
329
  if (templateSchema.type) {
231
330
  for (let i = 0, l = Math.max(schema.minItems, d.length); i < l; i += 1) {
232
- d[i] = getTemplate(core, d[i] == null ? template[i] : d[i], templateSchema, `${pointer}/items`);
331
+ d[i] = getTemplate(
332
+ core,
333
+ d[i] == null ? template[i] : d[i],
334
+ templateSchema,
335
+ `${pointer}/items`,
336
+ opts
337
+ );
233
338
  }
234
339
  return d;
235
340
  }
@@ -238,10 +343,11 @@ const TYPE = {
238
343
  }
239
344
  };
240
345
 
241
-
242
346
  function getDefault(schema: JSONSchema, templateValue: any, initValue: any) {
243
347
  if (templateValue != null) {
244
348
  return templateValue;
349
+ } else if (schema.const) {
350
+ return schema.const;
245
351
  } else if (schema.default === undefined && Array.isArray(schema.enum)) {
246
352
  return schema.enum[0];
247
353
  } else if (schema.default === undefined) {
@@ -250,8 +356,12 @@ function getDefault(schema: JSONSchema, templateValue: any, initValue: any) {
250
356
  return schema.default;
251
357
  }
252
358
 
253
-
254
- export default (core: Core, data?: any, schema: JSONSchema = core.rootSchema) => {
255
- cache = { "mi": ".." };
256
- return getTemplate(core, data, schema, "#");
359
+ export default (
360
+ core: Core,
361
+ data?: any,
362
+ schema: JSONSchema = core.rootSchema,
363
+ opts: TemplateOptions = defaultOptions
364
+ ) => {
365
+ cache = { mi: ".." };
366
+ return getTemplate(core, data, schema, "#", opts);
257
367
  };
package/lib/getTypeOf.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  const toString = Object.prototype.toString;
2
2
 
3
+ export type JSType = "array"|"bigint"|"boolean"|"function"|"null"|"number"|"object"|"string"|"symbol"|"undefined";
3
4
 
4
- export default function getTypeOf(value: any) {
5
+ export default function getTypeOf(value: unknown) : JSType {
5
6
  // eslint-disable-next-line newline-per-chained-call
6
7
  return toString.call(value).match(/\s([^\]]+)\]/).pop().toLowerCase();
7
8
  }
@@ -4,14 +4,18 @@ import errors from "./validation/errors";
4
4
  import { JSONSchema, JSONPointer, JSONError } from "./types";
5
5
  import Core from "./cores/CoreInterface";
6
6
 
7
-
8
- export default function resolveAllOf(core: Core, data: any, schema: JSONSchema = core.rootSchema, pointer: JSONPointer = "#"): JSONSchema|JSONError {
7
+ export default function resolveAllOf(
8
+ core: Core,
9
+ data: any,
10
+ schema: JSONSchema = core.rootSchema,
11
+ pointer: JSONPointer = "#"
12
+ ): JSONSchema | JSONError {
9
13
  let mergedSchema = copy(schema);
10
14
  for (let i = 0; i < schema.allOf.length; i += 1) {
11
15
  const allOfSchema = core.resolveRef(schema.allOf[i]);
12
- if (core.isValid(data, allOfSchema, pointer) === false) {
13
- return errors.allOfError({ value: data, pointer, allOf: JSON.stringify(schema.allOf) });
14
- }
16
+ // if (core.isValid(data, allOfSchema, pointer) === false) {
17
+ // return errors.allOfError({ value: data, pointer, allOf: JSON.stringify(schema.allOf) });
18
+ // }
15
19
  mergedSchema = merge(mergedSchema, allOfSchema);
16
20
  }
17
21
 
@@ -2,10 +2,9 @@ import { errorOrPromise } from "./utils/filter";
2
2
  import flattenArray from "./utils/flattenArray";
3
3
  import getTypeOf from "./getTypeOf";
4
4
  import settings from "./config/settings";
5
- import { JSONSchema, JSONPointer, JSONError } from "./types";
5
+ import { JSONSchema, JSONPointer, JSONError, isJSONError } from "./types";
6
6
  import Core from "./cores/CoreInterface";
7
7
 
8
-
9
8
  const { DECLARATOR_ONEOF } = settings;
10
9
 
11
10
  /**
@@ -17,7 +16,12 @@ const { DECLARATOR_ONEOF } = settings;
17
16
  * @param [pointer]
18
17
  * @return ranking value (higher is better)
19
18
  */
20
- function fuzzyObjectValue(core: Core, one: JSONSchema, data: { [p: string]: any }, pointer?: JSONPointer) {
19
+ function fuzzyObjectValue(
20
+ core: Core,
21
+ one: JSONSchema,
22
+ data: { [p: string]: any },
23
+ pointer?: JSONPointer
24
+ ) {
21
25
  if (data == null || one.properties == null) {
22
26
  return -1;
23
27
  }
@@ -43,7 +47,12 @@ function fuzzyObjectValue(core: Core, one: JSONSchema, data: { [p: string]: any
43
47
  * @param [pointer] - json pointer to data
44
48
  * @return oneOf schema or an error
45
49
  */
46
- export default function resolveOneOf(core: Core, data: any, schema: JSONSchema = core.rootSchema, pointer: JSONPointer = "#"): JSONSchema|JSONError {
50
+ export default function resolveOneOf(
51
+ core: Core,
52
+ data: any,
53
+ schema: JSONSchema = core.rootSchema,
54
+ pointer: JSONPointer = "#"
55
+ ): JSONSchema | JSONError {
47
56
  // !keyword: oneOfProperty
48
57
  // an additional <DECLARATOR_ONEOF> (default `oneOfProperty`) on the schema will exactly determine the
49
58
  // oneOf value (if set in data)
@@ -52,7 +61,6 @@ export default function resolveOneOf(core: Core, data: any, schema: JSONSchema =
52
61
  // abort if no data is given an DECLARATOR_ONEOF is set (used by getChildSchemaSelection)
53
62
  // this case (data != null) should not be necessary
54
63
  if (data != null && schema[DECLARATOR_ONEOF]) {
55
-
56
64
  const errors = [];
57
65
  const oneOfProperty = schema[DECLARATOR_ONEOF];
58
66
  const oneOfValue = data[schema[DECLARATOR_ONEOF]];
@@ -65,7 +73,7 @@ export default function resolveOneOf(core: Core, data: any, schema: JSONSchema =
65
73
  const one = core.resolveRef(schema.oneOf[i]);
66
74
  const oneOfPropertySchema = core.step(oneOfProperty, one, data, pointer);
67
75
 
68
- if (oneOfPropertySchema && oneOfPropertySchema.type === "error") {
76
+ if (isJSONError(oneOfPropertySchema)) {
69
77
  return oneOfPropertySchema;
70
78
  }
71
79
 
@@ -79,7 +87,12 @@ export default function resolveOneOf(core: Core, data: any, schema: JSONSchema =
79
87
  }
80
88
  }
81
89
 
82
- return core.errors.oneOfPropertyError({ property: oneOfProperty, value: oneOfValue, pointer, errors });
90
+ return core.errors.oneOfPropertyError({
91
+ property: oneOfProperty,
92
+ value: oneOfValue,
93
+ pointer,
94
+ errors
95
+ });
83
96
  }
84
97
 
85
98
  // keyword: oneOf
@@ -111,7 +124,11 @@ export default function resolveOneOf(core: Core, data: any, schema: JSONSchema =
111
124
  }
112
125
 
113
126
  if (schemaOfItem === undefined) {
114
- return core.errors.oneOfError({ value: JSON.stringify(data), pointer, oneOf: schema.oneOf });
127
+ return core.errors.oneOfError({
128
+ value: JSON.stringify(data),
129
+ pointer,
130
+ oneOf: schema.oneOf
131
+ });
115
132
  }
116
133
 
117
134
  return schemaOfItem;
@@ -3,7 +3,6 @@ import flattenArray from "./utils/flattenArray";
3
3
  import Core from "./cores/CoreInterface";
4
4
  import { JSONSchema, JSONError, JSONPointer } from "./types";
5
5
 
6
-
7
6
  /**
8
7
  * Selects and returns a oneOf schema for the given data
9
8
  *
@@ -13,7 +12,12 @@ import { JSONSchema, JSONError, JSONPointer } from "./types";
13
12
  * @param pointer - json pointer to data
14
13
  * @return oneOf schema or an error
15
14
  */
16
- export default function resolveOneOf(core: Core, data: any, schema: JSONSchema = core.rootSchema, pointer: JSONPointer = "#"): JSONSchema|JSONError {
15
+ export default function resolveOneOf(
16
+ core: Core,
17
+ data: any,
18
+ schema: JSONSchema = core.rootSchema,
19
+ pointer: JSONPointer = "#"
20
+ ): JSONSchema | JSONError {
17
21
  const matches = [];
18
22
  const errors = [];
19
23
  for (let i = 0; i < schema.oneOf.length; i += 1) {
@@ -33,8 +37,17 @@ export default function resolveOneOf(core: Core, data: any, schema: JSONSchema =
33
37
  return matches[0];
34
38
  }
35
39
  if (matches.length > 1) {
36
- return core.errors.multipleOneOfError({ value: data, pointer, matches });
40
+ return core.errors.multipleOneOfError({
41
+ value: data,
42
+ pointer,
43
+ matches,
44
+ });
37
45
  }
38
46
 
39
- return core.errors.oneOfError({ value: JSON.stringify(data), pointer, oneOf: schema.oneOf, errors });
47
+ return core.errors.oneOfError({
48
+ value: JSON.stringify(data),
49
+ pointer,
50
+ oneOf: schema.oneOf,
51
+ errors,
52
+ });
40
53
  }
@@ -6,6 +6,15 @@ export default function resolveRef(schema: JSONSchema, rootSchema: JSONSchema):
6
6
  return schema;
7
7
  }
8
8
 
9
+ if (schema.getRoot) {
10
+ // we actually always need to resolve the schema like this, since returned subschemas
11
+ // must resolve relative from their schema
12
+ const resolvedSchema = schema.getRoot().getRef(schema);
13
+ // console.log(schema.$ref, "=>", resolvedSchema);
14
+ return resolvedSchema;
15
+ }
16
+
17
+ // tryout - this should never be called, except we missed something
9
18
  const resolvedSchema = rootSchema.getRef(schema);
10
19
  return resolvedSchema;
11
20
  }
@@ -19,7 +19,20 @@ export default function getTypeDefs(schema: JSONSchema): Array<{ pointer: JSONPo
19
19
  if (id == null) {
20
20
  return defs;
21
21
  }
22
- const type = types[id];
22
+
23
+ let type;
24
+ if (Array.isArray(id)) {
25
+ // since types can also be declared as a set of types, merge the definitions
26
+ // maybe this will require a more sophisticated approach
27
+ type = {};
28
+ for (let i = 0, l = id.length; i < l; i += 1) {
29
+ Object.assign(type, types[id[i]]);
30
+ }
31
+
32
+ } else {
33
+ type = types[id];
34
+ }
35
+
23
36
  if (type.definitions == null) {
24
37
  return defs;
25
38
  }
@@ -12,7 +12,7 @@ const typeKeywords = Object.keys(types).filter(id => types[id].type === false);
12
12
  * @param schema
13
13
  * @return type id, if found
14
14
  */
15
- export default function getTypeId(schema: JSONSchema): string|undefined {
15
+ export default function getTypeId(schema: JSONSchema): string|string[]|undefined {
16
16
  if (isObject(schema) === false) {
17
17
  return undefined;
18
18
  }
@@ -21,7 +21,7 @@ export default function getTypeId(schema: JSONSchema): string|undefined {
21
21
  return "enum";
22
22
  }
23
23
 
24
- if (types[schema.type]) {
24
+ if (types[schema.type] || Array.isArray(schema.type)) {
25
25
  return schema.type;
26
26
  }
27
27