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
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { eachSchema } from "../../eachSchema";
|
|
2
|
+
// import remotes from "../../../remotes";
|
|
3
|
+
import joinScope from "../../compile/joinScope";
|
|
4
|
+
import getRef from "../../compile/getRef";
|
|
5
|
+
const COMPILED = "__compiled";
|
|
6
|
+
const COMPILED_REF = "__ref";
|
|
7
|
+
const GET_REF = "getRef";
|
|
8
|
+
const GET_ROOT = "getRoot";
|
|
9
|
+
const suffixes = /(#|\/)+$/g;
|
|
10
|
+
/**
|
|
11
|
+
* @draft starting with _draft 06_ keyword `id` has been renamed to `$id`
|
|
12
|
+
*
|
|
13
|
+
* compiles the input root schema for $ref resolution and returns it again
|
|
14
|
+
* @attention this modifies input schema but maintains object-structure
|
|
15
|
+
*
|
|
16
|
+
* for a compiled json-schema you can call getRef on any contained schema (location of type).
|
|
17
|
+
* this resolves a $ref target to a valid schema (for a valid $ref)
|
|
18
|
+
*
|
|
19
|
+
* @param rootSchema root json-schema ($id, defs, ... ) to compile
|
|
20
|
+
* @param [force] = false force compile json-schema
|
|
21
|
+
* @return compiled json-schema
|
|
22
|
+
*/
|
|
23
|
+
export default function compileSchema(draft, schemaToCompile, rootSchema = schemaToCompile, force = false) {
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
if (schemaToCompile === true || schemaToCompile === false || schemaToCompile === undefined) {
|
|
26
|
+
return schemaToCompile;
|
|
27
|
+
}
|
|
28
|
+
if (schemaToCompile[COMPILED] !== undefined) {
|
|
29
|
+
return schemaToCompile;
|
|
30
|
+
} // eslint-disable-line
|
|
31
|
+
const context = { ids: {}, remotes: draft.remotes };
|
|
32
|
+
const rootSchemaAsString = JSON.stringify(schemaToCompile);
|
|
33
|
+
const compiledSchema = JSON.parse(rootSchemaAsString);
|
|
34
|
+
Object.defineProperty(compiledSchema, COMPILED, { enumerable: false, value: true });
|
|
35
|
+
Object.defineProperty(compiledSchema, GET_REF, {
|
|
36
|
+
enumerable: false,
|
|
37
|
+
value: getRef.bind(null, context, compiledSchema)
|
|
38
|
+
});
|
|
39
|
+
// bail early, when no $refs are defined
|
|
40
|
+
if (force === false && rootSchemaAsString.includes("$ref") === false) {
|
|
41
|
+
return compiledSchema;
|
|
42
|
+
}
|
|
43
|
+
// compile this schema under rootSchema, making definitions available to $ref-resolution
|
|
44
|
+
if (compiledSchema !== rootSchema) {
|
|
45
|
+
Object.defineProperty(compiledSchema, "$defs", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
value: Object.assign({}, rootSchema.definitions, rootSchema.$defs, compiledSchema.definitions, compiledSchema.$defs)
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const scopes = {};
|
|
51
|
+
const getRoot = () => compiledSchema;
|
|
52
|
+
eachSchema(compiledSchema, (schema, pointer) => {
|
|
53
|
+
if (schema.$id) {
|
|
54
|
+
context.ids[schema.$id.replace(suffixes, "")] = pointer;
|
|
55
|
+
}
|
|
56
|
+
// build up scopes and add them to $ref-resolution map
|
|
57
|
+
pointer = `#${pointer}`.replace(/##+/, "#");
|
|
58
|
+
const previousPointer = pointer.replace(/\/[^/]+$/, "");
|
|
59
|
+
const parentPointer = pointer.replace(/\/[^/]+\/[^/]+$/, "");
|
|
60
|
+
const previousScope = scopes[previousPointer] || scopes[parentPointer];
|
|
61
|
+
const scope = joinScope(previousScope, schema.$id);
|
|
62
|
+
scopes[pointer] = scope;
|
|
63
|
+
if (context.ids[scope] == null) {
|
|
64
|
+
context.ids[scope] = pointer;
|
|
65
|
+
}
|
|
66
|
+
if (schema.$ref && !schema[COMPILED_REF]) {
|
|
67
|
+
Object.defineProperty(schema, COMPILED_REF, {
|
|
68
|
+
enumerable: false,
|
|
69
|
+
value: joinScope(scope, schema.$ref)
|
|
70
|
+
});
|
|
71
|
+
// @todo currently not used:
|
|
72
|
+
Object.defineProperty(schema, GET_ROOT, { enumerable: false, value: getRoot });
|
|
73
|
+
// console.log("compiled ref", scope, schema.$ref, "=>", joinScope(scope, schema.$ref));
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return compiledSchema;
|
|
77
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import addRemoteSchema from "../addRemoteSchema";
|
|
2
|
+
import compileSchema from "../draft06/compile";
|
|
3
|
+
import { each } from "../each";
|
|
4
|
+
import { eachSchema } from "../eachSchema";
|
|
5
|
+
import ERRORS from "../validation/errors";
|
|
6
|
+
import FORMATS from "../validation/format";
|
|
7
|
+
import getSchema from "../getSchema";
|
|
8
|
+
import getTemplate from "../getTemplate";
|
|
9
|
+
import isValid from "../isValid";
|
|
10
|
+
import KEYWORDS from "../draft06/validation/keyword";
|
|
11
|
+
import merge from "../utils/merge";
|
|
12
|
+
import resolveAllOf from "../resolveAllOf";
|
|
13
|
+
import resolveAnyOf from "../resolveAnyOf";
|
|
14
|
+
import resolveOneOf from "../resolveOneOf.strict";
|
|
15
|
+
import resolveRef from "../resolveRef.strict";
|
|
16
|
+
import createSchemaOf from "../createSchemaOf";
|
|
17
|
+
import getChildSchemaSelection from "../getChildSchemaSelection";
|
|
18
|
+
import step from "../step";
|
|
19
|
+
import TYPES from "../draft06/validation/type";
|
|
20
|
+
import validate from "../validate";
|
|
21
|
+
import { Draft } from "../draft";
|
|
22
|
+
const draft06Config = {
|
|
23
|
+
typeKeywords: {
|
|
24
|
+
array: ["enum", "contains", "items", "minItems", "maxItems", "uniqueItems", "not", "if"],
|
|
25
|
+
boolean: ["enum", "not"],
|
|
26
|
+
object: [
|
|
27
|
+
"additionalProperties",
|
|
28
|
+
"dependencies",
|
|
29
|
+
"enum",
|
|
30
|
+
"format",
|
|
31
|
+
"minProperties",
|
|
32
|
+
"maxProperties",
|
|
33
|
+
"patternProperties",
|
|
34
|
+
"properties",
|
|
35
|
+
"propertyNames",
|
|
36
|
+
"required",
|
|
37
|
+
"not",
|
|
38
|
+
"oneOf",
|
|
39
|
+
"allOf",
|
|
40
|
+
"anyOf",
|
|
41
|
+
"if"
|
|
42
|
+
],
|
|
43
|
+
string: [
|
|
44
|
+
"enum",
|
|
45
|
+
"format",
|
|
46
|
+
"maxLength",
|
|
47
|
+
"minLength",
|
|
48
|
+
"pattern",
|
|
49
|
+
"not",
|
|
50
|
+
"oneOf",
|
|
51
|
+
"allOf",
|
|
52
|
+
"anyOf",
|
|
53
|
+
"if"
|
|
54
|
+
],
|
|
55
|
+
number: [
|
|
56
|
+
"enum",
|
|
57
|
+
"exclusiveMaximum",
|
|
58
|
+
"exclusiveMinimum",
|
|
59
|
+
"format",
|
|
60
|
+
"maximum",
|
|
61
|
+
"minimum",
|
|
62
|
+
"multipleOf",
|
|
63
|
+
"not",
|
|
64
|
+
"oneOf",
|
|
65
|
+
"allOf",
|
|
66
|
+
"anyOf",
|
|
67
|
+
"if"
|
|
68
|
+
],
|
|
69
|
+
null: ["enum", "format", "not", "oneOf", "allOf", "anyOf"]
|
|
70
|
+
},
|
|
71
|
+
validateKeyword: KEYWORDS,
|
|
72
|
+
validateType: TYPES,
|
|
73
|
+
validateFormat: FORMATS,
|
|
74
|
+
errors: ERRORS,
|
|
75
|
+
addRemoteSchema,
|
|
76
|
+
compileSchema,
|
|
77
|
+
createSchemaOf,
|
|
78
|
+
each,
|
|
79
|
+
eachSchema,
|
|
80
|
+
getChildSchemaSelection,
|
|
81
|
+
getSchema,
|
|
82
|
+
getTemplate,
|
|
83
|
+
isValid,
|
|
84
|
+
resolveAllOf,
|
|
85
|
+
resolveAnyOf,
|
|
86
|
+
resolveOneOf,
|
|
87
|
+
resolveRef,
|
|
88
|
+
step,
|
|
89
|
+
validate
|
|
90
|
+
};
|
|
91
|
+
class Draft06 extends Draft {
|
|
92
|
+
constructor(schema, config = {}) {
|
|
93
|
+
super(merge(draft06Config, config), schema);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export { Draft06, draft06Config };
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import Keywords from "../../validation/keyword";
|
|
2
|
+
import getTypeOf from "../../getTypeOf";
|
|
3
|
+
const KeywordValidation = {
|
|
4
|
+
...Keywords,
|
|
5
|
+
// @draft >= 6
|
|
6
|
+
contains: (core, schema, value, pointer) => {
|
|
7
|
+
if (schema.contains === false) {
|
|
8
|
+
return core.errors.containsArrayError({ pointer, value });
|
|
9
|
+
}
|
|
10
|
+
if (schema.contains === true) {
|
|
11
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
12
|
+
return core.errors.containsAnyError({ pointer });
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
if (getTypeOf(schema.contains) !== "object") {
|
|
17
|
+
// ignore invalid schema
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
21
|
+
if (core.isValid(value[i], schema.contains)) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return core.errors.containsError({ pointer, schema: JSON.stringify(schema.contains) });
|
|
26
|
+
},
|
|
27
|
+
exclusiveMaximum: (core, schema, value, pointer) => {
|
|
28
|
+
if (isNaN(schema.exclusiveMaximum)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
if (schema.exclusiveMaximum <= value) {
|
|
32
|
+
return core.errors.maximumError({
|
|
33
|
+
maximum: schema.exclusiveMaximum,
|
|
34
|
+
length: value,
|
|
35
|
+
pointer
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
},
|
|
40
|
+
exclusiveMinimum: (core, schema, value, pointer) => {
|
|
41
|
+
if (isNaN(schema.exclusiveMinimum)) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
if (schema.exclusiveMinimum >= value) {
|
|
45
|
+
return core.errors.minimumError({
|
|
46
|
+
minimum: schema.exclusiveMinimum,
|
|
47
|
+
length: value,
|
|
48
|
+
pointer
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
},
|
|
53
|
+
if: (core, schema, value, pointer) => {
|
|
54
|
+
if (schema.if == null) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const ifErrors = core.validate(value, schema.if, pointer);
|
|
58
|
+
// console.log("if Errors", value, ifErrors);
|
|
59
|
+
if (ifErrors.length === 0 && schema.then) {
|
|
60
|
+
return core.validate(value, schema.then, pointer);
|
|
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
|
+
const errors = [];
|
|
91
|
+
const keys = Object.keys(value);
|
|
92
|
+
const patterns = Object.keys(pp).map((expr) => ({
|
|
93
|
+
regex: new RegExp(expr),
|
|
94
|
+
patternSchema: pp[expr]
|
|
95
|
+
}));
|
|
96
|
+
keys.forEach((key) => {
|
|
97
|
+
let patternFound = false;
|
|
98
|
+
for (let i = 0, l = patterns.length; i < l; i += 1) {
|
|
99
|
+
if (patterns[i].regex.test(key)) {
|
|
100
|
+
patternFound = true;
|
|
101
|
+
// for a boolean schema `false`, always invalidate
|
|
102
|
+
if (patterns[i].patternSchema === false) {
|
|
103
|
+
errors.push(core.errors.patternPropertiesError({
|
|
104
|
+
key,
|
|
105
|
+
pointer,
|
|
106
|
+
patterns: Object.keys(pp).join(",")
|
|
107
|
+
}));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const valErrors = core.validate(value[key], patterns[i].patternSchema, `${pointer}/${key}`);
|
|
111
|
+
if (valErrors && valErrors.length > 0) {
|
|
112
|
+
errors.push(...valErrors);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (properties[key]) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (patternFound === false && schema.additionalProperties === false) {
|
|
120
|
+
// this is an arrangement with additionalProperties
|
|
121
|
+
errors.push(core.errors.patternPropertiesError({
|
|
122
|
+
key,
|
|
123
|
+
pointer,
|
|
124
|
+
patterns: Object.keys(pp).join(",")
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return errors;
|
|
129
|
+
},
|
|
130
|
+
// @draft >= 6
|
|
131
|
+
propertyNames: (core, schema, value, pointer) => {
|
|
132
|
+
// bool schema
|
|
133
|
+
if (schema.propertyNames === false) {
|
|
134
|
+
// empty objects are valid
|
|
135
|
+
if (Object.keys(value).length === 0) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
return core.errors.invalidPropertyNameError({
|
|
139
|
+
property: Object.keys(value),
|
|
140
|
+
pointer,
|
|
141
|
+
value
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (schema.propertyNames === true) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
if (getTypeOf(schema.propertyNames) !== "object") {
|
|
148
|
+
// ignore invalid schema
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
const errors = [];
|
|
152
|
+
const properties = Object.keys(value);
|
|
153
|
+
const propertySchema = { ...schema.propertyNames, type: "string" };
|
|
154
|
+
properties.forEach((prop) => {
|
|
155
|
+
const validationResult = core.validate(prop, propertySchema, `${pointer}/${prop}`);
|
|
156
|
+
if (validationResult.length > 0) {
|
|
157
|
+
errors.push(core.errors.invalidPropertyNameError({
|
|
158
|
+
property: prop,
|
|
159
|
+
pointer,
|
|
160
|
+
validationError: validationResult[0],
|
|
161
|
+
value: value[prop]
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return errors;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
export default KeywordValidation;
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
const validationType = {
|
|
9
|
+
array: (core, schema, value, pointer) => core.typeKeywords.array
|
|
10
|
+
.filter((key) => schema && schema[key] != null)
|
|
11
|
+
.map((key) => core.validateKeyword[key](core, schema, value, pointer)),
|
|
12
|
+
object: (core, schema, value, pointer) => core.typeKeywords.object
|
|
13
|
+
.filter((key) => schema && schema[key] != null)
|
|
14
|
+
.map((key) => core.validateKeyword[key](core, schema, value, pointer)),
|
|
15
|
+
string: (core, schema, value, pointer) => core.typeKeywords.string
|
|
16
|
+
.filter((key) => schema && schema[key] != null)
|
|
17
|
+
.map((key) => core.validateKeyword[key](core, schema, value, pointer)),
|
|
18
|
+
integer: (core, schema, value, pointer) => core.typeKeywords.number
|
|
19
|
+
.filter((key) => schema && schema[key] != null)
|
|
20
|
+
.map((key) => core.validateKeyword[key](core, schema, value, pointer)),
|
|
21
|
+
number: (core, schema, value, pointer) => core.typeKeywords.number
|
|
22
|
+
.filter((key) => schema && schema[key] != null)
|
|
23
|
+
.map((key) => core.validateKeyword[key](core, schema, value, pointer)),
|
|
24
|
+
boolean: (core, schema, value, pointer) => core.typeKeywords.boolean
|
|
25
|
+
.filter((key) => schema && schema[key] != null)
|
|
26
|
+
.map((key) => core.validateKeyword[key](core, schema, value, pointer)),
|
|
27
|
+
null: (core, schema, value, pointer) => core.typeKeywords.null
|
|
28
|
+
.filter((key) => schema && schema[key] != null)
|
|
29
|
+
.map((key) => core.validateKeyword[key](core, schema, value, pointer))
|
|
30
|
+
};
|
|
31
|
+
export default validationType;
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import addRemoteSchema from "../addRemoteSchema";
|
|
2
|
+
import compileSchema from "../draft06/compile";
|
|
3
|
+
import { each } from "../each";
|
|
4
|
+
import { eachSchema } from "../eachSchema";
|
|
5
|
+
import ERRORS from "../validation/errors";
|
|
6
|
+
import FORMATS from "../validation/format";
|
|
7
|
+
import getSchema from "../getSchema";
|
|
8
|
+
import getTemplate from "../getTemplate";
|
|
9
|
+
import isValid from "../isValid";
|
|
10
|
+
import KEYWORDS from "../draft06/validation/keyword";
|
|
11
|
+
import merge from "../utils/merge";
|
|
12
|
+
import resolveAllOf from "../resolveAllOf";
|
|
13
|
+
import resolveAnyOf from "../resolveAnyOf";
|
|
14
|
+
import resolveOneOf from "../resolveOneOf.strict";
|
|
15
|
+
import resolveRef from "../resolveRef.strict";
|
|
16
|
+
import createSchemaOf from "../createSchemaOf";
|
|
17
|
+
import getChildSchemaSelection from "../getChildSchemaSelection";
|
|
18
|
+
import step from "../step";
|
|
19
|
+
import TYPES from "../draft06/validation/type";
|
|
20
|
+
import validate from "../validate";
|
|
21
|
+
import { Draft } from "../draft";
|
|
22
|
+
const draft07Config = {
|
|
23
|
+
typeKeywords: {
|
|
24
|
+
array: ["enum", "contains", "items", "minItems", "maxItems", "uniqueItems", "not", "if"],
|
|
25
|
+
boolean: ["enum", "not"],
|
|
26
|
+
object: [
|
|
27
|
+
"additionalProperties",
|
|
28
|
+
"dependencies",
|
|
29
|
+
"enum",
|
|
30
|
+
"format",
|
|
31
|
+
"minProperties",
|
|
32
|
+
"maxProperties",
|
|
33
|
+
"patternProperties",
|
|
34
|
+
"properties",
|
|
35
|
+
"propertyNames",
|
|
36
|
+
"required",
|
|
37
|
+
"not",
|
|
38
|
+
"oneOf",
|
|
39
|
+
"allOf",
|
|
40
|
+
"anyOf",
|
|
41
|
+
"if"
|
|
42
|
+
],
|
|
43
|
+
string: [
|
|
44
|
+
"enum",
|
|
45
|
+
"format",
|
|
46
|
+
"maxLength",
|
|
47
|
+
"minLength",
|
|
48
|
+
"pattern",
|
|
49
|
+
"not",
|
|
50
|
+
"oneOf",
|
|
51
|
+
"allOf",
|
|
52
|
+
"anyOf",
|
|
53
|
+
"if"
|
|
54
|
+
],
|
|
55
|
+
number: [
|
|
56
|
+
"enum",
|
|
57
|
+
"exclusiveMaximum",
|
|
58
|
+
"exclusiveMinimum",
|
|
59
|
+
"format",
|
|
60
|
+
"maximum",
|
|
61
|
+
"minimum",
|
|
62
|
+
"multipleOf",
|
|
63
|
+
"not",
|
|
64
|
+
"oneOf",
|
|
65
|
+
"allOf",
|
|
66
|
+
"anyOf",
|
|
67
|
+
"if"
|
|
68
|
+
],
|
|
69
|
+
null: ["enum", "format", "not", "oneOf", "allOf", "anyOf"]
|
|
70
|
+
},
|
|
71
|
+
validateKeyword: KEYWORDS,
|
|
72
|
+
validateType: TYPES,
|
|
73
|
+
validateFormat: FORMATS,
|
|
74
|
+
errors: ERRORS,
|
|
75
|
+
addRemoteSchema,
|
|
76
|
+
compileSchema,
|
|
77
|
+
createSchemaOf,
|
|
78
|
+
each,
|
|
79
|
+
eachSchema,
|
|
80
|
+
getChildSchemaSelection,
|
|
81
|
+
getSchema,
|
|
82
|
+
getTemplate,
|
|
83
|
+
isValid,
|
|
84
|
+
resolveAllOf,
|
|
85
|
+
resolveAnyOf,
|
|
86
|
+
resolveOneOf,
|
|
87
|
+
resolveRef,
|
|
88
|
+
step,
|
|
89
|
+
validate
|
|
90
|
+
};
|
|
91
|
+
class Draft07 extends Draft {
|
|
92
|
+
constructor(schema, config = {}) {
|
|
93
|
+
super(merge(draft07Config, config), schema);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export { Draft07, draft07Config };
|
package/dist/module/lib/each.js
CHANGED
|
@@ -8,11 +8,11 @@ import getTypeOf from "./getTypeOf";
|
|
|
8
8
|
* @param [schema] - the schema matching the data. Defaults to rootSchema
|
|
9
9
|
* @param [pointer] - pointer to current data. Default to rootPointer
|
|
10
10
|
*/
|
|
11
|
-
export
|
|
11
|
+
export function each(core, data, callback, schema = core.rootSchema, pointer = "#") {
|
|
12
12
|
callback(schema, data, pointer);
|
|
13
13
|
const dataType = getTypeOf(data);
|
|
14
14
|
if (dataType === "object") {
|
|
15
|
-
Object.keys(data).forEach(key => {
|
|
15
|
+
Object.keys(data).forEach((key) => {
|
|
16
16
|
const nextSchema = core.step(key, schema, data, pointer); // not save
|
|
17
17
|
const next = data[key]; // save
|
|
18
18
|
core.each(next, callback, nextSchema, `${pointer}/${key}`);
|
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
import gp from "gson-pointer";
|
|
2
2
|
import getTypeDefs from "./schema/getTypeDefs";
|
|
3
|
-
const isObject = value => Object.prototype.toString.call(value) === "[object Object]";
|
|
3
|
+
const isObject = (value) => Object.prototype.toString.call(value) === "[object Object]";
|
|
4
4
|
function nextTypeDefs(schema, pointer) {
|
|
5
|
-
if (this.callback(schema, pointer) === true) {
|
|
5
|
+
if (this.callback(schema, pointer) === true) {
|
|
6
|
+
// eslint-disable-line no-invalid-this
|
|
6
7
|
return; // stop iteration
|
|
7
8
|
}
|
|
8
9
|
const defs = getTypeDefs(schema);
|
|
9
10
|
// eslint-disable-next-line no-invalid-this
|
|
10
|
-
defs.forEach(next => this.nextTypeDefs(next.def, gp.join(pointer, next.pointer, false)));
|
|
11
|
+
defs.forEach((next) => this.nextTypeDefs(next.def, gp.join(pointer, next.pointer, false)));
|
|
11
12
|
}
|
|
12
|
-
function eachDefinition(walk, schema, pointer) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
|
|
13
|
+
function eachDefinition(walk, schema, pointer, key = "definitions") {
|
|
14
|
+
const defs = schema[key];
|
|
15
|
+
Object.keys(defs).forEach((defId) => {
|
|
16
|
+
if (defs[defId] === false || isObject(defs[defId])) {
|
|
17
|
+
walk.nextTypeDefs(defs[defId], gp.join(pointer, key, defId, false));
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
console.log(`Invalid schema in ${pointer}/${key}/${defId}`);
|
|
20
21
|
});
|
|
21
22
|
}
|
|
22
|
-
export
|
|
23
|
+
export function eachSchema(schema, callback, pointer = "#") {
|
|
23
24
|
const walk = { callback, nextTypeDefs };
|
|
24
25
|
walk.nextTypeDefs(schema, pointer);
|
|
25
|
-
if (schema.definitions
|
|
26
|
-
|
|
26
|
+
if (schema.definitions != null) {
|
|
27
|
+
walk.callback = (defschema, schemaPointer) => {
|
|
28
|
+
callback(defschema, schemaPointer);
|
|
29
|
+
if (defschema.definitions != null) {
|
|
30
|
+
eachDefinition(walk, defschema, schemaPointer);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
eachDefinition(walk, schema, pointer);
|
|
34
|
+
}
|
|
35
|
+
if (schema.$defs != null) {
|
|
36
|
+
walk.callback = (defschema, schemaPointer) => {
|
|
37
|
+
callback(defschema, schemaPointer);
|
|
38
|
+
if (defschema.definitions != null) {
|
|
39
|
+
eachDefinition(walk, defschema, schemaPointer);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
eachDefinition(walk, schema, pointer, "$defs");
|
|
27
43
|
}
|
|
28
|
-
walk.callback = (defschema, schemaPointer) => {
|
|
29
|
-
callback(defschema, schemaPointer);
|
|
30
|
-
if (defschema.definitions != null) {
|
|
31
|
-
eachDefinition(walk, defschema, schemaPointer);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
eachDefinition(walk, schema, pointer);
|
|
35
44
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
+
import { isJSONError } from "./types";
|
|
1
2
|
/**
|
|
2
3
|
* Returns a list of possible child-schemas for the given property key. In case of a oneOf selection, multiple schemas
|
|
3
4
|
* could be added at the given property (e.g. item-index), thus an array of options is returned. In all other cases
|
|
4
5
|
* a list with a single item will be returned
|
|
5
6
|
*
|
|
6
|
-
* @param
|
|
7
|
-
* @param
|
|
8
|
-
* @param
|
|
9
|
-
* @return
|
|
7
|
+
* @param core - core to use
|
|
8
|
+
* @param property - parent schema of following property
|
|
9
|
+
* @param [schema] - parent schema of following property
|
|
10
|
+
* @return
|
|
10
11
|
*/
|
|
11
12
|
export default function getChildSchemaSelection(core, property, schema = core.rootSchema) {
|
|
12
13
|
const result = core.step(property, schema, {}, "#");
|
|
13
|
-
if (result
|
|
14
|
+
if (isJSONError(result)) {
|
|
14
15
|
if (result.code === "one-of-error") {
|
|
15
|
-
return result.data.oneOf.map(item => core.resolveRef(item));
|
|
16
|
+
return result.data.oneOf.map((item) => core.resolveRef(item));
|
|
16
17
|
}
|
|
17
18
|
return result;
|
|
18
19
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import gp from "gson-pointer";
|
|
2
|
+
import { isJSONError } from "./types";
|
|
2
3
|
const emptyObject = {};
|
|
3
4
|
/**
|
|
4
5
|
* Returns the json-schema of a data-json-pointer.
|
|
@@ -19,13 +20,14 @@ export default function getSchema(core, pointer, data, schema = core.rootSchema)
|
|
|
19
20
|
}
|
|
20
21
|
function _get(core, schema, frags, pointer, data = emptyObject) {
|
|
21
22
|
if (frags.length === 0) {
|
|
22
|
-
return schema;
|
|
23
|
+
return core.resolveRef(schema);
|
|
23
24
|
}
|
|
24
25
|
const key = frags.shift(); // step key
|
|
25
26
|
schema = core.step(key, schema, data, pointer); // step schema
|
|
26
|
-
if (schema
|
|
27
|
+
if (isJSONError(schema)) {
|
|
27
28
|
return schema;
|
|
28
29
|
}
|
|
30
|
+
// @ts-ignore
|
|
29
31
|
data = data[key]; // step data
|
|
30
32
|
return _get(core, schema, frags, `${pointer}/${key}`, data);
|
|
31
33
|
}
|