json-schema-library 5.3.0 → 7.0.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.
- package/.editorconfig +1 -0
- package/.prettierignore +1 -0
- package/.prettierrc +7 -0
- package/CHANGELOG.md +106 -0
- package/README.md +811 -199
- package/TASKS.md +3 -81
- package/dist/index.d.ts +29 -71
- package/dist/jsonSchemaLibrary.js +1 -1
- package/dist/lib/SchemaService.d.ts +6 -8
- package/dist/lib/{addSchema.d.ts → addRemoteSchema.d.ts} +2 -1
- package/dist/lib/addValidator.d.ts +3 -2
- package/dist/lib/compile/getRef.d.ts +2 -1
- package/dist/lib/compile/index.d.ts +15 -1
- package/dist/lib/compile/types.d.ts +5 -0
- package/dist/lib/config/strings.d.ts +1 -39
- package/dist/lib/draft/index.d.ts +132 -0
- package/dist/lib/draft04/index.d.ts +7 -0
- package/dist/lib/draft06/compile/index.d.ts +16 -0
- package/dist/lib/draft06/index.d.ts +7 -0
- package/dist/lib/draft06/validation/keyword.d.ts +3 -0
- package/dist/lib/draft06/validation/type.d.ts +10 -0
- package/dist/lib/draft06/validation/typeKeywordMapping.d.ts +13 -0
- package/dist/lib/draft07/index.d.ts +7 -0
- package/dist/lib/each.d.ts +3 -2
- package/dist/lib/eachSchema.d.ts +2 -4
- package/dist/lib/getChildSchemaSelection.d.ts +7 -5
- package/dist/lib/getSchema.d.ts +2 -2
- package/dist/lib/getTemplate.d.ts +1 -1
- package/dist/lib/getTypeOf.d.ts +2 -1
- package/dist/lib/isValid.d.ts +1 -1
- package/dist/lib/jsoneditor/index.d.ts +7 -0
- package/dist/lib/resolveAllOf.d.ts +1 -1
- package/dist/lib/resolveAnyOf.d.ts +1 -1
- package/dist/lib/resolveOneOf.fuzzy.d.ts +1 -1
- package/dist/lib/resolveOneOf.strict.d.ts +2 -2
- package/dist/lib/{resolveRef.withOverwrite.d.ts → resolveRef.merge.d.ts} +0 -0
- package/dist/lib/schema/getTypeDefs.d.ts +6 -4
- package/dist/lib/schema/getTypeId.d.ts +1 -1
- package/dist/lib/schema/types.d.ts +7 -57
- package/dist/lib/step.d.ts +5 -5
- package/dist/lib/types.d.ts +11 -3
- package/dist/lib/utils/createCustomError.d.ts +8 -11
- package/dist/lib/utils/filter.d.ts +4 -4
- package/dist/lib/utils/flattenArray.d.ts +1 -1
- package/dist/lib/utils/merge.d.ts +3 -0
- package/dist/lib/utils/punycode.ucs2decode.d.ts +1 -1
- package/dist/lib/validate.d.ts +2 -2
- package/dist/lib/validateAsync.d.ts +1 -1
- package/dist/lib/validation/errors.d.ts +1 -3
- package/dist/lib/validation/format.d.ts +4 -11
- package/dist/lib/validation/keyword.d.ts +2 -27
- package/dist/lib/validation/type.d.ts +3 -10
- package/dist/lib/validation/typeKeywordMapping.d.ts +4 -4
- package/dist/module/index.js +23 -32
- package/dist/module/lib/SchemaService.js +7 -4
- package/dist/module/lib/{addSchema.js → addRemoteSchema.js} +2 -4
- package/dist/module/lib/addValidator.js +3 -4
- package/dist/module/lib/compile/getRef.js +1 -1
- package/dist/module/lib/compile/index.js +43 -18
- package/dist/module/lib/compile/types.js +1 -0
- package/dist/module/lib/config/strings.js +15 -2
- package/dist/module/lib/createSchemaOf.js +1 -1
- package/dist/module/lib/draft/index.js +133 -0
- package/dist/module/lib/draft04/index.js +90 -0
- package/dist/module/lib/draft06/compile/index.js +77 -0
- package/dist/module/lib/draft06/index.js +96 -0
- package/dist/module/lib/draft06/validation/keyword.js +168 -0
- package/dist/module/lib/draft06/validation/type.js +31 -0
- package/dist/module/lib/draft06/validation/typeKeywordMapping.js +15 -0
- package/dist/module/lib/draft07/index.js +96 -0
- package/dist/module/lib/each.js +2 -2
- package/dist/module/lib/eachSchema.js +28 -19
- package/dist/module/lib/getChildSchemaSelection.js +7 -6
- package/dist/module/lib/getSchema.js +4 -2
- package/dist/module/lib/getTemplate.js +42 -15
- package/dist/module/lib/jsoneditor/index.js +16 -0
- package/dist/module/lib/resolveAllOf.js +3 -4
- package/dist/module/lib/resolveOneOf.fuzzy.js +13 -3
- package/dist/module/lib/resolveOneOf.strict.js +49 -2
- package/dist/module/lib/{resolveRef.withOverwrite.js → resolveRef.merge.js} +0 -0
- package/dist/module/lib/resolveRef.strict.js +8 -0
- package/dist/module/lib/schema/getTypeDefs.js +14 -3
- package/dist/module/lib/schema/getTypeId.js +10 -6
- package/dist/module/lib/schema/types.js +33 -9
- package/dist/module/lib/step.js +67 -13
- package/dist/module/lib/types.js +7 -1
- package/dist/module/lib/utils/createCustomError.js +4 -4
- package/dist/module/lib/utils/filter.js +3 -5
- package/dist/module/lib/utils/flattenArray.js +4 -3
- package/dist/module/lib/utils/merge.js +4 -0
- package/dist/module/lib/utils/punycode.ucs2decode.js +4 -3
- package/dist/module/lib/validate.js +34 -8
- package/dist/module/lib/validateAsync.js +7 -7
- package/dist/module/lib/validation/errors.js +16 -3
- package/dist/module/lib/validation/format.js +115 -8
- package/dist/module/lib/validation/keyword.js +79 -32
- package/dist/module/lib/validation/type.js +2 -1
- package/index.ts +46 -32
- package/lib/SchemaService.ts +18 -11
- package/lib/{addSchema.ts → addRemoteSchema.ts} +3 -5
- package/lib/addValidator.ts +15 -12
- package/lib/compile/getRef.ts +3 -4
- package/lib/compile/index.ts +65 -19
- package/lib/compile/types.ts +6 -0
- package/lib/config/strings.ts +17 -3
- package/lib/createSchemaOf.ts +1 -3
- package/lib/draft/index.ts +201 -0
- package/lib/draft04/index.ts +95 -0
- package/lib/draft06/compile/index.ts +104 -0
- package/lib/draft06/index.ts +101 -0
- package/lib/draft06/validation/keyword.ts +199 -0
- package/lib/draft06/validation/type.ts +47 -0
- package/lib/draft06/validation/typeKeywordMapping.ts +15 -0
- package/lib/draft07/index.ts +101 -0
- package/lib/each.ts +11 -4
- package/lib/eachSchema.ts +45 -32
- package/lib/getChildSchemaSelection.ts +14 -7
- package/lib/getSchema.ts +18 -9
- package/lib/getTemplate.ts +155 -42
- package/lib/getTypeOf.ts +2 -1
- package/lib/isValid.ts +7 -3
- package/lib/jsoneditor/index.ts +20 -0
- package/lib/resolveAllOf.ts +10 -6
- package/lib/resolveAnyOf.ts +7 -3
- package/lib/resolveOneOf.fuzzy.ts +26 -9
- package/lib/resolveOneOf.strict.ts +63 -5
- package/lib/{resolveRef.withOverwrite.ts → resolveRef.merge.ts} +0 -0
- package/lib/resolveRef.strict.ts +9 -0
- package/lib/schema/getTypeDefs.ts +19 -7
- package/lib/schema/getTypeId.ts +11 -8
- package/lib/schema/types.ts +41 -9
- package/lib/step.ts +109 -25
- package/lib/types.ts +23 -5
- package/lib/utils/createCustomError.ts +8 -13
- package/lib/utils/filter.ts +7 -9
- package/lib/utils/flattenArray.ts +5 -4
- package/lib/utils/merge.ts +5 -0
- package/lib/utils/punycode.ucs2decode.ts +6 -5
- package/lib/validate.ts +47 -16
- package/lib/validateAsync.ts +15 -14
- package/lib/validation/errors.ts +17 -6
- package/lib/validation/format.ts +147 -13
- package/lib/validation/keyword.ts +172 -103
- package/lib/validation/type.ts +5 -1
- package/package.json +75 -63
- package/{dist/module/remotes/draft04.json → remotes/draft06.json} +47 -42
- package/remotes/draft07.json +172 -0
- package/remotes/draft2019-09.json +86 -0
- package/tsconfig.json +3 -10
- package/dist/lib/cores/CoreInterface.d.ts +0 -23
- package/dist/lib/cores/Draft04.d.ts +0 -13
- package/dist/lib/cores/JsonEditor.d.ts +0 -13
- package/dist/module/lib/cores/CoreInterface.js +0 -51
- package/dist/module/lib/cores/Draft04.js +0 -52
- package/dist/module/lib/cores/JsonEditor.js +0 -51
- package/dist/module/remotes/index.js +0 -10
- package/dist/remotes/index.d.ts +0 -5
- package/lib/cores/CoreInterface.ts +0 -76
- package/lib/cores/Draft04.ts +0 -66
- package/lib/cores/JsonEditor.ts +0 -64
- package/remotes/index.ts +0 -11
package/lib/getTemplate.ts
CHANGED
|
@@ -4,9 +4,8 @@ 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";
|
|
8
|
-
import Core from "./
|
|
9
|
-
|
|
7
|
+
import { JSONSchema, JSONPointer, isJSONError } from "./types";
|
|
8
|
+
import { Draft as Core } from "./draft";
|
|
10
9
|
|
|
11
10
|
interface TemplateOptions {
|
|
12
11
|
/** Add all properties (required and optional) to the generated data */
|
|
@@ -17,24 +16,32 @@ const defaultOptions: TemplateOptions = {
|
|
|
17
16
|
addOptionalProps: true
|
|
18
17
|
};
|
|
19
18
|
|
|
20
|
-
let cache
|
|
19
|
+
let cache: Record<string, JSONSchema>;
|
|
21
20
|
function shouldResolveRef(schema: JSONSchema, pointer: JSONPointer) {
|
|
22
21
|
// ensure we refactored consistently
|
|
23
|
-
if (pointer == null) {
|
|
22
|
+
if (pointer == null) {
|
|
23
|
+
throw new Error("Missing pointer");
|
|
24
|
+
}
|
|
24
25
|
|
|
25
26
|
const { $ref } = schema;
|
|
26
|
-
if ($ref == null) {
|
|
27
|
+
if ($ref == null) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
27
30
|
|
|
28
|
-
const value =
|
|
31
|
+
const value = cache[pointer] == null || cache[pointer][$ref] == null ? 0 : cache[pointer][$ref];
|
|
29
32
|
return value < settings.GET_TEMPLATE_RECURSION_LIMIT;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
function resolveRef(core: Core, schema: JSONSchema, pointer: JSONPointer) {
|
|
33
36
|
// ensure we refactored consistently
|
|
34
|
-
if (pointer == null) {
|
|
37
|
+
if (pointer == null) {
|
|
38
|
+
throw new Error(`missing pointer ${pointer}`);
|
|
39
|
+
}
|
|
35
40
|
|
|
36
41
|
const { $ref } = schema;
|
|
37
|
-
if ($ref == null) {
|
|
42
|
+
if ($ref == null) {
|
|
43
|
+
return schema;
|
|
44
|
+
}
|
|
38
45
|
|
|
39
46
|
// @todo pointer + ref is redundant?
|
|
40
47
|
cache[pointer] = cache[pointer] || {};
|
|
@@ -43,7 +50,6 @@ function resolveRef(core: Core, schema: JSONSchema, pointer: JSONPointer) {
|
|
|
43
50
|
return core.resolveRef(schema);
|
|
44
51
|
}
|
|
45
52
|
|
|
46
|
-
|
|
47
53
|
function convertValue(type: string, value: any) {
|
|
48
54
|
if (type === "string") {
|
|
49
55
|
return JSON.stringify(value);
|
|
@@ -68,13 +74,20 @@ function convertValue(type: string, value: any) {
|
|
|
68
74
|
* @param pointer
|
|
69
75
|
* @return resolved json-schema or input-schema
|
|
70
76
|
*/
|
|
71
|
-
function createTemplateSchema(
|
|
77
|
+
function createTemplateSchema(
|
|
78
|
+
core: Core,
|
|
79
|
+
schema: JSONSchema,
|
|
80
|
+
data: unknown,
|
|
81
|
+
pointer: JSONPointer
|
|
82
|
+
): JSONSchema | false {
|
|
72
83
|
// invalid schema
|
|
73
84
|
if (getTypeOf(schema) !== "object") {
|
|
74
85
|
return Object.assign({ pointer }, schema);
|
|
75
86
|
}
|
|
76
87
|
// return if reached recursion limit
|
|
77
|
-
if (shouldResolveRef(schema, pointer) === false && data == null) {
|
|
88
|
+
if (shouldResolveRef(schema, pointer) === false && data == null) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
78
91
|
|
|
79
92
|
// resolve $ref and copy schema
|
|
80
93
|
let templateSchema = copy(resolveRef(core, schema, pointer));
|
|
@@ -95,7 +108,10 @@ function createTemplateSchema(core: Core, schema: JSONSchema, data, pointer: JSO
|
|
|
95
108
|
for (let i = 0, l = schema.allOf.length; i < l; i += 1) {
|
|
96
109
|
// test if we may resolve
|
|
97
110
|
if (shouldResolveRef(schema.allOf[i], `${pointer}/allOf/${i}`)) {
|
|
98
|
-
templateSchema = merge(
|
|
111
|
+
templateSchema = merge(
|
|
112
|
+
templateSchema,
|
|
113
|
+
resolveRef(core, schema.allOf[i], `${pointer}/allOf/${i}`)
|
|
114
|
+
);
|
|
99
115
|
// add pointer return-value, if any
|
|
100
116
|
templateSchema.pointer = schema.allOf[i].$ref || templateSchema.pointer;
|
|
101
117
|
}
|
|
@@ -107,7 +123,8 @@ function createTemplateSchema(core: Core, schema: JSONSchema, data, pointer: JSO
|
|
|
107
123
|
return templateSchema;
|
|
108
124
|
}
|
|
109
125
|
|
|
110
|
-
const isJSONSchema = (template): template is JSONSchema =>
|
|
126
|
+
const isJSONSchema = (template: unknown): template is JSONSchema =>
|
|
127
|
+
template && typeof template === "object";
|
|
111
128
|
|
|
112
129
|
/**
|
|
113
130
|
* Create data object matching the given schema
|
|
@@ -117,21 +134,37 @@ const isJSONSchema = (template): template is JSONSchema => template && typeof te
|
|
|
117
134
|
* @param [schema] - json schema, defaults to rootSchema
|
|
118
135
|
* @return created template data
|
|
119
136
|
*/
|
|
120
|
-
function getTemplate(
|
|
121
|
-
|
|
122
|
-
|
|
137
|
+
function getTemplate(
|
|
138
|
+
core: Core,
|
|
139
|
+
data?: unknown,
|
|
140
|
+
_schema?: JSONSchema,
|
|
141
|
+
pointer?: JSONPointer,
|
|
142
|
+
opts?: TemplateOptions
|
|
143
|
+
) {
|
|
144
|
+
if (_schema == null) {
|
|
145
|
+
throw new Error(`getTemplate: missing schema for data: ${JSON.stringify(data)}`);
|
|
146
|
+
}
|
|
147
|
+
if (pointer == null) {
|
|
148
|
+
throw new Error("Missing pointer");
|
|
149
|
+
}
|
|
123
150
|
|
|
124
151
|
// resolve $ref references, allOf and first anyOf definitions
|
|
125
152
|
let schema = createTemplateSchema(core, _schema, data, pointer);
|
|
126
|
-
if (!isJSONSchema(schema)) {
|
|
153
|
+
if (!isJSONSchema(schema)) {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
127
156
|
pointer = schema.pointer;
|
|
128
157
|
|
|
158
|
+
if (schema?.const) {
|
|
159
|
+
return schema.const;
|
|
160
|
+
}
|
|
161
|
+
|
|
129
162
|
if (schema.oneOf) {
|
|
130
163
|
// find correct schema for data
|
|
131
164
|
const resolvedSchema = resolveOneOfFuzzy(core, data, schema);
|
|
132
|
-
if (data == null && resolvedSchema
|
|
165
|
+
if (data == null && isJSONError(resolvedSchema)) {
|
|
133
166
|
schema = schema.oneOf[0];
|
|
134
|
-
} else if (resolvedSchema.type
|
|
167
|
+
} else if (isJSONError(resolvedSchema.type)) {
|
|
135
168
|
// @todo - check: do not return schema, but either input-data or undefined (clearing wrong data)
|
|
136
169
|
return data;
|
|
137
170
|
} else {
|
|
@@ -139,6 +172,10 @@ function getTemplate(core, data, _schema: JSONSchema, pointer: JSONPointer, opts
|
|
|
139
172
|
}
|
|
140
173
|
}
|
|
141
174
|
|
|
175
|
+
// @todo Array.isArray(schema.type)
|
|
176
|
+
// -> hasDefault? return
|
|
177
|
+
// if not -> pick first type
|
|
178
|
+
|
|
142
179
|
if (!isJSONSchema(schema) || schema.type == null) {
|
|
143
180
|
return undefined;
|
|
144
181
|
}
|
|
@@ -148,7 +185,8 @@ function getTemplate(core, data, _schema: JSONSchema, pointer: JSONPointer, opts
|
|
|
148
185
|
data = convertValue(schema.type, data);
|
|
149
186
|
}
|
|
150
187
|
|
|
151
|
-
if (TYPE[schema.type] == null) {
|
|
188
|
+
if (TYPE[schema.type] == null) {
|
|
189
|
+
// eslint-disable-line no-use-before-define
|
|
152
190
|
throw new Error(`Unsupported type '${schema.type} in ${JSON.stringify(schema)}'`);
|
|
153
191
|
}
|
|
154
192
|
|
|
@@ -156,42 +194,94 @@ function getTemplate(core, data, _schema: JSONSchema, pointer: JSONPointer, opts
|
|
|
156
194
|
return templateData;
|
|
157
195
|
}
|
|
158
196
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
197
|
+
const TYPE: Record<
|
|
198
|
+
string,
|
|
199
|
+
(
|
|
200
|
+
core: Core,
|
|
201
|
+
schema: JSONSchema,
|
|
202
|
+
data: unknown,
|
|
203
|
+
pointer: JSONPointer,
|
|
204
|
+
opts: TemplateOptions
|
|
205
|
+
) => unknown
|
|
206
|
+
> = {
|
|
207
|
+
null: (core, schema, data) => getDefault(schema, data, null),
|
|
208
|
+
string: (core, schema, data) => getDefault(schema, data, ""),
|
|
209
|
+
number: (core, schema, data) => getDefault(schema, data, 0),
|
|
210
|
+
integer: (core, schema, data) => getDefault(schema, data, 0),
|
|
211
|
+
boolean: (core, schema, data) => getDefault(schema, data, false),
|
|
212
|
+
object: (
|
|
213
|
+
core,
|
|
214
|
+
schema,
|
|
215
|
+
data: Record<string, unknown> | undefined,
|
|
216
|
+
pointer: JSONPointer,
|
|
217
|
+
opts: TemplateOptions
|
|
218
|
+
) => {
|
|
166
219
|
const template = schema.default === undefined ? {} : schema.default;
|
|
167
|
-
const d = {}; // do not assign data here, to keep ordering from json-schema
|
|
220
|
+
const d: Record<string, unknown> = {}; // do not assign data here, to keep ordering from json-schema
|
|
168
221
|
|
|
169
222
|
if (schema.properties) {
|
|
170
|
-
Object.keys(schema.properties).forEach(key => {
|
|
171
|
-
const value =
|
|
223
|
+
Object.keys(schema.properties).forEach((key) => {
|
|
224
|
+
const value = data == null || data[key] == null ? template[key] : data[key];
|
|
172
225
|
const isRequired = Array.isArray(schema.required) && schema.required.includes(key);
|
|
173
226
|
|
|
174
227
|
// Omit adding a property if it is not required or optional props should be added
|
|
175
228
|
if (value != null || isRequired || opts.addOptionalProps) {
|
|
176
|
-
d[key] = getTemplate(
|
|
229
|
+
d[key] = getTemplate(
|
|
230
|
+
core,
|
|
231
|
+
value,
|
|
232
|
+
schema.properties[key],
|
|
233
|
+
`${pointer}/properties/${key}`,
|
|
234
|
+
opts
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (schema.dependencies) {
|
|
241
|
+
Object.keys(schema.dependencies).forEach((key) => {
|
|
242
|
+
const dependency = schema.dependencies[key];
|
|
243
|
+
if (getTypeOf(dependency) !== "object") {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (d[key] === undefined) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const result = getTemplate(
|
|
251
|
+
core,
|
|
252
|
+
data,
|
|
253
|
+
{ ...dependency, type: "object" },
|
|
254
|
+
`${pointer}/dependencies/${key}`,
|
|
255
|
+
opts
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
if (result && !isJSONError(result)) {
|
|
259
|
+
Object.assign(d, result);
|
|
177
260
|
}
|
|
178
261
|
});
|
|
179
262
|
}
|
|
180
263
|
|
|
181
264
|
if (data) {
|
|
182
265
|
// merge any missing data (additionals) to resulting object
|
|
183
|
-
Object.keys(data).forEach(key =>
|
|
266
|
+
Object.keys(data).forEach((key) => d[key] == null && (d[key] = data[key]));
|
|
184
267
|
}
|
|
185
268
|
|
|
186
269
|
// returns object, which is ordered by json-schema
|
|
187
270
|
return d;
|
|
188
271
|
},
|
|
189
272
|
// build array type of items, ignores additionalItems
|
|
190
|
-
|
|
273
|
+
array: (
|
|
274
|
+
core: Core,
|
|
275
|
+
schema: JSONSchema,
|
|
276
|
+
data: unknown[],
|
|
277
|
+
pointer: JSONPointer,
|
|
278
|
+
opts: TemplateOptions
|
|
279
|
+
) => {
|
|
191
280
|
const template = schema.default === undefined ? [] : schema.default;
|
|
192
|
-
const d = data || [];
|
|
193
281
|
schema.minItems = schema.minItems || 0;
|
|
194
282
|
|
|
283
|
+
const d: unknown[] = data || [];
|
|
284
|
+
|
|
195
285
|
// items are undefined
|
|
196
286
|
if (schema.items == null) {
|
|
197
287
|
return d;
|
|
@@ -200,7 +290,13 @@ const TYPE = {
|
|
|
200
290
|
// build defined set of items
|
|
201
291
|
if (Array.isArray(schema.items)) {
|
|
202
292
|
for (let i = 0, l = Math.min(schema.minItems, schema.items.length); i < l; i += 1) {
|
|
203
|
-
d[i] = getTemplate(
|
|
293
|
+
d[i] = getTemplate(
|
|
294
|
+
core,
|
|
295
|
+
d[i] == null ? template[i] : d[i],
|
|
296
|
+
schema.items[i],
|
|
297
|
+
`${pointer}/items/${i}`,
|
|
298
|
+
opts
|
|
299
|
+
);
|
|
204
300
|
}
|
|
205
301
|
return d;
|
|
206
302
|
}
|
|
@@ -221,7 +317,13 @@ const TYPE = {
|
|
|
221
317
|
if (templateSchema.oneOf && d.length === 0) {
|
|
222
318
|
const oneOfSchema = templateSchema.oneOf[0];
|
|
223
319
|
for (let i = 0; i < schema.minItems; i += 1) {
|
|
224
|
-
d[i] = getTemplate(
|
|
320
|
+
d[i] = getTemplate(
|
|
321
|
+
core,
|
|
322
|
+
d[i] == null ? template[i] : d[i],
|
|
323
|
+
oneOfSchema,
|
|
324
|
+
`${pointer}/oneOf/0`,
|
|
325
|
+
opts
|
|
326
|
+
);
|
|
225
327
|
}
|
|
226
328
|
return d;
|
|
227
329
|
}
|
|
@@ -243,7 +345,13 @@ const TYPE = {
|
|
|
243
345
|
// build items-definition
|
|
244
346
|
if (templateSchema.type) {
|
|
245
347
|
for (let i = 0, l = Math.max(schema.minItems, d.length); i < l; i += 1) {
|
|
246
|
-
d[i] = getTemplate(
|
|
348
|
+
d[i] = getTemplate(
|
|
349
|
+
core,
|
|
350
|
+
d[i] == null ? template[i] : d[i],
|
|
351
|
+
templateSchema,
|
|
352
|
+
`${pointer}/items`,
|
|
353
|
+
opts
|
|
354
|
+
);
|
|
247
355
|
}
|
|
248
356
|
return d;
|
|
249
357
|
}
|
|
@@ -252,10 +360,11 @@ const TYPE = {
|
|
|
252
360
|
}
|
|
253
361
|
};
|
|
254
362
|
|
|
255
|
-
|
|
256
363
|
function getDefault(schema: JSONSchema, templateValue: any, initValue: any) {
|
|
257
364
|
if (templateValue != null) {
|
|
258
365
|
return templateValue;
|
|
366
|
+
} else if (schema.const) {
|
|
367
|
+
return schema.const;
|
|
259
368
|
} else if (schema.default === undefined && Array.isArray(schema.enum)) {
|
|
260
369
|
return schema.enum[0];
|
|
261
370
|
} else if (schema.default === undefined) {
|
|
@@ -264,8 +373,12 @@ function getDefault(schema: JSONSchema, templateValue: any, initValue: any) {
|
|
|
264
373
|
return schema.default;
|
|
265
374
|
}
|
|
266
375
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
376
|
+
export default (
|
|
377
|
+
core: Core,
|
|
378
|
+
data?: any,
|
|
379
|
+
schema: JSONSchema = core.rootSchema,
|
|
380
|
+
opts: TemplateOptions = defaultOptions
|
|
381
|
+
) => {
|
|
382
|
+
cache = { mi: {} };
|
|
270
383
|
return getTemplate(core, data, schema, "#", opts);
|
|
271
384
|
};
|
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:
|
|
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
|
}
|
package/lib/isValid.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { JSONSchema, JSONPointer } from "./types";
|
|
2
|
-
import Core from "./
|
|
3
|
-
|
|
2
|
+
import { Draft as Core } from "./draft";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Test if the data is valid according to the given schema
|
|
@@ -11,6 +10,11 @@ import Core from "./cores/CoreInterface";
|
|
|
11
10
|
* @param [pointer] - json pointer pointing to value
|
|
12
11
|
* @return if schema does match given value
|
|
13
12
|
*/
|
|
14
|
-
export default function isValid(
|
|
13
|
+
export default function isValid(
|
|
14
|
+
core: Core,
|
|
15
|
+
value: any,
|
|
16
|
+
schema: JSONSchema = core.rootSchema,
|
|
17
|
+
pointer: JSONPointer = "#"
|
|
18
|
+
): boolean {
|
|
15
19
|
return core.validate(value, schema, pointer).length === 0;
|
|
16
20
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import merge from "../utils/merge";
|
|
2
|
+
import resolveOneOf from "../resolveOneOf.fuzzy";
|
|
3
|
+
import resolveRef from "../resolveRef.merge";
|
|
4
|
+
import { Draft, DraftConfig } from "../draft";
|
|
5
|
+
import { draft07Config } from "../draft07";
|
|
6
|
+
import { JSONSchema } from "../types";
|
|
7
|
+
|
|
8
|
+
const draftJsonEditorConfig: DraftConfig = {
|
|
9
|
+
...draft07Config,
|
|
10
|
+
resolveOneOf,
|
|
11
|
+
resolveRef
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
class JsonEditor extends Draft {
|
|
15
|
+
constructor(schema?: JSONSchema, config: Partial<DraftConfig> = {}) {
|
|
16
|
+
super(merge(draftJsonEditorConfig, config), schema);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { JsonEditor, draftJsonEditorConfig };
|
package/lib/resolveAllOf.ts
CHANGED
|
@@ -2,16 +2,20 @@ import copy from "./utils/copy";
|
|
|
2
2
|
import merge from "./utils/merge";
|
|
3
3
|
import errors from "./validation/errors";
|
|
4
4
|
import { JSONSchema, JSONPointer, JSONError } from "./types";
|
|
5
|
-
import Core from "./
|
|
5
|
+
import { Draft as Core } from "./draft";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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
|
|
package/lib/resolveAnyOf.ts
CHANGED
|
@@ -2,10 +2,14 @@ import copy from "./utils/copy";
|
|
|
2
2
|
import merge from "./utils/merge";
|
|
3
3
|
import errors from "./validation/errors";
|
|
4
4
|
import { JSONSchema, JSONPointer, JSONError } from "./types";
|
|
5
|
-
import Core from "./
|
|
5
|
+
import { Draft as Core } from "./draft";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export default function resolveAnyOf(
|
|
8
|
+
core: Core,
|
|
9
|
+
data: any,
|
|
10
|
+
schema: JSONSchema = core.rootSchema,
|
|
11
|
+
pointer: JSONPointer = "#"
|
|
12
|
+
): JSONSchema | JSONError {
|
|
9
13
|
let found = false;
|
|
10
14
|
let mergedSchema = copy(schema);
|
|
11
15
|
for (let i = 0; i < schema.anyOf.length; i += 1) {
|
|
@@ -2,9 +2,8 @@ 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";
|
|
6
|
-
import Core from "./
|
|
7
|
-
|
|
5
|
+
import { JSONSchema, JSONPointer, JSONError, isJSONError } from "./types";
|
|
6
|
+
import { Draft as Core } from "./draft";
|
|
8
7
|
|
|
9
8
|
const { DECLARATOR_ONEOF } = settings;
|
|
10
9
|
|
|
@@ -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(
|
|
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(
|
|
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
|
|
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({
|
|
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({
|
|
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;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { errorOrPromise } from "./utils/filter";
|
|
2
2
|
import flattenArray from "./utils/flattenArray";
|
|
3
|
-
import
|
|
4
|
-
import { JSONSchema, JSONError,
|
|
3
|
+
import settings from "./config/settings";
|
|
4
|
+
import { JSONSchema, JSONPointer, JSONError, isJSONError } from "./types";
|
|
5
|
+
import { Draft as Core } from "./draft";
|
|
5
6
|
|
|
7
|
+
const { DECLARATOR_ONEOF } = settings;
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Selects and returns a oneOf schema for the given data
|
|
@@ -13,7 +15,54 @@ import { JSONSchema, JSONError, JSONPointer } from "./types";
|
|
|
13
15
|
* @param pointer - json pointer to data
|
|
14
16
|
* @return oneOf schema or an error
|
|
15
17
|
*/
|
|
16
|
-
export default function resolveOneOf(
|
|
18
|
+
export default function resolveOneOf(
|
|
19
|
+
core: Core,
|
|
20
|
+
data: any,
|
|
21
|
+
schema: JSONSchema = core.rootSchema,
|
|
22
|
+
pointer: JSONPointer = "#"
|
|
23
|
+
): JSONSchema | JSONError {
|
|
24
|
+
// !keyword: oneOfProperty
|
|
25
|
+
// an additional <DECLARATOR_ONEOF> (default `oneOfProperty`) on the schema will exactly determine the
|
|
26
|
+
// oneOf value (if set in data)
|
|
27
|
+
|
|
28
|
+
// @fixme
|
|
29
|
+
// abort if no data is given an DECLARATOR_ONEOF is set (used by getChildSchemaSelection)
|
|
30
|
+
// this case (data != null) should not be necessary
|
|
31
|
+
if (data != null && schema[DECLARATOR_ONEOF]) {
|
|
32
|
+
const errors = [];
|
|
33
|
+
const oneOfProperty = schema[DECLARATOR_ONEOF];
|
|
34
|
+
const oneOfValue = data[schema[DECLARATOR_ONEOF]];
|
|
35
|
+
|
|
36
|
+
if (oneOfValue === undefined) {
|
|
37
|
+
return core.errors.missingOneOfPropertyError({ property: oneOfProperty, pointer });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (let i = 0; i < schema.oneOf.length; i += 1) {
|
|
41
|
+
const one = core.resolveRef(schema.oneOf[i]);
|
|
42
|
+
const oneOfPropertySchema = core.step(oneOfProperty, one, data, pointer);
|
|
43
|
+
|
|
44
|
+
if (isJSONError(oneOfPropertySchema)) {
|
|
45
|
+
return oneOfPropertySchema;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let result = flattenArray(core.validate(oneOfValue, oneOfPropertySchema, pointer));
|
|
49
|
+
result = result.filter(errorOrPromise);
|
|
50
|
+
|
|
51
|
+
if (result.length > 0) {
|
|
52
|
+
errors.push(...result);
|
|
53
|
+
} else {
|
|
54
|
+
return one; // return resolved schema
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return core.errors.oneOfPropertyError({
|
|
59
|
+
property: oneOfProperty,
|
|
60
|
+
value: oneOfValue,
|
|
61
|
+
pointer,
|
|
62
|
+
errors
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
17
66
|
const matches = [];
|
|
18
67
|
const errors = [];
|
|
19
68
|
for (let i = 0; i < schema.oneOf.length; i += 1) {
|
|
@@ -33,8 +82,17 @@ export default function resolveOneOf(core: Core, data: any, schema: JSONSchema =
|
|
|
33
82
|
return matches[0];
|
|
34
83
|
}
|
|
35
84
|
if (matches.length > 1) {
|
|
36
|
-
return core.errors.multipleOneOfError({
|
|
85
|
+
return core.errors.multipleOneOfError({
|
|
86
|
+
value: data,
|
|
87
|
+
pointer,
|
|
88
|
+
matches
|
|
89
|
+
});
|
|
37
90
|
}
|
|
38
91
|
|
|
39
|
-
return core.errors.oneOfError({
|
|
92
|
+
return core.errors.oneOfError({
|
|
93
|
+
value: JSON.stringify(data),
|
|
94
|
+
pointer,
|
|
95
|
+
oneOf: schema.oneOf,
|
|
96
|
+
errors
|
|
97
|
+
});
|
|
40
98
|
}
|
|
File without changes
|
package/lib/resolveRef.strict.ts
CHANGED
|
@@ -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
|
}
|