json-schema-library 5.2.1 → 6.1.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 (115) hide show
  1. package/.prettierignore +1 -0
  2. package/.prettierrc +7 -0
  3. package/README.md +9 -8
  4. package/dist/index.d.ts +13 -44
  5. package/dist/jsonSchemaLibrary.js +1 -1
  6. package/dist/lib/addValidator.d.ts +2 -1
  7. package/dist/lib/compile/index.d.ts +11 -0
  8. package/dist/lib/config/strings.d.ts +1 -39
  9. package/dist/lib/cores/CoreInterface.d.ts +28 -9
  10. package/dist/lib/cores/Draft04.d.ts +2 -2
  11. package/dist/lib/cores/Draft06.d.ts +15 -0
  12. package/dist/lib/cores/Draft07.d.ts +15 -0
  13. package/dist/lib/cores/JsonEditor.d.ts +2 -2
  14. package/dist/lib/draft06/addSchema.d.ts +7 -0
  15. package/dist/lib/draft06/compile/index.d.ts +15 -0
  16. package/dist/lib/draft06/validation/keyword.d.ts +3 -0
  17. package/dist/lib/draft06/validation/type.d.ts +17 -0
  18. package/dist/lib/draft06/validation/typeKeywordMapping.d.ts +13 -0
  19. package/dist/lib/getChildSchemaSelection.d.ts +7 -5
  20. package/dist/lib/getSchema.d.ts +1 -1
  21. package/dist/lib/getTemplate.d.ts +5 -1
  22. package/dist/lib/getTypeOf.d.ts +2 -1
  23. package/dist/lib/schema/getTypeId.d.ts +1 -1
  24. package/dist/lib/step.d.ts +4 -4
  25. package/dist/lib/types.d.ts +10 -2
  26. package/dist/lib/utils/filter.d.ts +0 -1
  27. package/dist/lib/utils/merge.d.ts +3 -0
  28. package/dist/lib/validate.d.ts +1 -1
  29. package/dist/lib/validation/format.d.ts +6 -0
  30. package/dist/lib/validation/keyword.d.ts +2 -27
  31. package/dist/lib/validation/type.d.ts +3 -10
  32. package/dist/lib/validation/typeKeywordMapping.d.ts +4 -4
  33. package/dist/module/index.js +13 -6
  34. package/dist/module/lib/addValidator.js +3 -4
  35. package/dist/module/lib/compile/getRef.js +1 -1
  36. package/dist/module/lib/compile/index.js +11 -0
  37. package/dist/module/lib/config/strings.js +15 -2
  38. package/dist/module/lib/cores/CoreInterface.js +22 -0
  39. package/dist/module/lib/cores/Draft06.js +61 -0
  40. package/dist/module/lib/cores/Draft07.js +61 -0
  41. package/dist/module/lib/createSchemaOf.js +1 -1
  42. package/dist/module/lib/draft06/addSchema.js +11 -0
  43. package/dist/module/lib/draft06/compile/index.js +65 -0
  44. package/dist/module/lib/draft06/validation/keyword.js +156 -0
  45. package/dist/module/lib/draft06/validation/type.js +30 -0
  46. package/dist/module/lib/draft06/validation/typeKeywordMapping.js +15 -0
  47. package/dist/module/lib/each.js +1 -1
  48. package/dist/module/lib/eachSchema.js +3 -3
  49. package/dist/module/lib/getChildSchemaSelection.js +7 -6
  50. package/dist/module/lib/getSchema.js +2 -1
  51. package/dist/module/lib/getTemplate.js +57 -23
  52. package/dist/module/lib/resolveAllOf.js +3 -4
  53. package/dist/module/lib/resolveOneOf.fuzzy.js +13 -3
  54. package/dist/module/lib/resolveOneOf.strict.js +11 -2
  55. package/dist/module/lib/resolveRef.strict.js +8 -0
  56. package/dist/module/lib/schema/getTypeDefs.js +12 -1
  57. package/dist/module/lib/schema/getTypeId.js +1 -1
  58. package/dist/module/lib/step.js +62 -11
  59. package/dist/module/lib/types.js +7 -1
  60. package/dist/module/lib/utils/filter.js +3 -5
  61. package/dist/module/lib/utils/merge.js +3 -0
  62. package/dist/module/lib/validate.js +33 -8
  63. package/dist/module/lib/validateAsync.js +7 -7
  64. package/dist/module/lib/validation/errors.js +15 -2
  65. package/dist/module/lib/validation/format.js +105 -4
  66. package/dist/module/lib/validation/keyword.js +77 -30
  67. package/dist/module/lib/validation/type.js +2 -1
  68. package/dist/module/remotes/draft06.json +155 -0
  69. package/dist/module/remotes/draft07.json +172 -0
  70. package/dist/module/remotes/index.js +0 -1
  71. package/dist/remotes/index.d.ts +0 -1
  72. package/index.ts +14 -5
  73. package/lib/addValidator.ts +5 -5
  74. package/lib/compile/getRef.ts +1 -1
  75. package/lib/compile/index.ts +11 -1
  76. package/lib/config/strings.ts +17 -3
  77. package/lib/cores/CoreInterface.ts +37 -10
  78. package/lib/cores/Draft04.ts +2 -4
  79. package/lib/cores/Draft06.ts +76 -0
  80. package/lib/cores/Draft07.ts +75 -0
  81. package/lib/cores/JsonEditor.ts +2 -4
  82. package/lib/createSchemaOf.ts +1 -3
  83. package/lib/draft06/addSchema.ts +14 -0
  84. package/lib/draft06/compile/index.ts +68 -0
  85. package/lib/draft06/validation/keyword.ts +177 -0
  86. package/lib/draft06/validation/type.ts +43 -0
  87. package/lib/draft06/validation/typeKeywordMapping.ts +15 -0
  88. package/lib/each.ts +8 -3
  89. package/lib/eachSchema.ts +3 -3
  90. package/lib/getChildSchemaSelection.ts +14 -7
  91. package/lib/getSchema.ts +15 -7
  92. package/lib/getTemplate.ts +148 -38
  93. package/lib/getTypeOf.ts +2 -1
  94. package/lib/resolveAllOf.ts +9 -5
  95. package/lib/resolveOneOf.fuzzy.ts +25 -8
  96. package/lib/resolveOneOf.strict.ts +17 -4
  97. package/lib/resolveRef.strict.ts +9 -0
  98. package/lib/schema/getTypeDefs.ts +14 -1
  99. package/lib/schema/getTypeId.ts +2 -2
  100. package/lib/step.ts +103 -22
  101. package/lib/types.ts +21 -4
  102. package/lib/utils/filter.ts +4 -6
  103. package/lib/utils/merge.ts +4 -0
  104. package/lib/validate.ts +45 -15
  105. package/lib/validateAsync.ts +13 -12
  106. package/lib/validation/errors.ts +15 -2
  107. package/lib/validation/format.ts +113 -4
  108. package/lib/validation/keyword.ts +147 -78
  109. package/lib/validation/type.ts +5 -1
  110. package/package.json +73 -63
  111. package/remotes/draft06.json +155 -0
  112. package/remotes/draft07.json +172 -0
  113. package/remotes/draft2019-09.json +86 -0
  114. package/remotes/index.ts +0 -2
  115. package/tsconfig.json +2 -9
package/index.ts CHANGED
@@ -1,24 +1,28 @@
1
- import strings from "./lib/config/strings";
2
- import Interface from "./lib/cores/CoreInterface";
3
- import Draft04 from "./lib/cores/Draft04";
4
- import JsonEditor from "./lib/cores/JsonEditor";
5
1
  import addSchema from "./lib/addSchema";
6
2
  import addValidator from "./lib/addValidator";
7
3
  import compileSchema from "./lib/compileSchema";
8
4
  import createCustomError from "./lib/utils/createCustomError";
9
5
  import createSchemaOf from "./lib/createSchemaOf";
6
+ import Draft04 from "./lib/cores/Draft04";
7
+ import Draft06 from "./lib/cores/Draft06";
8
+ import Draft07 from "./lib/cores/Draft07";
10
9
  import each from "./lib/each";
11
10
  import eachSchema from "./lib/eachSchema";
12
11
  import getChildSchemaSelection from "./lib/getChildSchemaSelection";
13
12
  import getSchema from "./lib/getSchema";
14
13
  import getTemplate from "./lib/getTemplate";
15
14
  import getTypeOf from "./lib/getTypeOf";
15
+ import Interface from "./lib/cores/CoreInterface";
16
16
  import isValid from "./lib/isValid";
17
+ import JsonEditor from "./lib/cores/JsonEditor";
18
+ import resolveOneOf from "./lib/resolveOneOf.strict";
19
+ import resolveOneOfFuzzy from "./lib/resolveOneOf.fuzzy";
17
20
  import SchemaService from "./lib/SchemaService";
21
+ import settings from "./lib/config/settings";
18
22
  import step from "./lib/step";
23
+ import strings from "./lib/config/strings";
19
24
  import validate from "./lib/validate";
20
25
  import validateAsync from "./lib/validateAsync";
21
- import settings from "./lib/config/settings";
22
26
 
23
27
  const config = { strings };
24
28
 
@@ -26,6 +30,8 @@ export {
26
30
  config,
27
31
  Interface,
28
32
  Draft04, // core implementing draft04 specs
33
+ Draft06, // core implementing draft06 specs
34
+ Draft07, // core implementing draft07 specs
29
35
  JsonEditor, // adjusted core of draft04 to better support the json-editor
30
36
  addSchema, // add a schema to be references via $ref
31
37
  addValidator, // add validation for keyword, format, datatype and customize errors
@@ -39,6 +45,8 @@ export {
39
45
  getTemplate, // create data which is valid to the given schema
40
46
  getTypeOf, // returns the javascript datatype
41
47
  isValid, // returns a boolean if the schema is valid
48
+ resolveOneOf,
49
+ resolveOneOfFuzzy,
42
50
  settings,
43
51
  SchemaService,
44
52
  step, // steps into a json-schema, returning the matching child-schema
@@ -47,3 +55,4 @@ export {
47
55
  };
48
56
 
49
57
  export type { JSONSchema, JSONPointer, JSONError, JSONValidator } from "./lib/types";
58
+ export { isJSONError } from "./lib/types";
@@ -1,5 +1,6 @@
1
1
  import Core from "./cores/CoreInterface";
2
2
  import { JSONValidator } from "./types";
3
+ import { CreateError } from "./utils/createCustomError";
3
4
 
4
5
 
5
6
  /**
@@ -10,7 +11,7 @@ import { JSONValidator } from "./types";
10
11
  * @param errorId id of error @see /lib/validation/errors
11
12
  * @param errorCreator - function returning an error-object @see /lib/utils/createCustomError
12
13
  */
13
- function addError(core: Core, errorId: string, errorCreator) {
14
+ function addError(core: Core, errorId: string, errorCreator: CreateError) {
14
15
  if (typeof errorCreator !== "function") {
15
16
  throw new Error(`Error callback 'errorCreator' must be of type function. Received '${typeof errorCreator}'`);
16
17
  }
@@ -28,11 +29,10 @@ function addFormat(core: Core, formatType: string, validationFunction: JSONValid
28
29
  if (typeof validationFunction !== "function") {
29
30
  throw new Error(`Validation function expected. Received ${typeof validationFunction}`);
30
31
  }
31
- if (core.validateFormat[formatType] == null) {
32
- core.validateFormat[formatType] = validationFunction;
33
- return;
32
+ if (core.validateFormat[formatType]) {
33
+ throw new Error(`A format '${formatType}' is already registered to validation`);
34
34
  }
35
- throw new Error(`A format '${formatType}' is already registered to validation`);
35
+ core.validateFormat[formatType] = validationFunction;
36
36
  }
37
37
 
38
38
 
@@ -5,7 +5,7 @@ import { JSONSchema } from "../types";
5
5
 
6
6
 
7
7
  const suffixes = /(#|\/)+$/g;
8
- const isObject = val => (getTypeOf(val) === "object");
8
+ const isObject = (val: unknown): val is Record<string, any> => (getTypeOf(val) === "object");
9
9
 
10
10
 
11
11
  // 1. combined is known
@@ -11,7 +11,17 @@ const GET_REF = "getRef";
11
11
  const GET_ROOT = "getRoot";
12
12
  const suffixes = /(#|\/)+$/g;
13
13
 
14
-
14
+ /**
15
+ * compiles the input root schema for $ref resolution and returns it again
16
+ * @attention this modifies input schema but maintains object-structure
17
+ *
18
+ * for a compiled json-schema you can call getRef on any contained schema (location of type).
19
+ * this resolves a $ref target to a valid schema (for a valid $ref)
20
+ *
21
+ * @param rootSchema root json-schema ($id, defs, ... ) to compile
22
+ * @param [force] = false force compile json-schema
23
+ * @return compiled json-schema
24
+ */
15
25
  export default function compile(rootSchema: JSONSchema, force = false): JSONSchema {
16
26
  if (rootSchema[COMPILED] !== undefined) { return rootSchema; } // eslint-disable-line
17
27
  const context = { ids: {}, remotes: Object.assign({}, remotes) };
@@ -5,15 +5,28 @@ export default {
5
5
  AdditionalPropertiesError: "Additional property `{{property}}` on `{{pointer}}` does not match schema `{{schema}}`",
6
6
  AnyOfError: "Value `{{value}}` at `{{pointer}}` does not match any schema of `{{anyOf}}`",
7
7
  AllOfError: "Value `{{value}}` at `{{pointer}}` does not match schema of `{{allOf}}`",
8
+ ConstError: "Expected value at `{{pointer}}` to be `{{expected}}`, but value given is `{{value}}`",
9
+ ContainsError: "The array at `{{pointer}}` must contain an element that matches `{{schema}}`",
10
+ ContainsArrayError: "The property at `{{pointer}}` must not be an array",
11
+ containsAnyError: "The array at `{{pointer}}` must contain at least one item",
8
12
  EnumError: "Expected given value `{{value}}` in `{{pointer}}` to be one of `{{values}}`",
13
+ FormatDateError: "Value `{{value}}` at `{{pointer}}` is not a valid date",
9
14
  FormatDateTimeError: "Value `{{value}}` at `{{pointer}}` is not a valid date-time",
10
15
  FormatEmailError: "Value `{{value}}` at `{{pointer}}` is not a valid email",
11
- FormatUrlError: "Value `{{value}}` at `{{pointer}}` is not a valid url",
12
- FormatUriError: "Value `{{value}}` at `{{pointer}}` is not a valid uri",
16
+ FormatURLError: "Value `{{value}}` at `{{pointer}}` is not a valid url",
17
+ FormatURIError: "Value `{{value}}` at `{{pointer}}` is not a valid uri",
18
+ FormatURIReferenceError: "Value `{{value}}` at `{{pointer}}` is not a valid uri-reference",
19
+ FormatURITemplateError: "Value `{{value}}` at `{{pointer}}` is not a valid uri-template",
13
20
  FormatHostnameError: "Value `{{value}}` at `{{pointer}}` is not a valid hostname",
14
21
  FormatIPV4Error: "Value `{{value}}` at `{{pointer}}` is not a valid IPv4 address",
22
+ FormatIPV4LeadingZeroError: "IPv4 addresses starting with zero are invalid, since they are interpreted as octals",
15
23
  FormatIPV6Error: "Value `{{value}}` at `{{pointer}}` is not a valid IPv6 address",
24
+ FormatIPV6LeadingZeroError: "IPv6 addresses starting with zero are invalid, since they are interpreted as octals",
25
+ FormatJSONPointerError: "Value `{{value}}` at `{{pointer}}` is not a valid json-pointer",
16
26
  FormatRegExError: "Value `{{value}}` at `{{pointer}}` is not a valid regular expression",
27
+ FormatTimeError: "Value `{{value}}` at `{{pointer}}` is not a valid time",
28
+ InvalidDataError: "No value may be specified in `{{pointer}}`",
29
+ InvalidPropertyNameError: "Invalid property name `{{property}}` at `{{pointer}}`",
17
30
  MaximumError: "Value in `{{pointer}}` is `{{length}}`, but should be `{{maximum}}` at maximum",
18
31
  MaxItemsError: "Too many items in `{{pointer}}`, should be `{{maximum}}` at most, but got `{{length}}`",
19
32
  MaxLengthError: "Value `{{pointer}}` should have a maximum length of `{{maxLength}}`, but got `{{length}}`.",
@@ -38,4 +51,5 @@ export default {
38
51
  UnknownPropertyError: "Could not find a valid schema for property `{{pointer}}` within object",
39
52
  UniqueItemsError: "Expected unique items in {{pointer}}: duplicate value `{{value}}` found at {{itemPointer}} and {{duplicatePointer}}",
40
53
  ValueNotEmptyError: "A value for `{{property}}` is required at `{{pointer}}`"
41
- };
54
+ } as Record<string, string>;
55
+
@@ -3,17 +3,23 @@ import resolveRef from "../resolveRef.withOverwrite";
3
3
  import compileSchema from "../compileSchema";
4
4
  import resolveAnyOf from "../resolveAnyOf";
5
5
  import resolveAllOf from "../resolveAllOf";
6
- import { JSONSchema, JSONPointer, JSONError } from "../types";
7
-
6
+ import { JSONSchema, JSONPointer, JSONValidator, JSONTypeValidator, JSONError } from "../types";
7
+ import { CreateError } from "../utils/createCustomError";
8
8
 
9
9
  /* eslint no-unused-vars: 0 no-empty-function: 0 */
10
10
  export default class CoreInterface {
11
+ /** entry point of schema */
11
12
  __rootSchema: JSONSchema;
12
- errors;
13
- typeKeywords;
14
- validateFormat;
15
- validateKeyword;
16
- validateType;
13
+ /** error creators by id */
14
+ errors: Record<string, CreateError> = {};
15
+ /** map for valid keywords of a type */
16
+ typeKeywords: Record<string, string[]> = {};
17
+ /** keyword validators */
18
+ validateKeyword: Record<string, JSONValidator> = {};
19
+ /** type validators */
20
+ validateType: Record<string, JSONTypeValidator> = {};
21
+ /** format validators */
22
+ validateFormat: Record<string, JSONValidator> = {};
17
23
 
18
24
  constructor(schema?: JSONSchema) {
19
25
  this.setSchema(schema);
@@ -34,7 +40,11 @@ export default class CoreInterface {
34
40
  throw new Error("function 'each' is not implemented");
35
41
  }
36
42
 
37
- validate(data: any, schema: JSONSchema = this.rootSchema, pointer: JSONPointer = "#"): Array<JSONError> {
43
+ validate(
44
+ data: unknown,
45
+ schema: JSONSchema = this.rootSchema,
46
+ pointer: JSONPointer = "#"
47
+ ): Array<JSONError> {
38
48
  throw new Error("function 'validate' is not implemented");
39
49
  }
40
50
 
@@ -62,7 +72,7 @@ export default class CoreInterface {
62
72
  throw new Error("function 'getSchema' is not implemented");
63
73
  }
64
74
 
65
- getTemplate(data: any, schema: JSONSchema = this.rootSchema) {
75
+ getTemplate(data?: unknown, schema: JSONSchema = this.rootSchema) {
66
76
  throw new Error("function 'getTemplate' is not implemented");
67
77
  }
68
78
 
@@ -70,7 +80,24 @@ export default class CoreInterface {
70
80
  this.rootSchema = schema;
71
81
  }
72
82
 
73
- step(key: string, schema: JSONSchema, data: any, pointer: JSONPointer = "#"): JSONSchema {
83
+ /**
84
+ * Returns the json-schema of the given object property or array item.
85
+ * e.g. it steps by one key into the data
86
+ * This helper determines the location of the property within the schema
87
+ * (additional properties, oneOf, ...) and returns the correct schema.
88
+ *
89
+ * @param key property-name or array-index
90
+ * @param schema json schema of current data
91
+ * @param data parent object or array of key
92
+ * @param [pointer] json pointer of parent object or array
93
+ * @return schema or error if failed resolving key
94
+ */
95
+ step(
96
+ key: string | number,
97
+ schema: JSONSchema,
98
+ data: any,
99
+ pointer: JSONPointer = "#"
100
+ ): JSONSchema {
74
101
  throw new Error("function 'step' is not implemented");
75
102
  }
76
103
  }
@@ -20,9 +20,7 @@ import TYPES from "../validation/type";
20
20
  import FORMATS from "../validation/format";
21
21
  import ERRORS from "../validation/errors";
22
22
 
23
-
24
23
  export default class Draft04Core extends CoreInterface {
25
-
26
24
  constructor(schema?: JSONSchema) {
27
25
  super(schema);
28
26
  this.typeKeywords = JSON.parse(JSON.stringify(TYPE_KEYWORD_MAPPING));
@@ -44,7 +42,7 @@ export default class Draft04Core extends CoreInterface {
44
42
  return this.validate(data, schema, pointer).length === 0;
45
43
  }
46
44
 
47
- resolveOneOf(data: any, schema: JSONSchema, pointer: JSONPointer) {
45
+ resolveOneOf(data: any, schema: JSONSchema, pointer?: JSONPointer) {
48
46
  return resolveOneOf(this, data, schema, pointer);
49
47
  }
50
48
 
@@ -56,7 +54,7 @@ export default class Draft04Core extends CoreInterface {
56
54
  return getSchema(this, pointer, data, schema);
57
55
  }
58
56
 
59
- getTemplate(data: any, schema: JSONSchema = this.rootSchema) {
57
+ getTemplate(data?: unknown, schema: JSONSchema = this.rootSchema) {
60
58
  return getTemplate(this, data, schema);
61
59
  }
62
60
 
@@ -0,0 +1,76 @@
1
+ import CoreInterface from "./CoreInterface";
2
+ import step from "../step";
3
+ import validate from "../validate";
4
+ import resolveOneOf from "../resolveOneOf.strict";
5
+ import resolveRef from "../resolveRef.strict";
6
+ import getTemplate from "../getTemplate";
7
+ import getSchema from "../getSchema";
8
+ import each from "../each";
9
+ import compileSchema from "../draft06/compile";
10
+ import { JSONSchema, JSONPointer } from "../types";
11
+
12
+ import remotes from "../../remotes";
13
+ import draft06 from "../../remotes/draft06.json";
14
+
15
+ // @ts-ignore
16
+ remotes["http://json-schema.org/draft-06/schema"] = compileSchema(draft06);
17
+
18
+ import TYPE_KEYWORD_MAPPING from "../draft06/validation/typeKeywordMapping";
19
+ import KEYWORDS from "../draft06/validation/keyword";
20
+ import TYPES from "../draft06/validation/type";
21
+ import FORMATS from "../validation/format";
22
+ import ERRORS from "../validation/errors";
23
+
24
+ export default class Draft06Core extends CoreInterface {
25
+ constructor(schema?: JSONSchema) {
26
+ super(schema);
27
+ this.typeKeywords = JSON.parse(JSON.stringify(TYPE_KEYWORD_MAPPING));
28
+ this.validateKeyword = Object.assign({}, KEYWORDS);
29
+ this.validateType = Object.assign({}, TYPES);
30
+ this.validateFormat = Object.assign({}, FORMATS);
31
+ this.errors = Object.assign({}, ERRORS);
32
+ }
33
+
34
+ get rootSchema() {
35
+ return this.__rootSchema;
36
+ }
37
+
38
+ set rootSchema(rootSchema: JSONSchema) {
39
+ if (rootSchema == null) {
40
+ return;
41
+ }
42
+ this.__rootSchema = compileSchema(rootSchema);
43
+ }
44
+
45
+ each(data: any, callback, schema: JSONSchema = this.rootSchema, pointer: JSONPointer = "#") {
46
+ each(this, data, callback, schema, pointer);
47
+ }
48
+
49
+ validate(data: any, schema: JSONSchema = this.rootSchema, pointer: JSONPointer = "#") {
50
+ return validate(this, data, schema, pointer);
51
+ }
52
+
53
+ isValid(data: any, schema: JSONSchema = this.rootSchema, pointer: JSONPointer = "#") {
54
+ return this.validate(data, schema, pointer).length === 0;
55
+ }
56
+
57
+ resolveOneOf(data: any, schema: JSONSchema, pointer?: JSONPointer) {
58
+ return resolveOneOf(this, data, schema, pointer);
59
+ }
60
+
61
+ resolveRef(schema: JSONSchema) {
62
+ return resolveRef(schema, this.rootSchema);
63
+ }
64
+
65
+ getSchema(pointer: JSONPointer, data: any, schema: JSONSchema = this.rootSchema) {
66
+ return getSchema(this, pointer, data, schema);
67
+ }
68
+
69
+ getTemplate(data?: unknown, schema: JSONSchema = this.rootSchema) {
70
+ return getTemplate(this, data, schema);
71
+ }
72
+
73
+ step(key: string, schema: JSONSchema, data: any, pointer: JSONPointer = "#") {
74
+ return step(this, key, schema, data, pointer);
75
+ }
76
+ }
@@ -0,0 +1,75 @@
1
+ import CoreInterface from "./CoreInterface";
2
+ import step from "../step";
3
+ import validate from "../validate";
4
+ import resolveOneOf from "../resolveOneOf.strict";
5
+ import resolveRef from "../resolveRef.strict";
6
+ import getTemplate from "../getTemplate";
7
+ import getSchema from "../getSchema";
8
+ import addSchema from "../addSchema";
9
+ import each from "../each";
10
+ import compileSchema from "../draft06/compile";
11
+ import { JSONSchema, JSONPointer } from "../types";
12
+ import draft07 from "../../remotes/draft07.json";
13
+
14
+ import TYPE_KEYWORD_MAPPING from "../draft06/validation/typeKeywordMapping";
15
+ import KEYWORDS from "../draft06/validation/keyword";
16
+ import TYPES from "../draft06/validation/type";
17
+ import FORMATS from "../validation/format";
18
+ import ERRORS from "../validation/errors";
19
+ import addValidator from "../addValidator";
20
+
21
+ addSchema("http://json-schema.org/draft-07/schema", draft07);
22
+
23
+ export default class Draft07Core extends CoreInterface {
24
+ constructor(schema?: JSONSchema) {
25
+ super(schema);
26
+ this.typeKeywords = JSON.parse(JSON.stringify(TYPE_KEYWORD_MAPPING));
27
+ Object.assign(this.validateKeyword, KEYWORDS);
28
+ Object.assign(this.validateType, TYPES);
29
+ Object.keys(FORMATS).forEach((id) => addValidator.format(this, id, FORMATS[id]));
30
+ Object.keys(ERRORS).forEach((id) => addValidator.error(this, id, ERRORS[id]));
31
+ }
32
+
33
+ get rootSchema() {
34
+ return this.__rootSchema;
35
+ }
36
+
37
+ set rootSchema(rootSchema: JSONSchema) {
38
+ if (rootSchema == null) {
39
+ return;
40
+ }
41
+ this.__rootSchema = compileSchema(rootSchema);
42
+ }
43
+
44
+ each(data: any, callback, schema: JSONSchema = this.rootSchema, pointer: JSONPointer = "#") {
45
+ each(this, data, callback, schema, pointer);
46
+ }
47
+
48
+ validate(data: any, schema: JSONSchema = this.rootSchema, pointer: JSONPointer = "#") {
49
+ return validate(this, data, schema, pointer);
50
+ }
51
+
52
+ isValid(data: any, schema: JSONSchema = this.rootSchema, pointer: JSONPointer = "#") {
53
+ return this.validate(data, schema, pointer).length === 0;
54
+ }
55
+
56
+ resolveOneOf(data: any, schema: JSONSchema, pointer?: JSONPointer) {
57
+ return resolveOneOf(this, data, schema, pointer);
58
+ }
59
+
60
+ resolveRef(schema: JSONSchema) {
61
+ return resolveRef(schema, this.rootSchema);
62
+ }
63
+
64
+ getSchema(pointer: JSONPointer, data: any, schema: JSONSchema = this.rootSchema) {
65
+ return getSchema(this, pointer, data, schema);
66
+ }
67
+
68
+ getTemplate(data?: unknown, schema: JSONSchema = this.rootSchema) {
69
+ return getTemplate(this, data, schema);
70
+ }
71
+
72
+ step(key: string, schema: JSONSchema, data: any, pointer: JSONPointer = "#") {
73
+ return step(this, key, schema, data, pointer);
74
+ }
75
+ }
@@ -14,9 +14,7 @@ import TYPES from "../validation/type";
14
14
  import FORMATS from "../validation/format";
15
15
  import ERRORS from "../validation/errors";
16
16
 
17
-
18
17
  export default class JsonEditorCore extends CoreInterface {
19
-
20
18
  constructor(schema?: JSONSchema) {
21
19
  super(schema);
22
20
  this.typeKeywords = JSON.parse(JSON.stringify(TYPE_KEYWORD_MAPPING));
@@ -42,7 +40,7 @@ export default class JsonEditorCore extends CoreInterface {
42
40
  return this.validate(data, schema, pointer).length === 0;
43
41
  }
44
42
 
45
- resolveOneOf(data, schema: JSONSchema, pointer: JSONPointer) {
43
+ resolveOneOf(data, schema: JSONSchema, pointer?: JSONPointer) {
46
44
  return resolveOneOf(this, data, schema, pointer);
47
45
  }
48
46
 
@@ -54,7 +52,7 @@ export default class JsonEditorCore extends CoreInterface {
54
52
  return getSchema(this, pointer, data, schema);
55
53
  }
56
54
 
57
- getTemplate(data: any, schema: JSONSchema = this.rootSchema) {
55
+ getTemplate(data?: any, schema: JSONSchema = this.rootSchema) {
58
56
  return getTemplate(this, data, schema);
59
57
  }
60
58
 
@@ -1,7 +1,6 @@
1
1
  import getTypeOf from "./getTypeOf";
2
2
  import { JSONSchema } from "./types";
3
3
 
4
-
5
4
  /**
6
5
  * Create a simple json schema for the given input data
7
6
  * @param data - data to get json schema for
@@ -14,12 +13,11 @@ export default function createSchemaOf(data: any): JSONSchema {
14
13
 
15
14
  if (schema.type === "object") {
16
15
  schema.properties = {};
17
- Object.keys(data).forEach(key => (schema.properties[key] = createSchemaOf(data[key])));
16
+ Object.keys(data).forEach((key) => (schema.properties[key] = createSchemaOf(data[key])));
18
17
  }
19
18
 
20
19
  if (schema.type === "array" && data.length === 1) {
21
20
  schema.items = createSchemaOf(data[0]);
22
-
23
21
  } else if (schema.type === "array") {
24
22
  schema.items = data.map(createSchemaOf);
25
23
  }
@@ -0,0 +1,14 @@
1
+ import remotes from "../../remotes";
2
+ import compileSchema from "./compile";
3
+ import { JSONSchema } from "../types";
4
+
5
+
6
+ /**
7
+ * register a json-schema to be referenced from another json-schema
8
+ * @param url base-url of json-schema (aka id)
9
+ * @param schema
10
+ */
11
+ export default function addSchema(url: string, schema: JSONSchema): void {
12
+ schema.id = schema.id || url;
13
+ remotes[url] = compileSchema(schema);
14
+ }
@@ -0,0 +1,68 @@
1
+ /* eslint max-statements-per-line: ["error", { "max": 2 }] */
2
+ import eachSchema from "../../eachSchema";
3
+ import remotes from "../../../remotes";
4
+ import joinScope from "../../compile/joinScope";
5
+ import getRef from "../../compile/getRef";
6
+ import { JSONSchema } from "../../types";
7
+
8
+ const COMPILED = "__compiled";
9
+ const COMPILED_REF = "__ref";
10
+ const GET_REF = "getRef";
11
+ const GET_ROOT = "getRoot";
12
+ const suffixes = /(#|\/)+$/g;
13
+
14
+
15
+ /**
16
+ * @draft starting with _draft 06_ keyword `id` has been renamed to `$id`
17
+ *
18
+ * compiles the input root schema for $ref resolution and returns it again
19
+ * @attention this modifies input schema but maintains object-structure
20
+ *
21
+ * for a compiled json-schema you can call getRef on any contained schema (location of type).
22
+ * this resolves a $ref target to a valid schema (for a valid $ref)
23
+ *
24
+ * @param rootSchema root json-schema ($id, defs, ... ) to compile
25
+ * @param [force] = false force compile json-schema
26
+ * @return compiled json-schema
27
+ */
28
+ export default function compile(rootSchema: JSONSchema, force = false): JSONSchema {
29
+ // @ts-ignore
30
+ if (rootSchema === true || rootSchema === false) {
31
+ return rootSchema;
32
+ }
33
+ if (rootSchema[COMPILED] !== undefined) { return rootSchema; } // eslint-disable-line
34
+ const context = { ids: {}, remotes: Object.assign({}, remotes) };
35
+ const rootSchemaAsString = JSON.stringify(rootSchema);
36
+ rootSchema = JSON.parse(rootSchemaAsString);
37
+ Object.defineProperty(rootSchema, COMPILED, { enumerable: false, value: true });
38
+ Object.defineProperty(rootSchema, GET_REF, { enumerable: false, value: getRef.bind(null, context, rootSchema) });
39
+
40
+ if (force === false && rootSchemaAsString.includes("$ref") === false) {
41
+ // bail early, when no $refs are defined
42
+ return rootSchema;
43
+ }
44
+
45
+ const scopes = {};
46
+ const getRoot = () => rootSchema;
47
+ eachSchema(rootSchema, (schema, pointer) => {
48
+ if (schema.$id) { context.ids[schema.$id.replace(suffixes, "")] = pointer; }
49
+
50
+ // build up scopes and add them to $ref-resolution map
51
+ pointer = `#${pointer}`.replace(/##+/, "#");
52
+ const previousPointer = pointer.replace(/\/[^/]+$/, "");
53
+ const parentPointer = pointer.replace(/\/[^/]+\/[^/]+$/, "");
54
+ const previousScope = scopes[previousPointer] || scopes[parentPointer];
55
+ const scope = joinScope(previousScope, schema.$id);
56
+ scopes[pointer] = scope;
57
+ if (context.ids[scope] == null) { context.ids[scope] = pointer; }
58
+
59
+ if (schema.$ref) {
60
+ Object.defineProperty(schema, COMPILED_REF, { enumerable: false, value: joinScope(scope, schema.$ref) });
61
+ // @todo currently not used:
62
+ Object.defineProperty(schema, GET_ROOT, { enumerable: false, value: getRoot });
63
+ // console.log("compiled ref", scope, schema.$ref, "=>", joinScope(scope, schema.$ref));
64
+ }
65
+ });
66
+
67
+ return rootSchema;
68
+ }