@hyperjump/json-schema 0.23.3 → 1.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 (202) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +459 -120
  3. package/draft-04/additionalItems.js +29 -0
  4. package/{lib/keywords → draft-04}/dependencies.js +9 -5
  5. package/draft-04/exclusiveMaximum.js +5 -0
  6. package/draft-04/exclusiveMinimum.js +5 -0
  7. package/draft-04/id.js +1 -0
  8. package/draft-04/index.d.ts +43 -0
  9. package/draft-04/index.js +69 -0
  10. package/draft-04/items.js +35 -0
  11. package/draft-04/maximum.js +26 -0
  12. package/draft-04/minimum.js +25 -0
  13. package/draft-04/ref.js +1 -0
  14. package/draft-04/schema.js +149 -0
  15. package/draft-06/contains.js +13 -0
  16. package/draft-06/index.d.ts +47 -0
  17. package/draft-06/index.js +66 -0
  18. package/draft-06/schema.js +154 -0
  19. package/{lib/draft-07.d.ts → draft-07/index.d.ts} +21 -19
  20. package/draft-07/index.js +72 -0
  21. package/draft-07/schema.js +172 -0
  22. package/{lib/keywords/contains-minContains-maxContains.js → draft-2019-09/contains.js} +14 -7
  23. package/{lib/draft-2019-09.d.ts → draft-2019-09/index.d.ts} +24 -22
  24. package/draft-2019-09/index.js +117 -0
  25. package/draft-2019-09/meta/applicator.js +55 -0
  26. package/draft-2019-09/meta/content.js +17 -0
  27. package/draft-2019-09/meta/core.js +57 -0
  28. package/draft-2019-09/meta/format.js +14 -0
  29. package/draft-2019-09/meta/meta-data.js +37 -0
  30. package/draft-2019-09/meta/validation.js +98 -0
  31. package/draft-2019-09/recursiveAnchor.js +1 -0
  32. package/draft-2019-09/recursiveRef.js +19 -0
  33. package/draft-2019-09/schema.js +42 -0
  34. package/draft-2020-12/dynamicAnchor.js +1 -0
  35. package/draft-2020-12/dynamicRef.js +35 -0
  36. package/draft-2020-12/index.d.ts +66 -0
  37. package/draft-2020-12/index.js +124 -0
  38. package/draft-2020-12/meta/applicator.js +46 -0
  39. package/draft-2020-12/meta/content.js +14 -0
  40. package/draft-2020-12/meta/core.js +54 -0
  41. package/draft-2020-12/meta/format-annotation.js +11 -0
  42. package/draft-2020-12/meta/format-assertion.js +11 -0
  43. package/draft-2020-12/meta/meta-data.js +34 -0
  44. package/draft-2020-12/meta/unevaluated.js +12 -0
  45. package/draft-2020-12/meta/validation.js +95 -0
  46. package/draft-2020-12/schema.js +44 -0
  47. package/lib/common.d.ts +5 -1
  48. package/lib/common.js +80 -9
  49. package/lib/configuration.d.ts +9 -0
  50. package/lib/configuration.js +18 -0
  51. package/lib/core.d.ts +48 -0
  52. package/lib/core.js +102 -0
  53. package/lib/experimental.d.ts +8 -0
  54. package/lib/experimental.js +4 -0
  55. package/lib/fetch.browser.js +1 -0
  56. package/lib/fetch.js +19 -0
  57. package/lib/index.d.ts +11 -42
  58. package/lib/index.js +130 -23
  59. package/lib/instance.d.ts +75 -0
  60. package/lib/instance.js +58 -0
  61. package/lib/invalid-schema-error.d.ts +8 -0
  62. package/lib/invalid-schema-error.js +7 -0
  63. package/lib/keywords/additionalProperties.js +19 -17
  64. package/lib/keywords/allOf.js +10 -7
  65. package/lib/keywords/anchor.js +1 -0
  66. package/lib/keywords/anyOf.js +10 -7
  67. package/lib/keywords/comment.js +4 -0
  68. package/lib/keywords/const.js +6 -3
  69. package/lib/keywords/contains.js +48 -5
  70. package/lib/keywords/contentEncoding.js +4 -0
  71. package/lib/keywords/contentMediaType.js +4 -0
  72. package/lib/keywords/contentSchema.js +4 -0
  73. package/lib/keywords/default.js +4 -0
  74. package/lib/keywords/definitions.js +7 -4
  75. package/lib/keywords/dependentRequired.js +6 -3
  76. package/lib/keywords/dependentSchemas.js +10 -6
  77. package/lib/keywords/deprecated.js +4 -0
  78. package/lib/keywords/description.js +4 -0
  79. package/lib/keywords/dynamicAnchor.js +1 -0
  80. package/lib/keywords/dynamicRef.js +13 -17
  81. package/lib/keywords/else.js +16 -11
  82. package/lib/keywords/enum.js +6 -3
  83. package/lib/keywords/examples.js +4 -0
  84. package/lib/keywords/exclusiveMaximum.js +5 -2
  85. package/lib/keywords/exclusiveMinimum.js +5 -2
  86. package/lib/keywords/format.js +4 -0
  87. package/lib/keywords/id.js +1 -0
  88. package/lib/keywords/if.js +8 -6
  89. package/lib/keywords/items.js +17 -19
  90. package/lib/keywords/maxContains.js +4 -0
  91. package/lib/keywords/maxItems.js +5 -2
  92. package/lib/keywords/maxLength.js +5 -2
  93. package/lib/keywords/maxProperties.js +5 -2
  94. package/lib/keywords/maximum.js +5 -2
  95. package/lib/keywords/meta-data.js +4 -0
  96. package/lib/keywords/minContains.js +4 -0
  97. package/lib/keywords/minItems.js +5 -2
  98. package/lib/keywords/minLength.js +5 -2
  99. package/lib/keywords/minProperties.js +5 -2
  100. package/lib/keywords/minimum.js +5 -2
  101. package/lib/keywords/multipleOf.js +5 -2
  102. package/lib/keywords/not.js +6 -4
  103. package/lib/keywords/oneOf.js +9 -6
  104. package/lib/keywords/pattern.js +5 -2
  105. package/lib/keywords/patternProperties.js +9 -5
  106. package/lib/keywords/prefixItems.js +28 -0
  107. package/lib/keywords/properties.js +11 -6
  108. package/lib/keywords/propertyDependencies.js +49 -0
  109. package/lib/keywords/propertyNames.js +7 -4
  110. package/lib/keywords/readOnly.js +4 -0
  111. package/lib/keywords/ref.js +9 -6
  112. package/lib/keywords/requireAllExcept.js +24 -0
  113. package/lib/keywords/required.js +5 -2
  114. package/lib/keywords/then.js +16 -11
  115. package/lib/keywords/title.js +4 -0
  116. package/lib/keywords/type.js +5 -2
  117. package/lib/keywords/unevaluatedItems.js +9 -5
  118. package/lib/keywords/unevaluatedProperties.js +9 -5
  119. package/lib/keywords/uniqueItems.js +6 -3
  120. package/lib/keywords/validation.js +123 -0
  121. package/lib/keywords/vocabulary.js +1 -0
  122. package/lib/keywords/writeOnly.js +4 -0
  123. package/lib/keywords.d.ts +19 -0
  124. package/lib/keywords.js +59 -0
  125. package/lib/media-types.d.ts +9 -0
  126. package/lib/media-types.js +26 -0
  127. package/lib/pubsub.js +42 -0
  128. package/lib/reference.d.ts +11 -0
  129. package/lib/reference.js +11 -0
  130. package/lib/schema.d.ts +64 -0
  131. package/lib/schema.js +308 -0
  132. package/package.json +31 -22
  133. package/{lib/draft-2020-12.d.ts → stable/index.d.ts} +26 -24
  134. package/stable/index.js +118 -0
  135. package/stable/meta/applicator.js +49 -0
  136. package/stable/meta/content.js +12 -0
  137. package/stable/meta/core.js +49 -0
  138. package/stable/meta/format-annotation.js +10 -0
  139. package/stable/meta/format-assertion.js +10 -0
  140. package/stable/meta/meta-data.js +16 -0
  141. package/stable/meta/unevaluated.js +11 -0
  142. package/stable/meta/validation.js +67 -0
  143. package/stable/validation.js +24 -0
  144. package/dist/json-schema-amd.js +0 -6602
  145. package/dist/json-schema-amd.js.map +0 -1
  146. package/dist/json-schema-amd.min.js +0 -3
  147. package/dist/json-schema-amd.min.js.map +0 -1
  148. package/dist/json-schema-cjs.js +0 -6600
  149. package/dist/json-schema-cjs.js.map +0 -1
  150. package/dist/json-schema-cjs.min.js +0 -3
  151. package/dist/json-schema-cjs.min.js.map +0 -1
  152. package/dist/json-schema-esm.js +0 -6596
  153. package/dist/json-schema-esm.js.map +0 -1
  154. package/dist/json-schema-esm.min.js +0 -3
  155. package/dist/json-schema-esm.min.js.map +0 -1
  156. package/dist/json-schema-iife.js +0 -6605
  157. package/dist/json-schema-iife.js.map +0 -1
  158. package/dist/json-schema-iife.min.js +0 -3
  159. package/dist/json-schema-iife.min.js.map +0 -1
  160. package/dist/json-schema-system.js +0 -6603
  161. package/dist/json-schema-system.js.map +0 -1
  162. package/dist/json-schema-system.min.js +0 -3
  163. package/dist/json-schema-system.min.js.map +0 -1
  164. package/dist/json-schema-umd.js +0 -6606
  165. package/dist/json-schema-umd.js.map +0 -1
  166. package/dist/json-schema-umd.min.js +0 -3
  167. package/dist/json-schema-umd.min.js.map +0 -1
  168. package/lib/draft-04.d.ts +0 -41
  169. package/lib/draft-04.js +0 -46
  170. package/lib/draft-06.d.ts +0 -45
  171. package/lib/draft-06.js +0 -51
  172. package/lib/draft-07.js +0 -55
  173. package/lib/draft-2019-09.js +0 -92
  174. package/lib/draft-2020-12.js +0 -103
  175. package/lib/index.mjs +0 -19
  176. package/lib/keywords/additionalItems.js +0 -27
  177. package/lib/keywords/additionalItems6.js +0 -23
  178. package/lib/keywords/additionalProperties6.js +0 -28
  179. package/lib/keywords/index.js +0 -53
  180. package/lib/keywords/items202012.js +0 -23
  181. package/lib/keywords/maximum-exclusiveMaximum.js +0 -20
  182. package/lib/keywords/minimum-exclusiveMinimum.js +0 -20
  183. package/lib/keywords/tupleItems.js +0 -24
  184. package/meta/draft/2019-09/meta/applicator.js +0 -55
  185. package/meta/draft/2019-09/meta/content.js +0 -17
  186. package/meta/draft/2019-09/meta/core.js +0 -57
  187. package/meta/draft/2019-09/meta/format.js +0 -14
  188. package/meta/draft/2019-09/meta/meta-data.js +0 -37
  189. package/meta/draft/2019-09/meta/validation.js +0 -98
  190. package/meta/draft/2019-09/schema.js +0 -42
  191. package/meta/draft/2020-12/meta/applicator.js +0 -49
  192. package/meta/draft/2020-12/meta/content.js +0 -17
  193. package/meta/draft/2020-12/meta/core.js +0 -57
  194. package/meta/draft/2020-12/meta/format-annotation.js +0 -14
  195. package/meta/draft/2020-12/meta/format-assertion.js +0 -14
  196. package/meta/draft/2020-12/meta/meta-data.js +0 -37
  197. package/meta/draft/2020-12/meta/unevaluated.js +0 -15
  198. package/meta/draft/2020-12/meta/validation.js +0 -98
  199. package/meta/draft/2020-12/schema.js +0 -44
  200. package/meta/draft-04/schema.js +0 -149
  201. package/meta/draft-06/schema.js +0 -154
  202. package/meta/draft-07/schema.js +0 -172
package/lib/core.js ADDED
@@ -0,0 +1,102 @@
1
+ import curry from "just-curry-it";
2
+ import * as PubSub from "./pubsub.js";
3
+ import * as Configuration from "./configuration.js";
4
+ import * as Instance from "./instance.js";
5
+ import { InvalidSchemaError } from "./invalid-schema-error.js";
6
+ import * as Schema from "./schema.js";
7
+ import Validation from "./keywords/validation.js";
8
+
9
+
10
+ export const FLAG = "FLAG", BASIC = "BASIC", DETAILED = "DETAILED", VERBOSE = "VERBOSE";
11
+ Configuration.setMetaSchemaOutputFormat(FLAG);
12
+
13
+ export const validate = async (url, value = undefined, outputFormat = undefined) => {
14
+ const compiled = await compile(url);
15
+ const interpretAst = (value, outputFormat) => interpret(compiled, Instance.cons(value), outputFormat);
16
+
17
+ return value === undefined ? interpretAst : interpretAst(value, outputFormat);
18
+ };
19
+
20
+ export const compile = async (url) => {
21
+ const schema = await Schema.get(url);
22
+ const ast = { metaData: {} };
23
+ const schemaUri = await Validation.compile(schema, ast);
24
+ return { ast, schemaUri };
25
+ };
26
+
27
+ export const interpret = curry(({ ast, schemaUri }, value, outputFormat = FLAG) => {
28
+ if (![FLAG, BASIC, DETAILED, VERBOSE].includes(outputFormat)) {
29
+ throw Error(`The '${outputFormat}' error format is not supported`);
30
+ }
31
+
32
+ const output = [];
33
+ const subscriptionToken = PubSub.subscribe("result", outputHandler(outputFormat, output));
34
+ Validation.interpret(schemaUri, value, ast, {});
35
+ PubSub.unsubscribe("result", subscriptionToken);
36
+
37
+ return output[0];
38
+ });
39
+
40
+ const outputHandler = (outputFormat, output) => {
41
+ const resultStack = [];
42
+
43
+ return (message, keywordResult) => {
44
+ if (message === "result") {
45
+ const { keyword, absoluteKeywordLocation, instanceLocation, valid } = keywordResult;
46
+ const result = { keyword, absoluteKeywordLocation, instanceLocation, valid, errors: [] };
47
+ resultStack.push(result);
48
+ } else if (message === "result.start") {
49
+ resultStack.push(message);
50
+ } else if (message === "result.end") {
51
+ const result = resultStack.pop();
52
+ while (resultStack[resultStack.length - 1] !== "result.start") {
53
+ const topResult = resultStack.pop();
54
+
55
+ const errors = [topResult];
56
+ if (outputFormat === BASIC) {
57
+ errors.push(...topResult.errors);
58
+ delete topResult.errors;
59
+ }
60
+
61
+ if (outputFormat === VERBOSE || (outputFormat !== FLAG && !topResult.valid)) {
62
+ result.errors.unshift(...errors);
63
+ }
64
+ }
65
+ resultStack[resultStack.length - 1] = result;
66
+
67
+ output[0] = result;
68
+ }
69
+ };
70
+ };
71
+
72
+ const metaValidators = {};
73
+ PubSub.subscribe("validate.metaValidate", async (message, schema) => {
74
+ if (Configuration.getShouldValidateSchema() && !schema.validated) {
75
+ Schema.markValidated(schema.id);
76
+
77
+ // Compile
78
+ if (!(schema.dialectId in metaValidators)) {
79
+ // Dynamic references are experimental, but are necessary for meta-validation
80
+ const dyanmicRefKeywordId = "https://json-schema.org/keyword/dynamicRef";
81
+ const isDynamicRefEnabled = Configuration.isExperimentalKeywordEnabled(dyanmicRefKeywordId);
82
+ Configuration.setExperimentalKeywordEnabled(dyanmicRefKeywordId, true);
83
+
84
+ const compiledSchema = await compile(schema.dialectId);
85
+ metaValidators[schema.dialectId] = interpret(compiledSchema);
86
+
87
+ Configuration.setExperimentalKeywordEnabled(dyanmicRefKeywordId, isDynamicRefEnabled);
88
+ }
89
+
90
+ // Interpret
91
+ const schemaInstance = Instance.cons(schema.schema, schema.id);
92
+ const metaResults = metaValidators[schema.dialectId](schemaInstance, Configuration.getMetaSchemaOutputFormat());
93
+ if (!metaResults.valid) {
94
+ throw new InvalidSchemaError(metaResults);
95
+ }
96
+ }
97
+ });
98
+
99
+ export const addSchema = (schema, url = undefined, defaultSchemaVersion = undefined) => {
100
+ const id = Schema.add(schema, url, defaultSchemaVersion);
101
+ delete metaValidators[id];
102
+ };
@@ -0,0 +1,8 @@
1
+ import type { Keyword } from "./keywords.js";
2
+
3
+
4
+ export { compile, interpret, BASIC, DETAILED, VERBOSE } from "./core.js";
5
+ export { isExperimentalKeywordEnabled, setExperimentalKeywordEnabled } from "./configuration.js";
6
+ export { getKeyword, addKeyword, defineVocabulary, getKeywordName, loadDialect } from "./keywords.js";
7
+ export type { Keyword } from "./keywords.js";
8
+ export const Validation: Keyword<string>;
@@ -0,0 +1,4 @@
1
+ export { compile, interpret, BASIC, DETAILED, VERBOSE } from "./core.js";
2
+ export { isExperimentalKeywordEnabled, setExperimentalKeywordEnabled } from "./configuration.js";
3
+ export { getKeyword, addKeyword, defineVocabulary, getKeywordName, loadDialect } from "./keywords.js";
4
+ export { default as Validation } from "./keywords/validation.js";
@@ -0,0 +1 @@
1
+ export default fetch;
package/lib/fetch.js ADDED
@@ -0,0 +1,19 @@
1
+ import fs from "fs/promises";
2
+ import fetch, { Response } from "node-fetch";
3
+ import Url from "url";
4
+ import * as MediaTypes from "./media-types.js";
5
+
6
+
7
+ export default async (url, options) => {
8
+ if (url.startsWith("file://")) {
9
+ const filePath = Url.fileURLToPath(url);
10
+ const fd = await fs.open(filePath);
11
+ const stream = fd.createReadStream();
12
+ return new Response(stream, {
13
+ url: url,
14
+ headers: { "Content-Type": MediaTypes.getContentType(filePath) }
15
+ });
16
+ } else {
17
+ return fetch(url, options);
18
+ }
19
+ };
package/lib/index.d.ts CHANGED
@@ -1,42 +1,11 @@
1
- import type { Core, Schema, Keywords, InvalidSchemaError } from "@hyperjump/json-schema-core";
2
-
3
-
4
- export type JsonSchema = {
5
- add: typeof Schema.add;
6
- get: typeof Schema.get;
7
- validate: typeof Core.validate;
8
- compile: typeof Core.compile;
9
- interpret: typeof Core.interpret;
10
- setMetaOutputFormat: typeof Core.setMetaOutputFormat;
11
- setShouldMetaValidate: typeof Core.setShouldMetaValidate;
12
- addMediaTypePlugin: typeof Core.addMediaTypePlugin;
13
- FLAG: typeof Core.FLAG;
14
- BASIC: typeof Core.BASIC;
15
- DETAILED: typeof Core.DETAILED;
16
- VERBOSE: typeof Core.VERBOSE;
17
- Keywords: typeof Keywords;
18
- InvalidSchemaError: typeof InvalidSchemaError;
19
- };
20
-
21
- export const add: JsonSchema["add"];
22
- export const get: JsonSchema["get"];
23
- export const validate: JsonSchema["validate"];
24
- export const compile: JsonSchema["compile"];
25
- export const interpret: JsonSchema["interpret"];
26
- export const setMetaOutputFormat: JsonSchema["setMetaOutputFormat"];
27
- export const setShouldMetaValidate: JsonSchema["setShouldMetaValidate"];
28
- export const addMediaTypePlugin: JsonSchema["addMediaTypePlugin"];
29
- export const FLAG: JsonSchema["FLAG"];
30
- export const BASIC: JsonSchema["BASIC"];
31
- export const DETAILED: JsonSchema["DETAILED"];
32
- export const VERBOSE: JsonSchema["VERBOSE"];
33
-
34
- export * from "@hyperjump/json-schema-core";
35
- export * from "./draft-04";
36
- export * from "./draft-06";
37
- export * from "./draft-07";
38
- export * from "./draft-2019-09";
39
- export * from "./draft-2020-12";
40
-
41
- declare const jsonSchema: JsonSchema;
42
- export default jsonSchema;
1
+ export { addSchema, validate, FLAG } from "./core.js";
2
+ export type { Validator, OutputFormat, CompiledSchema, Result } from "./core.js";
3
+ export {
4
+ getMetaSchemaOutputFormat,
5
+ setMetaSchemaOutputFormat,
6
+ getShouldValidateSchema,
7
+ setShouldValidateSchema
8
+ } from "./configuration.js";
9
+ export { InvalidSchemaError } from "./invalid-schema-error.js";
10
+ export { addMediaTypePlugin } from "./media-types.js";
11
+ export type { MediaTypePlugin } from "./media-types.js";
package/lib/index.js CHANGED
@@ -1,27 +1,134 @@
1
- const { Core, Schema, InvalidSchemaError } = require("@hyperjump/json-schema-core");
2
- const Keywords = require("./keywords");
1
+ import { addKeyword } from "./keywords.js";
2
+ import { addMediaTypePlugin } from "./media-types.js";
3
3
 
4
- require("./draft-04");
5
- require("./draft-06");
6
- require("./draft-07");
7
- require("./draft-2019-09");
8
- require("./draft-2020-12");
4
+ import additionalProperties from "./keywords/additionalProperties.js";
5
+ import allOf from "./keywords/allOf.js";
6
+ import anchor from "./keywords/anchor.js";
7
+ import anyOf from "./keywords/anyOf.js";
8
+ import const_ from "./keywords/const.js";
9
+ import contains from "./keywords/contains.js";
10
+ import comment from "./keywords/comment.js";
11
+ import contentEncoding from "./keywords/contentEncoding.js";
12
+ import contentMediaType from "./keywords/contentMediaType.js";
13
+ import contentSchema from "./keywords/contentSchema.js";
14
+ import default_ from "./keywords/default.js";
15
+ import definitions from "./keywords/definitions.js";
16
+ import dependentRequired from "./keywords/dependentRequired.js";
17
+ import dependentSchemas from "./keywords/dependentSchemas.js";
18
+ import deprecated from "./keywords/deprecated.js";
19
+ import description from "./keywords/description.js";
20
+ import dynamicAnchor from "./keywords/dynamicAnchor.js";
21
+ import dynamicRef from "./keywords/dynamicRef.js";
22
+ import else_ from "./keywords/else.js";
23
+ import enum_ from "./keywords/enum.js";
24
+ import examples from "./keywords/examples.js";
25
+ import exclusiveMaximum from "./keywords/exclusiveMaximum.js";
26
+ import exclusiveMinimum from "./keywords/exclusiveMinimum.js";
27
+ import format from "./keywords/format.js";
28
+ import id from "./keywords/id.js";
29
+ import if_ from "./keywords/if.js";
30
+ import items from "./keywords/items.js";
31
+ import maxContains from "./keywords/maxContains.js";
32
+ import maxItems from "./keywords/maxItems.js";
33
+ import maxLength from "./keywords/maxLength.js";
34
+ import maxProperties from "./keywords/maxProperties.js";
35
+ import maximum from "./keywords/maximum.js";
36
+ import minContains from "./keywords/minContains.js";
37
+ import minItems from "./keywords/minItems.js";
38
+ import minLength from "./keywords/minLength.js";
39
+ import minProperties from "./keywords/minProperties.js";
40
+ import minimum from "./keywords/minimum.js";
41
+ import multipleOf from "./keywords/multipleOf.js";
42
+ import not from "./keywords/not.js";
43
+ import oneOf from "./keywords/oneOf.js";
44
+ import pattern from "./keywords/pattern.js";
45
+ import patternProperties from "./keywords/patternProperties.js";
46
+ import prefixItems from "./keywords/prefixItems.js";
47
+ import properties from "./keywords/properties.js";
48
+ import propertyDependencies from "./keywords/propertyDependencies.js";
49
+ import propertyNames from "./keywords/propertyNames.js";
50
+ import readOnly from "./keywords/readOnly.js";
51
+ import ref from "./keywords/ref.js";
52
+ import requireAllExcept from "./keywords/requireAllExcept.js";
53
+ import required from "./keywords/required.js";
54
+ import title from "./keywords/title.js";
55
+ import then from "./keywords/then.js";
56
+ import type from "./keywords/type.js";
57
+ import unevaluatedItems from "./keywords/unevaluatedItems.js";
58
+ import unevaluatedProperties from "./keywords/unevaluatedProperties.js";
59
+ import uniqueItems from "./keywords/uniqueItems.js";
60
+ import vocabulary from "./keywords/vocabulary.js";
61
+ import writeOnly from "./keywords/writeOnly.js";
9
62
 
10
63
 
11
- module.exports = {
12
- add: Core.add,
13
- get: Schema.get,
14
- validate: Core.validate,
15
- compile: Core.compile,
16
- interpret: Core.interpret,
17
- setMetaOutputFormat: Core.setMetaOutputFormat,
18
- setShouldMetaValidate: Core.setShouldMetaValidate,
19
- addMediaTypePlugin: Core.addMediaTypePlugin,
20
- FLAG: Core.FLAG,
21
- BASIC: Core.BASIC,
22
- DETAILED: Core.DETAILED,
23
- VERBOSE: Core.VERBOSE,
24
- Keywords: Keywords,
25
- InvalidSchemaError: InvalidSchemaError
26
- };
64
+ addMediaTypePlugin("application/schema+json", {
65
+ parse: async (response, contentTypeParameters) => [
66
+ await response.json(),
67
+ contentTypeParameters.schema || contentTypeParameters.profile
68
+ ],
69
+ matcher: (path) => path.endsWith(".schema.json")
70
+ });
27
71
 
72
+ addKeyword(additionalProperties);
73
+ addKeyword(allOf);
74
+ addKeyword(anchor);
75
+ addKeyword(anyOf);
76
+ addKeyword(const_);
77
+ addKeyword(contains);
78
+ addKeyword(comment);
79
+ addKeyword(contentEncoding);
80
+ addKeyword(contentMediaType);
81
+ addKeyword(contentSchema);
82
+ addKeyword(default_);
83
+ addKeyword(definitions);
84
+ addKeyword(dependentRequired);
85
+ addKeyword(dependentSchemas);
86
+ addKeyword(deprecated);
87
+ addKeyword(description);
88
+ addKeyword(dynamicAnchor);
89
+ addKeyword(dynamicRef);
90
+ addKeyword(else_);
91
+ addKeyword(enum_);
92
+ addKeyword(examples);
93
+ addKeyword(exclusiveMaximum);
94
+ addKeyword(exclusiveMinimum);
95
+ addKeyword(format);
96
+ addKeyword(id);
97
+ addKeyword(if_);
98
+ addKeyword(items);
99
+ addKeyword(maxContains);
100
+ addKeyword(maxItems);
101
+ addKeyword(maxLength);
102
+ addKeyword(maxProperties);
103
+ addKeyword(maximum);
104
+ addKeyword(minContains);
105
+ addKeyword(minItems);
106
+ addKeyword(minLength);
107
+ addKeyword(minProperties);
108
+ addKeyword(minimum);
109
+ addKeyword(multipleOf);
110
+ addKeyword(not);
111
+ addKeyword(oneOf);
112
+ addKeyword(pattern);
113
+ addKeyword(patternProperties);
114
+ addKeyword(prefixItems);
115
+ addKeyword(properties);
116
+ addKeyword(propertyDependencies);
117
+ addKeyword(propertyNames);
118
+ addKeyword(readOnly);
119
+ addKeyword(ref);
120
+ addKeyword(requireAllExcept);
121
+ addKeyword(required);
122
+ addKeyword(title);
123
+ addKeyword(then);
124
+ addKeyword(type);
125
+ addKeyword(unevaluatedItems);
126
+ addKeyword(unevaluatedProperties);
127
+ addKeyword(uniqueItems);
128
+ addKeyword(vocabulary);
129
+ addKeyword(writeOnly);
130
+
131
+ export { addSchema, validate, FLAG } from "./core.js";
132
+ export { getMetaSchemaOutputFormat, setMetaSchemaOutputFormat, getShouldValidateSchema, setShouldValidateSchema } from "./configuration.js";
133
+ export { InvalidSchemaError } from "./invalid-schema-error.js";
134
+ export { addMediaTypePlugin } from "./media-types.js";
@@ -0,0 +1,75 @@
1
+ import type { JsonType } from "./common.js";
2
+ import type { Json, JsonObject } from "@hyperjump/json-pointer";
3
+
4
+
5
+ export const nil: JsonDocument<undefined>;
6
+ export const cons: (instance: Json, id?: string) => JsonDocument;
7
+ export const get: (url: string, context?: JsonDocument) => JsonDocument;
8
+ export const uri: (doc: JsonDocument) => string;
9
+ export const value: <A extends Json>(doc: JsonDocument<A>) => A;
10
+ export const has: (key: string, doc: JsonDocument<JsonObject>) => boolean;
11
+ export const typeOf: (
12
+ (doc: JsonDocument, type: "null") => doc is JsonDocument<null>
13
+ ) & (
14
+ (doc: JsonDocument, type: "boolean") => doc is JsonDocument<boolean>
15
+ ) & (
16
+ (doc: JsonDocument, type: "object") => doc is JsonDocument<JsonObject>
17
+ ) & (
18
+ (doc: JsonDocument, type: "array") => doc is JsonDocument<Json[]>
19
+ ) & (
20
+ (doc: JsonDocument, type: "number" | "integer") => doc is JsonDocument<number>
21
+ ) & (
22
+ (doc: JsonDocument, type: "string") => doc is JsonDocument<string>
23
+ ) & (
24
+ (doc: JsonDocument, type: JsonType) => boolean
25
+ ) & (
26
+ (doc: JsonDocument) => (type: JsonType) => boolean
27
+ );
28
+ export const step: (key: string, doc: JsonDocument<JsonObject | Json[]>) => JsonDocument<typeof doc.value>;
29
+ export const entries: (doc: JsonDocument<JsonObject>) => [string, JsonDocument][];
30
+ export const keys: (doc: JsonDocument<JsonObject>) => string[];
31
+ export const map: (
32
+ <A>(fn: MapFn<A>, doc: JsonDocument<Json[]>) => A[]
33
+ ) & (
34
+ <A>(fn: MapFn<A>) => (doc: JsonDocument<Json[]>) => A[]
35
+ );
36
+ export const forEach: (
37
+ (fn: ForEachFn, doc: JsonDocument<Json[]>) => void
38
+ ) & (
39
+ (fn: ForEachFn) => (doc: JsonDocument<Json[]>) => void
40
+ );
41
+ export const filter: (
42
+ (fn: FilterFn, doc: JsonDocument<Json[]>) => JsonDocument[]
43
+ ) & (
44
+ (fn: FilterFn) => (doc: JsonDocument<Json[]>) => JsonDocument[]
45
+ );
46
+ export const reduce: (
47
+ <A>(fn: ReduceFn<A>, acc: A, doc: JsonDocument<Json[]>) => A
48
+ ) & (
49
+ <A>(fn: ReduceFn<A>) => (acc: A, doc: JsonDocument<Json[]>) => A
50
+ ) & (
51
+ <A>(fn: ReduceFn<A>) => (acc: A) => (doc: JsonDocument<Json[]>) => A
52
+ );
53
+ export const every: (
54
+ (fn: FilterFn, doc: JsonDocument<Json[]>) => boolean
55
+ ) & (
56
+ (fn: FilterFn) => (doc: JsonDocument<Json[]>) => boolean
57
+ );
58
+ export const some: (
59
+ (fn: FilterFn, doc: JsonDocument<Json[]>) => boolean
60
+ ) & (
61
+ (fn: FilterFn) => (doc: JsonDocument<Json[]>) => boolean
62
+ );
63
+ export const length: (doc: JsonDocument<Json[] | string>) => number;
64
+
65
+ type MapFn<A> = (element: JsonDocument, index: number) => A;
66
+ type ForEachFn = (element: JsonDocument, index: number) => void;
67
+ type FilterFn = (element: JsonDocument, index: number) => boolean;
68
+ type ReduceFn<A> = (accumulator: A, currentValue: JsonDocument, index: number) => A;
69
+
70
+ export type JsonDocument<A extends Json | undefined = Json> = {
71
+ id: string;
72
+ pointer: string;
73
+ instance: Json;
74
+ value: A;
75
+ };
@@ -0,0 +1,58 @@
1
+ import * as JsonPointer from "@hyperjump/json-pointer";
2
+ import curry from "just-curry-it";
3
+ import { resolveUrl, jsonTypeOf } from "./common.js";
4
+ import * as Reference from "./reference.js";
5
+
6
+
7
+ export const nil = Object.freeze({ id: undefined, pointer: "", instance: undefined, value: undefined });
8
+ export const cons = (instance, id = undefined) => Object.freeze({
9
+ ...nil,
10
+ id: id ? resolveUrl("", id) : "",
11
+ instance,
12
+ value: instance
13
+ });
14
+
15
+ export const get = (url, instance = nil) => {
16
+ if (!url.startsWith("#")) {
17
+ throw Error(`No JSON document found at '${url.split("#")[0]}'`);
18
+ }
19
+
20
+ return Object.freeze({ ...instance, pointer: url.substr(1) });
21
+ };
22
+
23
+ export const uri = (doc) => `${doc.id || ""}#${encodeURI(doc.pointer)}`;
24
+ export const value = (doc) => Reference.isReference(doc.value) ? Reference.value(doc.value) : doc.value;
25
+ export const has = (key, doc) => key in value(doc);
26
+ export const typeOf = curry((doc, type) => jsonTypeOf(value(doc), type));
27
+
28
+ export const step = (key, doc) => Object.freeze({
29
+ ...doc,
30
+ pointer: JsonPointer.append(key, doc.pointer),
31
+ value: value(doc)[key]
32
+ });
33
+
34
+ export const entries = (doc) => Object.keys(value(doc))
35
+ .map((key) => [key, step(key, doc)]);
36
+
37
+ export const keys = (doc) => Object.keys(value(doc));
38
+
39
+ export const map = curry((fn, doc) => value(doc)
40
+ .map((item, ndx, array, thisArg) => fn(step(ndx, doc), ndx, array, thisArg)));
41
+
42
+ export const forEach = curry((fn, doc) => value(doc)
43
+ .forEach((item, ndx, array, thisArg) => fn(step(ndx, doc), ndx, array, thisArg)));
44
+
45
+ export const filter = curry((fn, doc) => value(doc)
46
+ .map((item, ndx, array, thisArg) => step(ndx, doc, array, thisArg))
47
+ .filter((item, ndx, array, thisArg) => fn(item, ndx, array, thisArg)));
48
+
49
+ export const reduce = curry((fn, acc, doc) => value(doc)
50
+ .reduce((acc, item, ndx) => fn(acc, step(ndx, doc), ndx), acc));
51
+
52
+ export const every = curry((fn, doc) => value(doc)
53
+ .every((item, ndx, array, thisArg) => fn(step(ndx, doc), ndx, array, thisArg)));
54
+
55
+ export const some = curry((fn, doc) => value(doc)
56
+ .some((item, ndx, array, thisArg) => fn(step(ndx, doc), ndx, array, thisArg)));
57
+
58
+ export const length = (doc) => value(doc).length;
@@ -0,0 +1,8 @@
1
+ import type { Result } from "./core.js";
2
+
3
+
4
+ export class InvalidSchemaError extends Error {
5
+ public output: Result;
6
+
7
+ public constructor(output: Result);
8
+ }
@@ -0,0 +1,7 @@
1
+ export class InvalidSchemaError extends Error {
2
+ constructor(output) {
3
+ super("Invalid Schema");
4
+ this.name = this.constructor.name;
5
+ this.output = output;
6
+ }
7
+ }
@@ -1,18 +1,21 @@
1
- const { Core, Schema, Instance } = require("@hyperjump/json-schema-core");
1
+ import * as Schema from "../schema.js";
2
+ import * as Instance from "../instance.js";
3
+ import { getKeywordName } from "../keywords.js";
4
+ import Validation from "./validation.js";
2
5
 
3
6
 
7
+ const id = "https://json-schema.org/keyword/additionalProperties";
8
+
4
9
  const compile = async (schema, ast, parentSchema) => {
5
- const properties = await Schema.step("properties", parentSchema);
6
- const propertyNames = Schema.typeOf(properties, "object") ? Schema.keys(properties) : [];
10
+ const propertiesKeyword = getKeywordName(schema.dialectId, "https://json-schema.org/keyword/properties");
11
+ const propertiesSchema = await Schema.step(propertiesKeyword, parentSchema);
12
+ const propertyNames = Schema.typeOf(propertiesSchema, "object") ? Schema.keys(propertiesSchema) : [];
7
13
 
8
- const patternProperties = await Schema.step("patternProperties", parentSchema);
14
+ const patternPropertiesKeyword = getKeywordName(schema.dialectId, "https://json-schema.org/keyword/patternProperties");
15
+ const patternProperties = await Schema.step(patternPropertiesKeyword, parentSchema);
9
16
  const propertyNamePatterns = Schema.typeOf(patternProperties, "object") ? Schema.keys(patternProperties).map((pattern) => new RegExp(pattern)) : [];
10
17
 
11
- if (Schema.typeOf(schema, "boolean")) {
12
- return [propertyNames, propertyNamePatterns, Schema.value(schema)];
13
- } else {
14
- return [propertyNames, propertyNamePatterns, await Core.compileSchema(schema, ast)];
15
- }
18
+ return [propertyNames, propertyNamePatterns, await Validation.compile(schema, ast)];
16
19
  };
17
20
 
18
21
  const interpret = ([propertyNames, propertyNamePatterns, additionalProperties], instance, ast, dynamicAnchors) => {
@@ -20,14 +23,13 @@ const interpret = ([propertyNames, propertyNamePatterns, additionalProperties],
20
23
  return true;
21
24
  }
22
25
 
23
- const properties = Instance.entries(instance)
24
- .filter(([propertyName]) => !propertyNames.includes(propertyName) && !propertyNamePatterns.some((pattern) => pattern.test(propertyName)));
26
+ return Instance.entries(instance)
27
+ .filter(([propertyName]) => !propertyNames.includes(propertyName) && !propertyNamePatterns.some((pattern) => pattern.test(propertyName)))
28
+ .every(([, property]) => Validation.interpret(additionalProperties, property, ast, dynamicAnchors));
29
+ };
25
30
 
26
- if (typeof additionalProperties === "string") {
27
- return properties.every(([, property]) => Core.interpretSchema(additionalProperties, property, ast, dynamicAnchors));
28
- } else {
29
- return properties.length === 0 || additionalProperties;
30
- }
31
+ const collectEvaluatedProperties = (keywordValue, instance, ast, dynamicAnchors) => {
32
+ return interpret(keywordValue, instance, ast, dynamicAnchors) && [new RegExp("")];
31
33
  };
32
34
 
33
- module.exports = { compile, interpret };
35
+ export default { id, compile, interpret, collectEvaluatedProperties };
@@ -1,28 +1,31 @@
1
- const { Core, Schema } = require("@hyperjump/json-schema-core");
2
- const Pact = require("@hyperjump/pact");
1
+ import * as Pact from "@hyperjump/pact";
2
+ import * as Schema from "../schema.js";
3
+ import Validation from "./validation.js";
3
4
 
4
5
 
6
+ const id = "https://json-schema.org/keyword/allOf";
7
+
5
8
  const compile = (schema, ast) => Pact.pipeline([
6
- Schema.map(async (itemSchema) => Core.compileSchema(await itemSchema, ast)),
9
+ Schema.map(async (itemSchema) => Validation.compile(await itemSchema, ast)),
7
10
  Pact.all
8
11
  ], schema);
9
12
 
10
13
  const interpret = (allOf, instance, ast, dynamicAnchors) => {
11
- return allOf.every((schemaUrl) => Core.interpretSchema(schemaUrl, instance, ast, dynamicAnchors));
14
+ return allOf.every((schemaUrl) => Validation.interpret(schemaUrl, instance, ast, dynamicAnchors));
12
15
  };
13
16
 
14
17
  const collectEvaluatedProperties = (allOf, instance, ast, dynamicAnchors) => {
15
18
  return allOf.reduce((acc, schemaUrl) => {
16
- const propertyNames = acc && Core.collectEvaluatedProperties(schemaUrl, instance, ast, dynamicAnchors);
19
+ const propertyNames = acc && Validation.collectEvaluatedProperties(schemaUrl, instance, ast, dynamicAnchors);
17
20
  return propertyNames !== false && [...acc, ...propertyNames];
18
21
  }, []);
19
22
  };
20
23
 
21
24
  const collectEvaluatedItems = (allOf, instance, ast, dynamicAnchors) => {
22
25
  return allOf.reduce((acc, schemaUrl) => {
23
- const itemIndexes = acc !== false && Core.collectEvaluatedItems(schemaUrl, instance, ast, dynamicAnchors);
26
+ const itemIndexes = acc !== false && Validation.collectEvaluatedItems(schemaUrl, instance, ast, dynamicAnchors);
24
27
  return itemIndexes !== false && new Set([...acc, ...itemIndexes]);
25
28
  }, new Set());
26
29
  };
27
30
 
28
- module.exports = { compile, interpret, collectEvaluatedProperties, collectEvaluatedItems };
31
+ export default { id, compile, interpret, collectEvaluatedProperties, collectEvaluatedItems };
@@ -0,0 +1 @@
1
+ export default { id: "https://json-schema.org/keyword/anchor" };
@@ -1,29 +1,32 @@
1
- const { Core, Schema } = require("@hyperjump/json-schema-core");
2
- const Pact = require("@hyperjump/pact");
1
+ import * as Pact from "@hyperjump/pact";
2
+ import * as Schema from "../schema.js";
3
+ import Validation from "./validation.js";
3
4
 
4
5
 
6
+ const id = "https://json-schema.org/keyword/anyOf";
7
+
5
8
  const compile = (schema, ast) => Pact.pipeline([
6
- Schema.map(async (itemSchema) => Core.compileSchema(await itemSchema, ast)),
9
+ Schema.map(async (itemSchema) => Validation.compile(await itemSchema, ast)),
7
10
  Pact.all
8
11
  ], schema);
9
12
 
10
13
  const interpret = (anyOf, instance, ast, dynamicAnchors) => {
11
- const matches = anyOf.filter((schemaUrl) => Core.interpretSchema(schemaUrl, instance, ast, dynamicAnchors));
14
+ const matches = anyOf.filter((schemaUrl) => Validation.interpret(schemaUrl, instance, ast, dynamicAnchors));
12
15
  return matches.length > 0;
13
16
  };
14
17
 
15
18
  const collectEvaluatedProperties = (anyOf, instance, ast, dynamicAnchors) => {
16
19
  return anyOf.reduce((acc, schemaUrl) => {
17
- const propertyNames = Core.collectEvaluatedProperties(schemaUrl, instance, ast, dynamicAnchors);
20
+ const propertyNames = Validation.collectEvaluatedProperties(schemaUrl, instance, ast, dynamicAnchors);
18
21
  return propertyNames !== false ? [...acc || [], ...propertyNames] : acc;
19
22
  }, false);
20
23
  };
21
24
 
22
25
  const collectEvaluatedItems = (anyOf, instance, ast, dynamicAnchors) => {
23
26
  return anyOf.reduce((acc, schemaUrl) => {
24
- const itemIndexes = Core.collectEvaluatedItems(schemaUrl, instance, ast, dynamicAnchors);
27
+ const itemIndexes = Validation.collectEvaluatedItems(schemaUrl, instance, ast, dynamicAnchors);
25
28
  return itemIndexes !== false ? new Set([...acc || [], ...itemIndexes]) : acc;
26
29
  }, false);
27
30
  };
28
31
 
29
- module.exports = { compile, interpret, collectEvaluatedProperties, collectEvaluatedItems };
32
+ export default { id, compile, interpret, collectEvaluatedProperties, collectEvaluatedItems };
@@ -0,0 +1,4 @@
1
+ import metaData from "./meta-data.js";
2
+
3
+
4
+ export default { id: "https://json-schema.org/keyword/comment", ...metaData };