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.
Files changed (161) hide show
  1. package/.editorconfig +1 -0
  2. package/.prettierignore +1 -0
  3. package/.prettierrc +7 -0
  4. package/CHANGELOG.md +106 -0
  5. package/README.md +811 -199
  6. package/TASKS.md +3 -81
  7. package/dist/index.d.ts +29 -71
  8. package/dist/jsonSchemaLibrary.js +1 -1
  9. package/dist/lib/SchemaService.d.ts +6 -8
  10. package/dist/lib/{addSchema.d.ts → addRemoteSchema.d.ts} +2 -1
  11. package/dist/lib/addValidator.d.ts +3 -2
  12. package/dist/lib/compile/getRef.d.ts +2 -1
  13. package/dist/lib/compile/index.d.ts +15 -1
  14. package/dist/lib/compile/types.d.ts +5 -0
  15. package/dist/lib/config/strings.d.ts +1 -39
  16. package/dist/lib/draft/index.d.ts +132 -0
  17. package/dist/lib/draft04/index.d.ts +7 -0
  18. package/dist/lib/draft06/compile/index.d.ts +16 -0
  19. package/dist/lib/draft06/index.d.ts +7 -0
  20. package/dist/lib/draft06/validation/keyword.d.ts +3 -0
  21. package/dist/lib/draft06/validation/type.d.ts +10 -0
  22. package/dist/lib/draft06/validation/typeKeywordMapping.d.ts +13 -0
  23. package/dist/lib/draft07/index.d.ts +7 -0
  24. package/dist/lib/each.d.ts +3 -2
  25. package/dist/lib/eachSchema.d.ts +2 -4
  26. package/dist/lib/getChildSchemaSelection.d.ts +7 -5
  27. package/dist/lib/getSchema.d.ts +2 -2
  28. package/dist/lib/getTemplate.d.ts +1 -1
  29. package/dist/lib/getTypeOf.d.ts +2 -1
  30. package/dist/lib/isValid.d.ts +1 -1
  31. package/dist/lib/jsoneditor/index.d.ts +7 -0
  32. package/dist/lib/resolveAllOf.d.ts +1 -1
  33. package/dist/lib/resolveAnyOf.d.ts +1 -1
  34. package/dist/lib/resolveOneOf.fuzzy.d.ts +1 -1
  35. package/dist/lib/resolveOneOf.strict.d.ts +2 -2
  36. package/dist/lib/{resolveRef.withOverwrite.d.ts → resolveRef.merge.d.ts} +0 -0
  37. package/dist/lib/schema/getTypeDefs.d.ts +6 -4
  38. package/dist/lib/schema/getTypeId.d.ts +1 -1
  39. package/dist/lib/schema/types.d.ts +7 -57
  40. package/dist/lib/step.d.ts +5 -5
  41. package/dist/lib/types.d.ts +11 -3
  42. package/dist/lib/utils/createCustomError.d.ts +8 -11
  43. package/dist/lib/utils/filter.d.ts +4 -4
  44. package/dist/lib/utils/flattenArray.d.ts +1 -1
  45. package/dist/lib/utils/merge.d.ts +3 -0
  46. package/dist/lib/utils/punycode.ucs2decode.d.ts +1 -1
  47. package/dist/lib/validate.d.ts +2 -2
  48. package/dist/lib/validateAsync.d.ts +1 -1
  49. package/dist/lib/validation/errors.d.ts +1 -3
  50. package/dist/lib/validation/format.d.ts +4 -11
  51. package/dist/lib/validation/keyword.d.ts +2 -27
  52. package/dist/lib/validation/type.d.ts +3 -10
  53. package/dist/lib/validation/typeKeywordMapping.d.ts +4 -4
  54. package/dist/module/index.js +23 -32
  55. package/dist/module/lib/SchemaService.js +7 -4
  56. package/dist/module/lib/{addSchema.js → addRemoteSchema.js} +2 -4
  57. package/dist/module/lib/addValidator.js +3 -4
  58. package/dist/module/lib/compile/getRef.js +1 -1
  59. package/dist/module/lib/compile/index.js +43 -18
  60. package/dist/module/lib/compile/types.js +1 -0
  61. package/dist/module/lib/config/strings.js +15 -2
  62. package/dist/module/lib/createSchemaOf.js +1 -1
  63. package/dist/module/lib/draft/index.js +133 -0
  64. package/dist/module/lib/draft04/index.js +90 -0
  65. package/dist/module/lib/draft06/compile/index.js +77 -0
  66. package/dist/module/lib/draft06/index.js +96 -0
  67. package/dist/module/lib/draft06/validation/keyword.js +168 -0
  68. package/dist/module/lib/draft06/validation/type.js +31 -0
  69. package/dist/module/lib/draft06/validation/typeKeywordMapping.js +15 -0
  70. package/dist/module/lib/draft07/index.js +96 -0
  71. package/dist/module/lib/each.js +2 -2
  72. package/dist/module/lib/eachSchema.js +28 -19
  73. package/dist/module/lib/getChildSchemaSelection.js +7 -6
  74. package/dist/module/lib/getSchema.js +4 -2
  75. package/dist/module/lib/getTemplate.js +42 -15
  76. package/dist/module/lib/jsoneditor/index.js +16 -0
  77. package/dist/module/lib/resolveAllOf.js +3 -4
  78. package/dist/module/lib/resolveOneOf.fuzzy.js +13 -3
  79. package/dist/module/lib/resolveOneOf.strict.js +49 -2
  80. package/dist/module/lib/{resolveRef.withOverwrite.js → resolveRef.merge.js} +0 -0
  81. package/dist/module/lib/resolveRef.strict.js +8 -0
  82. package/dist/module/lib/schema/getTypeDefs.js +14 -3
  83. package/dist/module/lib/schema/getTypeId.js +10 -6
  84. package/dist/module/lib/schema/types.js +33 -9
  85. package/dist/module/lib/step.js +67 -13
  86. package/dist/module/lib/types.js +7 -1
  87. package/dist/module/lib/utils/createCustomError.js +4 -4
  88. package/dist/module/lib/utils/filter.js +3 -5
  89. package/dist/module/lib/utils/flattenArray.js +4 -3
  90. package/dist/module/lib/utils/merge.js +4 -0
  91. package/dist/module/lib/utils/punycode.ucs2decode.js +4 -3
  92. package/dist/module/lib/validate.js +34 -8
  93. package/dist/module/lib/validateAsync.js +7 -7
  94. package/dist/module/lib/validation/errors.js +16 -3
  95. package/dist/module/lib/validation/format.js +115 -8
  96. package/dist/module/lib/validation/keyword.js +79 -32
  97. package/dist/module/lib/validation/type.js +2 -1
  98. package/index.ts +46 -32
  99. package/lib/SchemaService.ts +18 -11
  100. package/lib/{addSchema.ts → addRemoteSchema.ts} +3 -5
  101. package/lib/addValidator.ts +15 -12
  102. package/lib/compile/getRef.ts +3 -4
  103. package/lib/compile/index.ts +65 -19
  104. package/lib/compile/types.ts +6 -0
  105. package/lib/config/strings.ts +17 -3
  106. package/lib/createSchemaOf.ts +1 -3
  107. package/lib/draft/index.ts +201 -0
  108. package/lib/draft04/index.ts +95 -0
  109. package/lib/draft06/compile/index.ts +104 -0
  110. package/lib/draft06/index.ts +101 -0
  111. package/lib/draft06/validation/keyword.ts +199 -0
  112. package/lib/draft06/validation/type.ts +47 -0
  113. package/lib/draft06/validation/typeKeywordMapping.ts +15 -0
  114. package/lib/draft07/index.ts +101 -0
  115. package/lib/each.ts +11 -4
  116. package/lib/eachSchema.ts +45 -32
  117. package/lib/getChildSchemaSelection.ts +14 -7
  118. package/lib/getSchema.ts +18 -9
  119. package/lib/getTemplate.ts +155 -42
  120. package/lib/getTypeOf.ts +2 -1
  121. package/lib/isValid.ts +7 -3
  122. package/lib/jsoneditor/index.ts +20 -0
  123. package/lib/resolveAllOf.ts +10 -6
  124. package/lib/resolveAnyOf.ts +7 -3
  125. package/lib/resolveOneOf.fuzzy.ts +26 -9
  126. package/lib/resolveOneOf.strict.ts +63 -5
  127. package/lib/{resolveRef.withOverwrite.ts → resolveRef.merge.ts} +0 -0
  128. package/lib/resolveRef.strict.ts +9 -0
  129. package/lib/schema/getTypeDefs.ts +19 -7
  130. package/lib/schema/getTypeId.ts +11 -8
  131. package/lib/schema/types.ts +41 -9
  132. package/lib/step.ts +109 -25
  133. package/lib/types.ts +23 -5
  134. package/lib/utils/createCustomError.ts +8 -13
  135. package/lib/utils/filter.ts +7 -9
  136. package/lib/utils/flattenArray.ts +5 -4
  137. package/lib/utils/merge.ts +5 -0
  138. package/lib/utils/punycode.ucs2decode.ts +6 -5
  139. package/lib/validate.ts +47 -16
  140. package/lib/validateAsync.ts +15 -14
  141. package/lib/validation/errors.ts +17 -6
  142. package/lib/validation/format.ts +147 -13
  143. package/lib/validation/keyword.ts +172 -103
  144. package/lib/validation/type.ts +5 -1
  145. package/package.json +75 -63
  146. package/{dist/module/remotes/draft04.json → remotes/draft06.json} +47 -42
  147. package/remotes/draft07.json +172 -0
  148. package/remotes/draft2019-09.json +86 -0
  149. package/tsconfig.json +3 -10
  150. package/dist/lib/cores/CoreInterface.d.ts +0 -23
  151. package/dist/lib/cores/Draft04.d.ts +0 -13
  152. package/dist/lib/cores/JsonEditor.d.ts +0 -13
  153. package/dist/module/lib/cores/CoreInterface.js +0 -51
  154. package/dist/module/lib/cores/Draft04.js +0 -52
  155. package/dist/module/lib/cores/JsonEditor.js +0 -51
  156. package/dist/module/remotes/index.js +0 -10
  157. package/dist/remotes/index.d.ts +0 -5
  158. package/lib/cores/CoreInterface.ts +0 -76
  159. package/lib/cores/Draft04.ts +0 -66
  160. package/lib/cores/JsonEditor.ts +0 -64
  161. package/remotes/index.ts +0 -11
@@ -0,0 +1,201 @@
1
+ import step from "../step";
2
+ import validate from "../validate";
3
+ import resolveOneOf from "../resolveOneOf.strict";
4
+ import resolveRef from "../resolveRef.strict";
5
+ import resolveAllOf from "../resolveAllOf";
6
+ import resolveAnyOf from "../resolveAnyOf";
7
+ import getTemplate from "../getTemplate";
8
+ import getChildSchemaSelection from "../getChildSchemaSelection";
9
+ import getSchema from "../getSchema";
10
+ import { each, EachCallback } from "../each";
11
+ import isValid from "../isValid";
12
+ import { eachSchema, EachSchemaCallback } from "../eachSchema";
13
+ import createSchemaOf from "../createSchemaOf";
14
+ import compileSchema from "../compileSchema";
15
+ import { CreateError } from "../utils/createCustomError";
16
+ import addRemoteSchema from "../addRemoteSchema";
17
+ import { JSONSchema, JSONPointer, JSONValidator, JSONTypeValidator, JSONError } from "../types";
18
+
19
+ export type DraftConfig = {
20
+ /** error creators by id */
21
+ errors: Record<string, CreateError>;
22
+ /** map for valid keywords of a type */
23
+ typeKeywords: Record<string, string[]>;
24
+ /** keyword validators */
25
+ validateKeyword: Record<string, JSONValidator>;
26
+ /** type validators */
27
+ validateType: Record<string, JSONTypeValidator>;
28
+ /** format validators */
29
+ validateFormat: Record<string, JSONValidator>;
30
+
31
+ addRemoteSchema: typeof addRemoteSchema;
32
+ compileSchema: typeof compileSchema;
33
+ createSchemaOf: typeof createSchemaOf;
34
+ each: typeof each;
35
+ eachSchema: typeof eachSchema;
36
+ getChildSchemaSelection: typeof getChildSchemaSelection;
37
+ getSchema: typeof getSchema;
38
+ getTemplate: typeof getTemplate;
39
+ isValid: typeof isValid;
40
+ resolveAllOf: typeof resolveAllOf;
41
+ resolveAnyOf: typeof resolveAnyOf;
42
+ resolveOneOf: typeof resolveOneOf;
43
+ resolveRef: typeof resolveRef;
44
+ step: typeof step;
45
+ validate: typeof validate;
46
+ };
47
+
48
+ export class Draft {
49
+ readonly config: DraftConfig;
50
+ /** entry point of schema */
51
+ private __rootSchema: JSONSchema;
52
+ /** cache for remote schemas */
53
+ remotes: Record<string, JSONSchema> = {};
54
+ /** error creators by id */
55
+ readonly errors: Record<string, CreateError> = {};
56
+ /** map for valid keywords of a type */
57
+ readonly typeKeywords: Record<string, string[]> = {};
58
+ /** keyword validators */
59
+ readonly validateKeyword: Record<string, JSONValidator> = {};
60
+ /** type validators */
61
+ readonly validateType: Record<string, JSONTypeValidator> = {};
62
+ /** format validators */
63
+ readonly validateFormat: Record<string, JSONValidator> = {};
64
+
65
+ constructor(config: DraftConfig, schema?: JSONSchema) {
66
+ this.config = config;
67
+ this.typeKeywords = JSON.parse(JSON.stringify(config.typeKeywords));
68
+ this.validateKeyword = Object.assign({}, config.validateKeyword);
69
+ this.validateType = Object.assign({}, config.validateType);
70
+ this.validateFormat = Object.assign({}, config.validateFormat);
71
+ this.errors = Object.assign({}, config.errors);
72
+ this.setSchema(schema);
73
+ }
74
+
75
+ get rootSchema() {
76
+ return this.__rootSchema;
77
+ }
78
+
79
+ set rootSchema(rootSchema: JSONSchema) {
80
+ if (rootSchema == null) {
81
+ return;
82
+ }
83
+ this.__rootSchema = this.config.compileSchema(this, rootSchema);
84
+ }
85
+
86
+ /**
87
+ * register a json-schema to be referenced from another json-schema
88
+ * @param url - base-url of json-schema (aka id)
89
+ * @param schema - json-schema root
90
+ */
91
+ addRemoteSchema(url: string, schema: JSONSchema): void {
92
+ this.config.addRemoteSchema(this, url, schema);
93
+ }
94
+
95
+ compileSchema(schema: JSONSchema): JSONSchema {
96
+ return this.config.compileSchema(this, schema, this.rootSchema ?? schema);
97
+ }
98
+
99
+ createSchemaOf(data: unknown) {
100
+ return this.config.createSchemaOf(data);
101
+ }
102
+
103
+ /**
104
+ * Iterates over data, retrieving its schema
105
+ *
106
+ * @param data - the data to iterate
107
+ * @param callback - will be called with (schema, data, pointer) on each item
108
+ * @param [schema] - the schema matching the data. Defaults to rootSchema
109
+ * @param [pointer] - pointer to current data. Default to rootPointer
110
+ */
111
+ each(data: any, callback: EachCallback, schema?: JSONSchema, pointer?: JSONPointer) {
112
+ return this.config.each(this, data, callback, schema, pointer);
113
+ }
114
+
115
+ eachSchema(callback: EachSchemaCallback, schema = this.rootSchema) {
116
+ return this.config.eachSchema(schema, callback);
117
+ }
118
+
119
+ getChildSchemaSelection(property: string | number, schema?: JSONSchema) {
120
+ return this.config.getChildSchemaSelection(this, property, schema);
121
+ }
122
+
123
+ /**
124
+ * Returns the json-schema of a data-json-pointer.
125
+ * Notes
126
+ * - Uses core.step to walk through data and schema
127
+ *
128
+ * @param pointer - json pointer in data to get the json schema for
129
+ * @param [data] - the data object, which includes the json pointers value. This is optional, as
130
+ * long as no oneOf, anyOf, etc statement is part of the pointers schema
131
+ * @param [schema] - the json schema to iterate. Defaults to core.rootSchema
132
+ * @return json schema object of the json-pointer or an error
133
+ */
134
+ getSchema(pointer: JSONPointer = "#", data?: any, schema?: JSONSchema): JSONSchema | JSONError {
135
+ return this.config.getSchema(this, pointer, data, schema);
136
+ }
137
+
138
+ /**
139
+ * Create data object matching the given schema
140
+ *
141
+ * @param [data] - optional template data
142
+ * @param [schema] - json schema, defaults to rootSchema
143
+ * @return created template data
144
+ */
145
+ getTemplate(data?: unknown, schema?: JSONSchema) {
146
+ return this.config.getTemplate(this, data, schema);
147
+ }
148
+
149
+ isValid(data: any, schema?: JSONSchema, pointer?: JSONPointer): boolean {
150
+ return this.config.isValid(this, data, schema, pointer);
151
+ }
152
+
153
+ resolveAnyOf(data: any, schema: JSONSchema, pointer?: JSONPointer): JSONSchema {
154
+ return this.config.resolveAnyOf(this, data, schema, pointer);
155
+ }
156
+
157
+ resolveAllOf(data: any, schema: JSONSchema, pointer?: JSONPointer): JSONSchema {
158
+ return this.config.resolveAllOf(this, data, schema, pointer);
159
+ }
160
+
161
+ resolveRef(schema: JSONSchema): JSONSchema {
162
+ return this.config.resolveRef(schema, this.rootSchema);
163
+ }
164
+
165
+ resolveOneOf(data: any, schema: JSONSchema, pointer?: JSONPointer): JSONSchema {
166
+ return this.config.resolveOneOf(this, data, schema, pointer);
167
+ }
168
+
169
+ setSchema(schema: JSONSchema) {
170
+ this.rootSchema = schema;
171
+ }
172
+
173
+ /**
174
+ * Returns the json-schema of the given object property or array item.
175
+ * e.g. it steps by one key into the data
176
+ *
177
+ * This helper determines the location of the property within the schema (additional properties, oneOf, ...) and
178
+ * returns the correct schema.
179
+ *
180
+ * @param key - property-name or array-index
181
+ * @param schema - json schema of current data
182
+ * @param data - parent of key
183
+ * @param [pointer] - pointer to schema and data (parent of key)
184
+ * @return Schema or Error if failed resolving key
185
+ */
186
+ step(key: string | number, schema: JSONSchema, data: any, pointer?: JSONPointer): JSONSchema {
187
+ return this.config.step(this, key, schema, data, pointer);
188
+ }
189
+
190
+ /**
191
+ * Validate data by a json schema
192
+ *
193
+ * @param value - value to validate
194
+ * @param [schema] - json schema, defaults to rootSchema
195
+ * @param [pointer] - json pointer pointing to value (used for error-messages only)
196
+ * @return list of errors or empty
197
+ */
198
+ validate(data: unknown, schema?: JSONSchema, pointer?: JSONPointer): JSONError[] {
199
+ return this.config.validate(this, data, schema, pointer);
200
+ }
201
+ }
@@ -0,0 +1,95 @@
1
+ import addRemoteSchema from "../addRemoteSchema";
2
+ import compileSchema from "../compileSchema";
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 "../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 step from "../step";
17
+ import createSchemaOf from "../createSchemaOf";
18
+ import getChildSchemaSelection from "../getChildSchemaSelection";
19
+ import TYPES from "../validation/type";
20
+ import validate from "../validate";
21
+ import { DraftConfig, Draft } from "../draft";
22
+ import { JSONSchema } from "../types";
23
+
24
+ const draft04Config: DraftConfig = {
25
+ typeKeywords: {
26
+ array: ["enum", "items", "minItems", "maxItems", "uniqueItems", "not"],
27
+ boolean: ["enum", "not"],
28
+ object: [
29
+ "additionalProperties",
30
+ "dependencies",
31
+ "enum",
32
+ "format",
33
+ "minProperties",
34
+ "maxProperties",
35
+ "patternProperties",
36
+ "properties",
37
+ "required",
38
+ "not",
39
+ "oneOf",
40
+ "allOf",
41
+ "anyOf"
42
+ ],
43
+ string: [
44
+ "enum",
45
+ "format",
46
+ "maxLength",
47
+ "minLength",
48
+ "pattern",
49
+ "not",
50
+ "oneOf",
51
+ "allOf",
52
+ "anyOf"
53
+ ],
54
+ number: [
55
+ "enum",
56
+ "format",
57
+ "maximum",
58
+ "minimum",
59
+ "multipleOf",
60
+ "not",
61
+ "oneOf",
62
+ "allOf",
63
+ "anyOf"
64
+ ],
65
+ null: ["enum", "format", "not", "oneOf", "allOf", "anyOf"]
66
+ },
67
+ validateKeyword: KEYWORDS,
68
+ validateType: TYPES,
69
+ validateFormat: FORMATS,
70
+ errors: ERRORS,
71
+
72
+ addRemoteSchema,
73
+ compileSchema,
74
+ createSchemaOf,
75
+ each,
76
+ eachSchema,
77
+ getChildSchemaSelection,
78
+ getSchema,
79
+ getTemplate,
80
+ isValid,
81
+ resolveAllOf,
82
+ resolveAnyOf,
83
+ resolveOneOf,
84
+ resolveRef,
85
+ step,
86
+ validate
87
+ };
88
+
89
+ class Draft04 extends Draft {
90
+ constructor(schema?: JSONSchema, config: Partial<DraftConfig> = {}) {
91
+ super(merge(draft04Config, config), schema);
92
+ }
93
+ }
94
+
95
+ export { Draft04, draft04Config };
@@ -0,0 +1,104 @@
1
+ /* eslint max-statements-per-line: ["error", { "max": 2 }] */
2
+ import { Draft } from "../../draft";
3
+ import { eachSchema } from "../../eachSchema";
4
+ // import remotes from "../../../remotes";
5
+ import joinScope from "../../compile/joinScope";
6
+ import getRef from "../../compile/getRef";
7
+ import { JSONSchema } from "../../types";
8
+
9
+ const COMPILED = "__compiled";
10
+ const COMPILED_REF = "__ref";
11
+ const GET_REF = "getRef";
12
+ const GET_ROOT = "getRoot";
13
+ const suffixes = /(#|\/)+$/g;
14
+
15
+ type Context = {
16
+ ids: Record<string, unknown>;
17
+ remotes: Record<string, JSONSchema>;
18
+ };
19
+
20
+ /**
21
+ * @draft starting with _draft 06_ keyword `id` has been renamed to `$id`
22
+ *
23
+ * compiles the input root schema for $ref resolution and returns it again
24
+ * @attention this modifies input schema but maintains object-structure
25
+ *
26
+ * for a compiled json-schema you can call getRef on any contained schema (location of type).
27
+ * this resolves a $ref target to a valid schema (for a valid $ref)
28
+ *
29
+ * @param rootSchema root json-schema ($id, defs, ... ) to compile
30
+ * @param [force] = false force compile json-schema
31
+ * @return compiled json-schema
32
+ */
33
+ export default function compileSchema(
34
+ draft: Draft,
35
+ schemaToCompile: JSONSchema,
36
+ rootSchema = schemaToCompile,
37
+ force = false
38
+ ): JSONSchema {
39
+ // @ts-ignore
40
+ if (schemaToCompile === true || schemaToCompile === false || schemaToCompile === undefined) {
41
+ return schemaToCompile;
42
+ }
43
+ if (schemaToCompile[COMPILED] !== undefined) {
44
+ return schemaToCompile;
45
+ } // eslint-disable-line
46
+ const context: Context = { ids: {}, remotes: draft.remotes };
47
+ const rootSchemaAsString = JSON.stringify(schemaToCompile);
48
+ const compiledSchema = JSON.parse(rootSchemaAsString);
49
+ Object.defineProperty(compiledSchema, COMPILED, { enumerable: false, value: true });
50
+ Object.defineProperty(compiledSchema, GET_REF, {
51
+ enumerable: false,
52
+ value: getRef.bind(null, context, compiledSchema)
53
+ });
54
+
55
+ // bail early, when no $refs are defined
56
+ if (force === false && rootSchemaAsString.includes("$ref") === false) {
57
+ return compiledSchema;
58
+ }
59
+
60
+ // compile this schema under rootSchema, making definitions available to $ref-resolution
61
+ if (compiledSchema !== rootSchema) {
62
+ Object.defineProperty(compiledSchema, "$defs", {
63
+ enumerable: true,
64
+ value: Object.assign(
65
+ {},
66
+ rootSchema.definitions,
67
+ rootSchema.$defs,
68
+ compiledSchema.definitions,
69
+ compiledSchema.$defs
70
+ )
71
+ });
72
+ }
73
+
74
+ const scopes: Record<string, string> = {};
75
+ const getRoot = () => compiledSchema;
76
+ eachSchema(compiledSchema, (schema, pointer) => {
77
+ if (schema.$id) {
78
+ context.ids[schema.$id.replace(suffixes, "")] = pointer;
79
+ }
80
+
81
+ // build up scopes and add them to $ref-resolution map
82
+ pointer = `#${pointer}`.replace(/##+/, "#");
83
+ const previousPointer = pointer.replace(/\/[^/]+$/, "");
84
+ const parentPointer = pointer.replace(/\/[^/]+\/[^/]+$/, "");
85
+ const previousScope = scopes[previousPointer] || scopes[parentPointer];
86
+ const scope = joinScope(previousScope, schema.$id);
87
+ scopes[pointer] = scope;
88
+ if (context.ids[scope] == null) {
89
+ context.ids[scope] = pointer;
90
+ }
91
+
92
+ if (schema.$ref && !schema[COMPILED_REF]) {
93
+ Object.defineProperty(schema, COMPILED_REF, {
94
+ enumerable: false,
95
+ value: joinScope(scope, schema.$ref)
96
+ });
97
+ // @todo currently not used:
98
+ Object.defineProperty(schema, GET_ROOT, { enumerable: false, value: getRoot });
99
+ // console.log("compiled ref", scope, schema.$ref, "=>", joinScope(scope, schema.$ref));
100
+ }
101
+ });
102
+
103
+ return compiledSchema;
104
+ }
@@ -0,0 +1,101 @@
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 { DraftConfig, Draft } from "../draft";
22
+ import { JSONSchema } from "../types";
23
+
24
+ const draft06Config: DraftConfig = {
25
+ typeKeywords: {
26
+ array: ["enum", "contains", "items", "minItems", "maxItems", "uniqueItems", "not", "if"],
27
+ boolean: ["enum", "not"],
28
+ object: [
29
+ "additionalProperties",
30
+ "dependencies",
31
+ "enum",
32
+ "format",
33
+ "minProperties",
34
+ "maxProperties",
35
+ "patternProperties",
36
+ "properties",
37
+ "propertyNames",
38
+ "required",
39
+ "not",
40
+ "oneOf",
41
+ "allOf",
42
+ "anyOf",
43
+ "if"
44
+ ],
45
+ string: [
46
+ "enum",
47
+ "format",
48
+ "maxLength",
49
+ "minLength",
50
+ "pattern",
51
+ "not",
52
+ "oneOf",
53
+ "allOf",
54
+ "anyOf",
55
+ "if"
56
+ ],
57
+ number: [
58
+ "enum",
59
+ "exclusiveMaximum",
60
+ "exclusiveMinimum",
61
+ "format",
62
+ "maximum",
63
+ "minimum",
64
+ "multipleOf",
65
+ "not",
66
+ "oneOf",
67
+ "allOf",
68
+ "anyOf",
69
+ "if"
70
+ ],
71
+ null: ["enum", "format", "not", "oneOf", "allOf", "anyOf"]
72
+ },
73
+ validateKeyword: KEYWORDS,
74
+ validateType: TYPES,
75
+ validateFormat: FORMATS,
76
+ errors: ERRORS,
77
+
78
+ addRemoteSchema,
79
+ compileSchema,
80
+ createSchemaOf,
81
+ each,
82
+ eachSchema,
83
+ getChildSchemaSelection,
84
+ getSchema,
85
+ getTemplate,
86
+ isValid,
87
+ resolveAllOf,
88
+ resolveAnyOf,
89
+ resolveOneOf,
90
+ resolveRef,
91
+ step,
92
+ validate
93
+ };
94
+
95
+ class Draft06 extends Draft {
96
+ constructor(schema?: JSONSchema, config: Partial<DraftConfig> = {}) {
97
+ super(merge(draft06Config, config), schema);
98
+ }
99
+ }
100
+
101
+ export { Draft06, draft06Config };
@@ -0,0 +1,199 @@
1
+ import Keywords from "../../validation/keyword";
2
+ import getTypeOf from "../../getTypeOf";
3
+ import { JSONValidator, JSONError } from "../../types";
4
+
5
+ const KeywordValidation: Record<string, JSONValidator> = {
6
+ ...Keywords,
7
+ // @draft >= 6
8
+ contains: (core, schema, value: unknown[], pointer) => {
9
+ if (schema.contains === false) {
10
+ return core.errors.containsArrayError({ pointer, value });
11
+ }
12
+
13
+ if (schema.contains === true) {
14
+ if (Array.isArray(value) && value.length === 0) {
15
+ return core.errors.containsAnyError({ pointer });
16
+ }
17
+ return undefined;
18
+ }
19
+
20
+ if (getTypeOf(schema.contains) !== "object") {
21
+ // ignore invalid schema
22
+ return undefined;
23
+ }
24
+
25
+ for (let i = 0; i < value.length; i += 1) {
26
+ if (core.isValid(value[i], schema.contains)) {
27
+ return undefined;
28
+ }
29
+ }
30
+ return core.errors.containsError({ pointer, schema: JSON.stringify(schema.contains) });
31
+ },
32
+ exclusiveMaximum: (core, schema, value, pointer) => {
33
+ if (isNaN(schema.exclusiveMaximum)) {
34
+ return undefined;
35
+ }
36
+ if (schema.exclusiveMaximum <= value) {
37
+ return core.errors.maximumError({
38
+ maximum: schema.exclusiveMaximum,
39
+ length: value,
40
+ pointer
41
+ });
42
+ }
43
+ return undefined;
44
+ },
45
+ exclusiveMinimum: (core, schema, value, pointer) => {
46
+ if (isNaN(schema.exclusiveMinimum)) {
47
+ return undefined;
48
+ }
49
+ if (schema.exclusiveMinimum >= value) {
50
+ return core.errors.minimumError({
51
+ minimum: schema.exclusiveMinimum,
52
+ length: value,
53
+ pointer
54
+ });
55
+ }
56
+ return undefined;
57
+ },
58
+ if: (core, schema, value, pointer) => {
59
+ if (schema.if == null) {
60
+ return undefined;
61
+ }
62
+
63
+ const ifErrors = core.validate(value, schema.if, pointer);
64
+ // console.log("if Errors", value, ifErrors);
65
+
66
+ if (ifErrors.length === 0 && schema.then) {
67
+ return core.validate(value, schema.then, pointer);
68
+ }
69
+
70
+ if (ifErrors.length !== 0 && schema.else) {
71
+ return core.validate(value, schema.else, pointer);
72
+ }
73
+ },
74
+ maximum: (core, schema, value, pointer) => {
75
+ if (isNaN(schema.maximum)) {
76
+ return undefined;
77
+ }
78
+ if (schema.maximum && schema.maximum < value) {
79
+ return core.errors.maximumError({ maximum: schema.maximum, length: value, pointer });
80
+ }
81
+ return undefined;
82
+ },
83
+ minimum: (core, schema, value, pointer) => {
84
+ if (isNaN(schema.minimum)) {
85
+ return undefined;
86
+ }
87
+ if (schema.minimum > value) {
88
+ return core.errors.minimumError({ minimum: schema.minimum, length: value, pointer });
89
+ }
90
+ return undefined;
91
+ },
92
+ patternProperties: (core, schema, value: Record<string, unknown>, pointer) => {
93
+ const properties = schema.properties || {};
94
+ const pp = schema.patternProperties;
95
+ if (getTypeOf(pp) !== "object") {
96
+ return undefined;
97
+ }
98
+
99
+ const errors: JSONError[] = [];
100
+ const keys = Object.keys(value);
101
+ const patterns = Object.keys(pp).map((expr) => ({
102
+ regex: new RegExp(expr),
103
+ patternSchema: pp[expr]
104
+ }));
105
+
106
+ keys.forEach((key) => {
107
+ let patternFound = false;
108
+
109
+ for (let i = 0, l = patterns.length; i < l; i += 1) {
110
+ if (patterns[i].regex.test(key)) {
111
+ patternFound = true;
112
+
113
+ // for a boolean schema `false`, always invalidate
114
+ if (patterns[i].patternSchema === false) {
115
+ errors.push(
116
+ core.errors.patternPropertiesError({
117
+ key,
118
+ pointer,
119
+ patterns: Object.keys(pp).join(",")
120
+ })
121
+ );
122
+ return;
123
+ }
124
+
125
+ const valErrors = core.validate(
126
+ value[key],
127
+ patterns[i].patternSchema,
128
+ `${pointer}/${key}`
129
+ );
130
+ if (valErrors && valErrors.length > 0) {
131
+ errors.push(...valErrors);
132
+ }
133
+ }
134
+ }
135
+
136
+ if (properties[key]) {
137
+ return;
138
+ }
139
+
140
+ if (patternFound === false && schema.additionalProperties === false) {
141
+ // this is an arrangement with additionalProperties
142
+ errors.push(
143
+ core.errors.patternPropertiesError({
144
+ key,
145
+ pointer,
146
+ patterns: Object.keys(pp).join(",")
147
+ })
148
+ );
149
+ }
150
+ });
151
+
152
+ return errors;
153
+ },
154
+ // @draft >= 6
155
+ propertyNames: (core, schema, value: Record<string, unknown>, pointer) => {
156
+ // bool schema
157
+ if (schema.propertyNames === false) {
158
+ // empty objects are valid
159
+ if (Object.keys(value).length === 0) {
160
+ return undefined;
161
+ }
162
+ return core.errors.invalidPropertyNameError({
163
+ property: Object.keys(value),
164
+ pointer,
165
+ value
166
+ });
167
+ }
168
+
169
+ if (schema.propertyNames === true) {
170
+ return undefined;
171
+ }
172
+
173
+ if (getTypeOf(schema.propertyNames) !== "object") {
174
+ // ignore invalid schema
175
+ return undefined;
176
+ }
177
+
178
+ const errors: JSONError[] = [];
179
+ const properties = Object.keys(value);
180
+ const propertySchema = { ...schema.propertyNames, type: "string" };
181
+ properties.forEach((prop) => {
182
+ const validationResult = core.validate(prop, propertySchema, `${pointer}/${prop}`);
183
+ if (validationResult.length > 0) {
184
+ errors.push(
185
+ core.errors.invalidPropertyNameError({
186
+ property: prop,
187
+ pointer,
188
+ validationError: validationResult[0],
189
+ value: value[prop]
190
+ })
191
+ );
192
+ }
193
+ });
194
+
195
+ return errors;
196
+ }
197
+ };
198
+
199
+ export default KeywordValidation;