json-schema-library 10.5.4 → 11.0.1
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/README.md +128 -14
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +42 -19
- package/dist/index.d.mts +42 -19
- package/dist/index.mjs +1 -1
- package/dist/jlib.js +2 -2
- package/index.ts +8 -4
- package/package.json +6 -6
- package/src/Keyword.ts +8 -3
- package/src/SchemaNode.ts +46 -10
- package/src/compileSchema.validate.test.ts +89 -54
- package/src/draft04.ts +10 -8
- package/src/draft06.ts +10 -8
- package/src/draft07.ts +10 -8
- package/src/draft2019-09/keywords/additionalItems.ts +2 -2
- package/src/draft2019-09/keywords/items.ts +2 -2
- package/src/draft2019-09/keywords/unevaluatedItems.ts +12 -6
- package/src/draft2019.ts +10 -8
- package/src/draft2020.ts +8 -6
- package/src/errors/errors.ts +3 -1
- package/src/formats/formats.ts +2 -6
- package/src/keywords/additionalProperties.ts +2 -2
- package/src/keywords/allOf.ts +2 -2
- package/src/keywords/dependencies.ts +5 -6
- package/src/keywords/dependentRequired.ts +2 -2
- package/src/keywords/dependentSchemas.ts +4 -3
- package/src/keywords/deprecated.ts +18 -0
- package/src/keywords/items.ts +2 -2
- package/src/keywords/oneOf.test.ts +150 -15
- package/src/keywords/oneOf.ts +64 -4
- package/src/keywords/patternProperties.ts +2 -2
- package/src/keywords/prefixItems.ts +2 -11
- package/src/keywords/properties.ts +2 -2
- package/src/keywords/unevaluatedItems.ts +2 -2
- package/src/keywords/unevaluatedProperties.ts +2 -2
- package/src/methods/getData.test.ts +1779 -1781
- package/src/types.ts +32 -18
- package/src/utils/sanitizeErrors.ts +9 -8
- package/src/validateNode.ts +2 -2
package/index.ts
CHANGED
|
@@ -3,16 +3,19 @@ export type { CompileOptions } from "./src/compileSchema";
|
|
|
3
3
|
export type { Context, SchemaNode, GetNodeOptions, ValidateReturnType } from "./src/SchemaNode";
|
|
4
4
|
export type { DataNode } from "./src/methods/toDataNodes";
|
|
5
5
|
export type { Draft, DraftVersion } from "./src/Draft";
|
|
6
|
-
export type { JsonError, JsonPointer, JsonSchema, OptionalNodeOrError, NodeOrError } from "./src/types";
|
|
6
|
+
export type { JsonError, JsonAnnotation, JsonPointer, JsonSchema, OptionalNodeOrError, NodeOrError } from "./src/types";
|
|
7
7
|
export type {
|
|
8
8
|
Keyword,
|
|
9
|
+
Maybe,
|
|
9
10
|
ValidationPath,
|
|
10
11
|
JsonSchemaReducerParams,
|
|
11
12
|
JsonSchemaReducer,
|
|
12
13
|
JsonSchemaResolverParams,
|
|
13
14
|
JsonSchemaResolver,
|
|
14
15
|
JsonSchemaValidatorParams,
|
|
15
|
-
JsonSchemaValidator
|
|
16
|
+
JsonSchemaValidator,
|
|
17
|
+
ValidationAnnotation,
|
|
18
|
+
ValidationReturnType
|
|
16
19
|
} from "./src/Keyword";
|
|
17
20
|
export { default as settings } from "./src/settings";
|
|
18
21
|
|
|
@@ -29,16 +32,17 @@ export { oneOfFuzzyKeyword, oneOfKeyword } from "./src/keywords/oneOf";
|
|
|
29
32
|
|
|
30
33
|
// errors
|
|
31
34
|
export { render } from "./src/errors/render";
|
|
32
|
-
export type {
|
|
35
|
+
export type { Annotation, AnnotationData, ErrorConfig } from "./src/types";
|
|
33
36
|
|
|
34
37
|
// utilities
|
|
35
38
|
export { getTypeOf } from "./src/utils/getTypeOf";
|
|
36
39
|
export { isReduceable } from "./src/SchemaNode";
|
|
37
|
-
export { isJsonError, isSchemaNode } from "./src/types";
|
|
40
|
+
export { isJsonError, isJsonAnnotation, isAnnotation, isSchemaNode } from "./src/types";
|
|
38
41
|
export { extendDraft, addKeywords } from "./src/Draft";
|
|
39
42
|
export { mergeNode } from "./src/mergeNode";
|
|
40
43
|
export { mergeSchema } from "./src/utils/mergeSchema";
|
|
41
44
|
export { getSchemaType } from "./src/utils/getSchemaType";
|
|
45
|
+
export { default as sanitizeErrors } from "./src/utils/sanitizeErrors";
|
|
42
46
|
|
|
43
47
|
// remotes
|
|
44
48
|
export { remotes } from "./remotes";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-schema-library",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.1",
|
|
4
4
|
"description": "Customizable and hackable json-validator and json-schema utilities for traversal, data generation and validation",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -67,17 +67,17 @@
|
|
|
67
67
|
"@eslint/js": "^10.0.1",
|
|
68
68
|
"@types/glob": "^9.0.0",
|
|
69
69
|
"@types/mocha": "^10.0.6",
|
|
70
|
-
"@types/node": "^25.2.
|
|
70
|
+
"@types/node": "^25.2.3",
|
|
71
71
|
"@types/valid-url": "^1.0.7",
|
|
72
72
|
"eslint": "^9.39.2",
|
|
73
|
-
"glob": "^13.0.
|
|
74
|
-
"json-schema-test-suite": "https://github.com/json-schema-org/JSON-Schema-Test-Suite#
|
|
73
|
+
"glob": "^13.0.3",
|
|
74
|
+
"json-schema-test-suite": "https://github.com/json-schema-org/JSON-Schema-Test-Suite#Test-JSON-Schema-Acceptance-1.029",
|
|
75
75
|
"mocha": "^11.7.5",
|
|
76
76
|
"nyc": "^17.1.0",
|
|
77
77
|
"tsdown": "^0.20.3",
|
|
78
78
|
"tsx": "^4.21.0",
|
|
79
79
|
"typescript": "^5.9.3",
|
|
80
|
-
"typescript-eslint": "^8.
|
|
80
|
+
"typescript-eslint": "^8.55.0",
|
|
81
81
|
"watch": "^1.0.1"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"lodash": ">=4",
|
|
100
100
|
"merge": ">=2",
|
|
101
101
|
"micromatch": ">=4.0.8",
|
|
102
|
-
"string-width": "
|
|
102
|
+
"string-width": ">=4.2.3"
|
|
103
103
|
},
|
|
104
104
|
"publishConfig": {
|
|
105
105
|
"registry": "https://registry.npmjs.org"
|
package/src/Keyword.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SchemaNode, JsonError } from "./types";
|
|
1
|
+
import type { SchemaNode, JsonError, JsonAnnotation } from "./types";
|
|
2
2
|
|
|
3
3
|
export type ValidationPath = {
|
|
4
4
|
pointer: string;
|
|
@@ -30,13 +30,18 @@ export interface JsonSchemaResolver {
|
|
|
30
30
|
(options: JsonSchemaResolverParams): SchemaNode | JsonError | undefined;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// type MaybeAsync<T> = T | Promise<T>;
|
|
34
|
+
// type MaybeArray<T> = T | T[];
|
|
35
|
+
export type Maybe<T> = T | undefined;
|
|
36
|
+
export type ValidationAnnotation = JsonError | JsonAnnotation | Promise<Maybe<ValidationAnnotation>[]>;
|
|
37
|
+
type ValidationResult = Maybe<ValidationAnnotation>;
|
|
38
|
+
export type ValidationReturnType = ValidationResult | ValidationResult[];
|
|
34
39
|
|
|
35
40
|
export type JsonSchemaValidatorParams = { pointer: string; data: unknown; node: SchemaNode; path: ValidationPath };
|
|
36
41
|
export interface JsonSchemaValidator {
|
|
37
42
|
toJSON?: () => string;
|
|
38
43
|
order?: number;
|
|
39
|
-
(options: JsonSchemaValidatorParams):
|
|
44
|
+
(options: JsonSchemaValidatorParams): ValidationReturnType;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
export type Keyword = {
|
package/src/SchemaNode.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { copy } from "fast-copy";
|
|
2
2
|
import sanitizeErrors from "./utils/sanitizeErrors";
|
|
3
3
|
import settings from "./settings";
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
JsonSchemaReducer,
|
|
6
|
+
JsonSchemaResolver,
|
|
7
|
+
JsonSchemaValidator,
|
|
8
|
+
Keyword,
|
|
9
|
+
Maybe,
|
|
10
|
+
ValidationAnnotation,
|
|
11
|
+
ValidationPath
|
|
12
|
+
} from "./Keyword";
|
|
5
13
|
import { createSchema } from "./methods/createSchema";
|
|
6
14
|
import { Draft } from "./Draft";
|
|
7
15
|
import { toSchemaNodes } from "./methods/toSchemaNodes";
|
|
@@ -9,10 +17,12 @@ import {
|
|
|
9
17
|
isJsonError,
|
|
10
18
|
JsonSchema,
|
|
11
19
|
JsonError,
|
|
12
|
-
|
|
20
|
+
AnnotationData,
|
|
13
21
|
DefaultErrors,
|
|
14
22
|
OptionalNodeOrError,
|
|
15
|
-
NodeOrError
|
|
23
|
+
NodeOrError,
|
|
24
|
+
JsonAnnotation,
|
|
25
|
+
isJsonAnnotation
|
|
16
26
|
} from "./types";
|
|
17
27
|
import { isObject } from "./utils/isObject";
|
|
18
28
|
import { join } from "@sagold/json-pointer";
|
|
@@ -180,7 +190,8 @@ export interface SchemaNode extends SchemaNodeMethodsType {
|
|
|
180
190
|
*/
|
|
181
191
|
interface SchemaNodeMethodsType {
|
|
182
192
|
compileSchema(schema: JsonSchema, evaluationPath?: string, schemaLocation?: string, dynamicId?: string): SchemaNode;
|
|
183
|
-
createError<T extends string = DefaultErrors>(code: T, data:
|
|
193
|
+
createError<T extends string = DefaultErrors>(code: T, data: AnnotationData, message?: string): JsonError;
|
|
194
|
+
createAnnotation<T extends string = DefaultErrors>(code: T, data: AnnotationData, message?: string): JsonAnnotation;
|
|
184
195
|
createSchema(data?: unknown): JsonSchema;
|
|
185
196
|
|
|
186
197
|
// getNode overloads
|
|
@@ -201,7 +212,7 @@ interface SchemaNodeMethodsType {
|
|
|
201
212
|
getNodeRef($ref: string): SchemaNode | undefined;
|
|
202
213
|
getNodeRoot(): SchemaNode;
|
|
203
214
|
getDraftVersion(): string;
|
|
204
|
-
getData(data?: unknown, options?: TemplateOptions):
|
|
215
|
+
getData(data?: unknown, options?: TemplateOptions): any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
205
216
|
reduceNode(
|
|
206
217
|
data: unknown,
|
|
207
218
|
options?: { key?: string | number; pointer?: string; path?: ValidationPath }
|
|
@@ -241,10 +252,14 @@ export type ValidateReturnType = {
|
|
|
241
252
|
* List of validation errors or empty
|
|
242
253
|
*/
|
|
243
254
|
errors: JsonError[];
|
|
255
|
+
/**
|
|
256
|
+
* List of annotations from validators
|
|
257
|
+
*/
|
|
258
|
+
annotations: JsonAnnotation[];
|
|
244
259
|
/**
|
|
245
260
|
* List of Promises resolving to `JsonError|undefined` or empty.
|
|
246
261
|
*/
|
|
247
|
-
errorsAsync: Promise<
|
|
262
|
+
errorsAsync: Promise<Maybe<ValidationAnnotation>[]>[];
|
|
248
263
|
};
|
|
249
264
|
|
|
250
265
|
export function joinDynamicId(a?: string, b?: string) {
|
|
@@ -290,7 +305,7 @@ export const SchemaNodeMethods = {
|
|
|
290
305
|
return node;
|
|
291
306
|
},
|
|
292
307
|
|
|
293
|
-
createError<T extends string = DefaultErrors>(code: T, data:
|
|
308
|
+
createError<T extends string = DefaultErrors>(code: T, data: AnnotationData, message?: string): JsonError {
|
|
294
309
|
const node = this as SchemaNode;
|
|
295
310
|
let errorMessage = message;
|
|
296
311
|
if (errorMessage === undefined) {
|
|
@@ -303,6 +318,23 @@ export const SchemaNodeMethods = {
|
|
|
303
318
|
return { type: "error", code, message: errorMessage, data };
|
|
304
319
|
},
|
|
305
320
|
|
|
321
|
+
createAnnotation<T extends string = DefaultErrors>(
|
|
322
|
+
code: T,
|
|
323
|
+
data: AnnotationData,
|
|
324
|
+
message?: string
|
|
325
|
+
): JsonAnnotation {
|
|
326
|
+
const node = this as SchemaNode;
|
|
327
|
+
let annotationMessage = message;
|
|
328
|
+
if (annotationMessage === undefined) {
|
|
329
|
+
const error = node.schema?.errorMessages?.[code] ?? node.context.errors[code];
|
|
330
|
+
if (typeof error === "function") {
|
|
331
|
+
return error(data);
|
|
332
|
+
}
|
|
333
|
+
annotationMessage = render(error ?? name, data);
|
|
334
|
+
}
|
|
335
|
+
return { type: "annotation", code, message: annotationMessage, data };
|
|
336
|
+
},
|
|
337
|
+
|
|
306
338
|
createSchema,
|
|
307
339
|
|
|
308
340
|
getChildSelection(property: string | number): JsonError | SchemaNode[] {
|
|
@@ -412,20 +444,24 @@ export const SchemaNodeMethods = {
|
|
|
412
444
|
const node = this as SchemaNode;
|
|
413
445
|
const errors = validateNode(node, data, pointer, path) ?? [];
|
|
414
446
|
const syncErrors: JsonError[] = [];
|
|
447
|
+
const annotations: JsonAnnotation[] = [];
|
|
415
448
|
const flatErrorList = sanitizeErrors(Array.isArray(errors) ? errors : [errors]).filter(isJsonError);
|
|
416
449
|
|
|
417
|
-
const errorsAsync: Promise<
|
|
450
|
+
const errorsAsync: Promise<Maybe<ValidationAnnotation>[]>[] = [];
|
|
418
451
|
sanitizeErrors(Array.isArray(errors) ? errors : [errors]).forEach((error) => {
|
|
419
452
|
if (isJsonError(error)) {
|
|
420
453
|
syncErrors.push(error);
|
|
421
454
|
} else if (error instanceof Promise) {
|
|
422
|
-
errorsAsync.push(error);
|
|
455
|
+
errorsAsync.push(error.then(sanitizeErrors));
|
|
456
|
+
} else if (isJsonAnnotation(error)) {
|
|
457
|
+
annotations.push(error);
|
|
423
458
|
}
|
|
424
459
|
});
|
|
425
460
|
|
|
426
461
|
const result: ValidateReturnType = {
|
|
427
462
|
valid: flatErrorList.length === 0,
|
|
428
463
|
errors: syncErrors,
|
|
464
|
+
annotations,
|
|
429
465
|
errorsAsync
|
|
430
466
|
};
|
|
431
467
|
|
|
@@ -478,7 +514,7 @@ export const SchemaNodeMethods = {
|
|
|
478
514
|
* @returns a list of all sub-schema as SchemaNode
|
|
479
515
|
*/
|
|
480
516
|
toSchemaNodes() {
|
|
481
|
-
return toSchemaNodes(this
|
|
517
|
+
return toSchemaNodes(this);
|
|
482
518
|
},
|
|
483
519
|
|
|
484
520
|
/**
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { compileSchema } from "./compileSchema";
|
|
2
2
|
import { strict as assert } from "assert";
|
|
3
|
-
import { Draft,
|
|
3
|
+
import { Draft, isJsonError, SchemaNode } from "./types";
|
|
4
4
|
import { draft2020 } from "./draft2020";
|
|
5
|
+
import sanitizeErrors from "./utils/sanitizeErrors";
|
|
5
6
|
|
|
6
|
-
describe("compileSchema
|
|
7
|
+
describe("compileSchema : validate", () => {
|
|
8
|
+
// note: boolean schema is already thoroughly tested by spec
|
|
7
9
|
describe("boolean schema", () => {
|
|
8
|
-
// note: all this is tested in spec already
|
|
9
10
|
it("should fail if root schema is false", () => {
|
|
10
11
|
// @ts-expect-error boolean typ unsupported
|
|
11
12
|
const { errors } = compileSchema(false).validate("anything");
|
|
@@ -995,73 +996,107 @@ describe("compileSchema.validate - errorsAsync", () => {
|
|
|
995
996
|
...draft2020.keywords,
|
|
996
997
|
{
|
|
997
998
|
id: "async",
|
|
998
|
-
keyword: "
|
|
999
|
+
keyword: "asyncError",
|
|
999
1000
|
addValidate: (node) => node.schema.asyncError != null,
|
|
1000
|
-
validate: async ({ node })
|
|
1001
|
+
validate: async ({ node }) => {
|
|
1001
1002
|
if (node.schema.asyncError === false) {
|
|
1002
|
-
return undefined;
|
|
1003
|
+
return [undefined];
|
|
1003
1004
|
}
|
|
1004
|
-
return
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1005
|
+
return [
|
|
1006
|
+
node.createError("type-error", {
|
|
1007
|
+
schema: {},
|
|
1008
|
+
pointer: "",
|
|
1009
|
+
value: ""
|
|
1010
|
+
})
|
|
1011
|
+
];
|
|
1009
1012
|
}
|
|
1010
1013
|
}
|
|
1011
1014
|
]
|
|
1012
1015
|
};
|
|
1016
|
+
});
|
|
1013
1017
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
const asyncErrors = await Promise.all(errorsAsync);
|
|
1020
|
-
assert.deepEqual(errors.length, 0);
|
|
1021
|
-
assert.deepEqual(asyncErrors.length, 0);
|
|
1022
|
-
});
|
|
1018
|
+
it("should resolve async validation returning no error", async () => {
|
|
1019
|
+
const { errors, errorsAsync } = compileSchema(
|
|
1020
|
+
{ type: "number", asyncError: false },
|
|
1021
|
+
{ drafts: [draft] }
|
|
1022
|
+
).validate(4);
|
|
1023
1023
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1024
|
+
const asyncErrors = sanitizeErrors(await Promise.all(errorsAsync));
|
|
1025
|
+
assert.deepEqual(errors.length, 0);
|
|
1026
|
+
assert.deepEqual(asyncErrors.length, 0);
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
it("should resolve async validation errors", async () => {
|
|
1030
|
+
const { errorsAsync } = compileSchema({ type: "number", asyncError: true }, { drafts: [draft] }).validate(
|
|
1031
|
+
4
|
|
1032
|
+
);
|
|
1033
|
+
|
|
1034
|
+
const asyncErrors = sanitizeErrors(await Promise.all(errorsAsync));
|
|
1035
|
+
assert.deepEqual(asyncErrors.length, 1, "should have resolved promise to return error");
|
|
1036
|
+
assert(isJsonError(asyncErrors[0]));
|
|
1037
|
+
assert.deepEqual(asyncErrors[0].code, "type-error");
|
|
1033
1038
|
});
|
|
1034
1039
|
});
|
|
1035
1040
|
});
|
|
1036
1041
|
|
|
1037
|
-
describe("
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1042
|
+
describe("annotation", () => {
|
|
1043
|
+
let draft: Draft;
|
|
1044
|
+
beforeEach(() => {
|
|
1045
|
+
draft = {
|
|
1046
|
+
...draft2020,
|
|
1047
|
+
keywords: [
|
|
1048
|
+
...draft2020.keywords,
|
|
1049
|
+
{
|
|
1050
|
+
id: "annotation",
|
|
1051
|
+
keyword: "annotation",
|
|
1052
|
+
addValidate: (node) => node.schema.annotation === true,
|
|
1053
|
+
validate: ({ node }) =>
|
|
1054
|
+
node.createAnnotation("deprecated-warning", {
|
|
1055
|
+
schema: {},
|
|
1056
|
+
pointer: "",
|
|
1057
|
+
value: ""
|
|
1058
|
+
})
|
|
1059
|
+
}
|
|
1060
|
+
]
|
|
1061
|
+
};
|
|
1062
|
+
});
|
|
1063
|
+
|
|
1064
|
+
it("should return annotations-property from validate", async () => {
|
|
1065
|
+
const { annotations } = compileSchema(
|
|
1066
|
+
{
|
|
1067
|
+
type: "number",
|
|
1068
|
+
annotation: true
|
|
1069
|
+
},
|
|
1070
|
+
{
|
|
1071
|
+
drafts: [draft]
|
|
1044
1072
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
assert.
|
|
1073
|
+
).validate(4);
|
|
1074
|
+
|
|
1075
|
+
assert(Array.isArray(annotations));
|
|
1048
1076
|
});
|
|
1049
1077
|
|
|
1050
|
-
it("should
|
|
1051
|
-
const {
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
"one-of-error": "{{value}} does not match any of the options"
|
|
1056
|
-
},
|
|
1057
|
-
oneOf: [
|
|
1058
|
-
{ type: "number" },
|
|
1059
|
-
{ type: "object", properties: { a: { type: "string" } }, additionalProperties: false }
|
|
1060
|
-
]
|
|
1078
|
+
it("should add annotations to annotations-property", async () => {
|
|
1079
|
+
const { annotations } = compileSchema(
|
|
1080
|
+
{
|
|
1081
|
+
type: "number",
|
|
1082
|
+
annotation: true
|
|
1061
1083
|
},
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1084
|
+
{
|
|
1085
|
+
drafts: [draft]
|
|
1086
|
+
}
|
|
1087
|
+
).validate(4);
|
|
1088
|
+
|
|
1089
|
+
assert.equal(annotations.length, 1);
|
|
1090
|
+
assert.equal(annotations[0].code, "deprecated-warning");
|
|
1091
|
+
});
|
|
1092
|
+
|
|
1093
|
+
it("should return deprecated-warning annotation per default", async () => {
|
|
1094
|
+
const { annotations } = compileSchema({
|
|
1095
|
+
type: "number",
|
|
1096
|
+
deprecated: true
|
|
1097
|
+
}).validate(4);
|
|
1098
|
+
|
|
1099
|
+
assert.equal(annotations.length, 1);
|
|
1100
|
+
assert.equal(annotations[0].code, "deprecated-warning");
|
|
1066
1101
|
});
|
|
1067
1102
|
});
|
package/src/draft04.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
import { $defsKeyword } from "./keywords/$defs";
|
|
2
|
+
import { $refKeyword } from "./draft04/keywords/$ref";
|
|
1
3
|
import { additionalItemsKeyword } from "./draft2019-09/keywords/additionalItems";
|
|
2
4
|
import { additionalPropertiesKeyword } from "./keywords/additionalProperties";
|
|
3
5
|
import { allOfKeyword } from "./keywords/allOf";
|
|
4
6
|
import { anyOfKeyword } from "./keywords/anyOf";
|
|
5
7
|
import { containsKeyword } from "./keywords/contains";
|
|
6
|
-
import {
|
|
8
|
+
import { createSchema } from "./methods/createSchema";
|
|
7
9
|
import { dependenciesKeyword } from "./keywords/dependencies";
|
|
10
|
+
import { deprecatedKeyword } from "./keywords/deprecated";
|
|
8
11
|
import { enumKeyword } from "./keywords/enum";
|
|
12
|
+
import { errors } from "./errors/errors";
|
|
9
13
|
import { exclusiveMaximumKeyword } from "./draft04/keywords/exclusiveMaximum";
|
|
10
14
|
import { exclusiveMinimumKeyword } from "./draft04/keywords/exclusiveMinimum";
|
|
11
15
|
import { formatKeyword } from "./keywords/format";
|
|
16
|
+
import { formats } from "./formats/formats";
|
|
17
|
+
import { getChildSelection } from "./draft2019-09/methods/getChildSelection";
|
|
18
|
+
import { getData } from "./draft2019-09/methods/getData";
|
|
12
19
|
import { itemsKeyword } from "./draft2019-09/keywords/items";
|
|
13
20
|
import { maximumKeyword } from "./keywords/maximum";
|
|
14
21
|
import { maxItemsKeyword } from "./keywords/maxItems";
|
|
@@ -25,17 +32,11 @@ import { patternKeyword } from "./keywords/pattern";
|
|
|
25
32
|
import { patternPropertiesKeyword } from "./keywords/patternProperties";
|
|
26
33
|
import { propertiesKeyword } from "./keywords/properties";
|
|
27
34
|
import { propertyNamesKeyword } from "./keywords/propertyNames";
|
|
28
|
-
import { $refKeyword } from "./draft04/keywords/$ref";
|
|
29
35
|
import { requiredKeyword } from "./keywords/required";
|
|
30
36
|
import { sanitizeKeywords } from "./Draft";
|
|
37
|
+
import { toDataNodes } from "./methods/toDataNodes";
|
|
31
38
|
import { typeKeyword } from "./keywords/type";
|
|
32
39
|
import { uniqueItemsKeyword } from "./keywords/uniqueItems";
|
|
33
|
-
import { getChildSelection } from "./draft2019-09/methods/getChildSelection";
|
|
34
|
-
import { getData } from "./draft2019-09/methods/getData";
|
|
35
|
-
import { toDataNodes } from "./methods/toDataNodes";
|
|
36
|
-
import { createSchema } from "./methods/createSchema";
|
|
37
|
-
import { errors } from "./errors/errors";
|
|
38
|
-
import { formats } from "./formats/formats";
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* @draft-04
|
|
@@ -77,6 +78,7 @@ export const draft04 = sanitizeKeywords({
|
|
|
77
78
|
containsKeyword,
|
|
78
79
|
$defsKeyword,
|
|
79
80
|
dependenciesKeyword, // optional support for old draft-version
|
|
81
|
+
deprecatedKeyword,
|
|
80
82
|
enumKeyword,
|
|
81
83
|
exclusiveMaximumKeyword,
|
|
82
84
|
exclusiveMinimumKeyword,
|
package/src/draft06.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
import { $defsKeyword } from "./keywords/$defs";
|
|
2
|
+
import { $refKeyword } from "./draft06/keywords/$ref";
|
|
1
3
|
import { additionalItemsKeyword } from "./draft2019-09/keywords/additionalItems";
|
|
2
4
|
import { additionalPropertiesKeyword } from "./keywords/additionalProperties";
|
|
3
5
|
import { allOfKeyword } from "./keywords/allOf";
|
|
4
6
|
import { anyOfKeyword } from "./keywords/anyOf";
|
|
5
7
|
import { constKeyword } from "./keywords/const";
|
|
6
8
|
import { containsKeyword } from "./keywords/contains";
|
|
7
|
-
import {
|
|
9
|
+
import { createSchema } from "./methods/createSchema";
|
|
8
10
|
import { dependenciesKeyword } from "./keywords/dependencies";
|
|
11
|
+
import { deprecatedKeyword } from "./keywords/deprecated";
|
|
9
12
|
import { enumKeyword } from "./keywords/enum";
|
|
13
|
+
import { errors } from "./errors/errors";
|
|
10
14
|
import { exclusiveMaximumKeyword } from "./keywords/exclusiveMaximum";
|
|
11
15
|
import { exclusiveMinimumKeyword } from "./keywords/exclusiveMinimum";
|
|
12
16
|
import { formatKeyword } from "./keywords/format";
|
|
17
|
+
import { formats } from "./formats/formats";
|
|
18
|
+
import { getChildSelection } from "./draft2019-09/methods/getChildSelection";
|
|
19
|
+
import { getData } from "./draft2019-09/methods/getData";
|
|
13
20
|
import { itemsKeyword } from "./draft2019-09/keywords/items";
|
|
14
21
|
import { maximumKeyword } from "./keywords/maximum";
|
|
15
22
|
import { maxItemsKeyword } from "./keywords/maxItems";
|
|
@@ -26,17 +33,11 @@ import { patternKeyword } from "./keywords/pattern";
|
|
|
26
33
|
import { patternPropertiesKeyword } from "./keywords/patternProperties";
|
|
27
34
|
import { propertiesKeyword } from "./keywords/properties";
|
|
28
35
|
import { propertyNamesKeyword } from "./keywords/propertyNames";
|
|
29
|
-
import { $refKeyword } from "./draft06/keywords/$ref";
|
|
30
36
|
import { requiredKeyword } from "./keywords/required";
|
|
31
37
|
import { sanitizeKeywords } from "./Draft";
|
|
38
|
+
import { toDataNodes } from "./methods/toDataNodes";
|
|
32
39
|
import { typeKeyword } from "./keywords/type";
|
|
33
40
|
import { uniqueItemsKeyword } from "./keywords/uniqueItems";
|
|
34
|
-
import { getChildSelection } from "./draft2019-09/methods/getChildSelection";
|
|
35
|
-
import { getData } from "./draft2019-09/methods/getData";
|
|
36
|
-
import { toDataNodes } from "./methods/toDataNodes";
|
|
37
|
-
import { createSchema } from "./methods/createSchema";
|
|
38
|
-
import { errors } from "./errors/errors";
|
|
39
|
-
import { formats } from "./formats/formats";
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
43
|
* @draft-06 https://json-schema.org/draft-06/json-schema-release-notes
|
|
@@ -79,6 +80,7 @@ export const draft06 = sanitizeKeywords({
|
|
|
79
80
|
containsKeyword,
|
|
80
81
|
$defsKeyword,
|
|
81
82
|
dependenciesKeyword, // optional support for old draft-version
|
|
83
|
+
deprecatedKeyword,
|
|
82
84
|
enumKeyword,
|
|
83
85
|
exclusiveMaximumKeyword,
|
|
84
86
|
exclusiveMinimumKeyword,
|
package/src/draft07.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
import { $defsKeyword } from "./keywords/$defs";
|
|
2
|
+
import { $refKeyword } from "./draft06/keywords/$ref";
|
|
1
3
|
import { additionalItemsKeyword } from "./draft2019-09/keywords/additionalItems";
|
|
2
4
|
import { additionalPropertiesKeyword } from "./keywords/additionalProperties";
|
|
3
5
|
import { allOfKeyword } from "./keywords/allOf";
|
|
4
6
|
import { anyOfKeyword } from "./keywords/anyOf";
|
|
5
7
|
import { constKeyword } from "./keywords/const";
|
|
6
8
|
import { containsKeyword } from "./keywords/contains";
|
|
7
|
-
import {
|
|
9
|
+
import { createSchema } from "./methods/createSchema";
|
|
8
10
|
import { dependenciesKeyword } from "./keywords/dependencies";
|
|
11
|
+
import { deprecatedKeyword } from "./keywords/deprecated";
|
|
9
12
|
import { enumKeyword } from "./keywords/enum";
|
|
13
|
+
import { errors } from "./errors/errors";
|
|
10
14
|
import { exclusiveMaximumKeyword } from "./keywords/exclusiveMaximum";
|
|
11
15
|
import { exclusiveMinimumKeyword } from "./keywords/exclusiveMinimum";
|
|
12
16
|
import { formatKeyword } from "./keywords/format";
|
|
17
|
+
import { formats } from "./formats/formats";
|
|
18
|
+
import { getChildSelection } from "./draft2019-09/methods/getChildSelection";
|
|
19
|
+
import { getData } from "./draft2019-09/methods/getData";
|
|
13
20
|
import { ifKeyword } from "./keywords/ifthenelse";
|
|
14
21
|
import { itemsKeyword } from "./draft2019-09/keywords/items";
|
|
15
22
|
import { maximumKeyword } from "./keywords/maximum";
|
|
@@ -27,17 +34,11 @@ import { patternKeyword } from "./keywords/pattern";
|
|
|
27
34
|
import { patternPropertiesKeyword } from "./keywords/patternProperties";
|
|
28
35
|
import { propertiesKeyword } from "./keywords/properties";
|
|
29
36
|
import { propertyNamesKeyword } from "./keywords/propertyNames";
|
|
30
|
-
import { $refKeyword } from "./draft06/keywords/$ref";
|
|
31
37
|
import { requiredKeyword } from "./keywords/required";
|
|
32
38
|
import { sanitizeKeywords } from "./Draft";
|
|
39
|
+
import { toDataNodes } from "./methods/toDataNodes";
|
|
33
40
|
import { typeKeyword } from "./keywords/type";
|
|
34
41
|
import { uniqueItemsKeyword } from "./keywords/uniqueItems";
|
|
35
|
-
import { getChildSelection } from "./draft2019-09/methods/getChildSelection";
|
|
36
|
-
import { getData } from "./draft2019-09/methods/getData";
|
|
37
|
-
import { toDataNodes } from "./methods/toDataNodes";
|
|
38
|
-
import { createSchema } from "./methods/createSchema";
|
|
39
|
-
import { errors } from "./errors/errors";
|
|
40
|
-
import { formats } from "./formats/formats";
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
44
|
* @draft-07 https://json-schema.org/draft-07/json-schema-release-notes
|
|
@@ -70,6 +71,7 @@ export const draft07 = sanitizeKeywords({
|
|
|
70
71
|
containsKeyword,
|
|
71
72
|
$defsKeyword,
|
|
72
73
|
dependenciesKeyword, // optional support for old draft-version
|
|
74
|
+
deprecatedKeyword,
|
|
73
75
|
enumKeyword,
|
|
74
76
|
exclusiveMaximumKeyword,
|
|
75
77
|
exclusiveMinimumKeyword,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isObject } from "../../utils/isObject";
|
|
2
|
-
import { Keyword, JsonSchemaResolverParams, JsonSchemaValidatorParams,
|
|
2
|
+
import { Keyword, JsonSchemaResolverParams, JsonSchemaValidatorParams, ValidationReturnType } from "../../Keyword";
|
|
3
3
|
import { SchemaNode } from "../../types";
|
|
4
4
|
import { getValue } from "../../utils/getValue";
|
|
5
5
|
import { validateNode } from "../../validateNode";
|
|
@@ -49,7 +49,7 @@ function validateAdditionalItems({ node, data, pointer, path }: JsonSchemaValida
|
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
const startIndex = Array.isArray(schema.items) ? schema.items.length : 0;
|
|
52
|
-
const errors:
|
|
52
|
+
const errors: ValidationReturnType = [];
|
|
53
53
|
for (let i = startIndex; i < data.length; i += 1) {
|
|
54
54
|
const item = data[i];
|
|
55
55
|
if (node.items) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Keyword, JsonSchemaResolverParams, JsonSchemaValidatorParams,
|
|
1
|
+
import { Keyword, JsonSchemaResolverParams, JsonSchemaValidatorParams, ValidationReturnType } from "../../Keyword";
|
|
2
2
|
import { SchemaNode } from "../../types";
|
|
3
3
|
import { isObject } from "../../utils/isObject";
|
|
4
4
|
import { validateNode } from "../../validateNode";
|
|
@@ -52,7 +52,7 @@ function validateItems({ node, data, pointer = "#", path }: JsonSchemaValidatorP
|
|
|
52
52
|
return node.createError("invalid-data-error", { pointer, value: data, schema });
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const errors:
|
|
55
|
+
const errors: ValidationReturnType = [];
|
|
56
56
|
if (node.prefixItems) {
|
|
57
57
|
// note: schema is valid when data does not have enough elements as defined by array-list
|
|
58
58
|
for (let i = 0; i < Math.min(node.prefixItems.length, data.length); i += 1) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { isObject } from "../../utils/isObject";
|
|
2
2
|
import { SchemaNode } from "../../types";
|
|
3
|
-
import { Keyword, JsonSchemaValidatorParams,
|
|
4
|
-
import sanitizeErrors from "../../utils/sanitizeErrors";
|
|
3
|
+
import { Keyword, JsonSchemaValidatorParams, ValidationReturnType } from "../../Keyword";
|
|
5
4
|
import { validateNode } from "../../validateNode";
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -50,7 +49,7 @@ function validateUnevaluatedItems({ node, data, pointer, path }: JsonSchemaValid
|
|
|
50
49
|
// console.log("EVAL", reducedNode.schema);
|
|
51
50
|
|
|
52
51
|
const validIf = node.if != null && validateNode(node.if, data, pointer, path).length === 0;
|
|
53
|
-
const errors:
|
|
52
|
+
const errors: ValidationReturnType = [];
|
|
54
53
|
// "unevaluatedItems with nested items"
|
|
55
54
|
for (let i = 0; i < data.length; i += 1) {
|
|
56
55
|
const value = data[i];
|
|
@@ -63,9 +62,16 @@ function validateUnevaluatedItems({ node, data, pointer, path }: JsonSchemaValid
|
|
|
63
62
|
// nothing should validate, so we validate unevaluated items only
|
|
64
63
|
const unevaluatedItems = node.unevaluatedItems;
|
|
65
64
|
if (unevaluatedItems) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
data.forEach((value) => {
|
|
66
|
+
const result = validateNode(unevaluatedItems, value, `${pointer}/${i}`, path);
|
|
67
|
+
if (result == null) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (Array.isArray(result)) {
|
|
71
|
+
return errors.push(...result);
|
|
72
|
+
}
|
|
73
|
+
errors.push(result);
|
|
74
|
+
});
|
|
69
75
|
}
|
|
70
76
|
if (node.schema.unevaluatedItems === false) {
|
|
71
77
|
return node.createError("unevaluated-items-error", {
|