z-schema 12.0.4 → 12.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 (176) hide show
  1. package/bin/z-schema +7 -2
  2. package/cjs/index.d.ts +541 -530
  3. package/cjs/index.js +3963 -7740
  4. package/dist/errors.d.mts +64 -0
  5. package/dist/errors.mjs +67 -0
  6. package/dist/format-validators.d.mts +14 -0
  7. package/dist/format-validators.mjs +261 -0
  8. package/dist/index.d.mts +10 -0
  9. package/dist/index.mjs +7 -0
  10. package/dist/json-schema-versions.d.mts +137 -0
  11. package/dist/json-schema-versions.mjs +11 -0
  12. package/dist/json-schema.d.mts +61 -0
  13. package/dist/json-schema.mjs +53 -0
  14. package/dist/json-validation.mjs +441 -0
  15. package/dist/report.d.mts +97 -0
  16. package/dist/report.mjs +194 -0
  17. package/dist/schema-cache.d.mts +23 -0
  18. package/dist/schema-cache.mjs +144 -0
  19. package/dist/schema-compiler.d.mts +23 -0
  20. package/dist/schema-compiler.mjs +265 -0
  21. package/dist/schema-validator.d.mts +15 -0
  22. package/dist/schema-validator.mjs +446 -0
  23. package/dist/schemas/draft-04-schema.mjs +125 -0
  24. package/dist/schemas/draft-06-schema.mjs +126 -0
  25. package/dist/schemas/draft-07-schema.mjs +141 -0
  26. package/dist/schemas/draft-2019-09-meta-applicator.mjs +46 -0
  27. package/dist/schemas/draft-2019-09-meta-content.mjs +15 -0
  28. package/dist/schemas/draft-2019-09-meta-core.mjs +52 -0
  29. package/dist/schemas/draft-2019-09-meta-format.mjs +11 -0
  30. package/dist/schemas/draft-2019-09-meta-meta-data.mjs +31 -0
  31. package/dist/schemas/draft-2019-09-meta-validation.mjs +80 -0
  32. package/dist/schemas/draft-2019-09-schema.mjs +39 -0
  33. package/dist/schemas/draft-2020-12-meta-applicator.mjs +45 -0
  34. package/dist/schemas/draft-2020-12-meta-content.mjs +15 -0
  35. package/dist/schemas/draft-2020-12-meta-core.mjs +46 -0
  36. package/dist/schemas/draft-2020-12-meta-format-annotation.mjs +11 -0
  37. package/dist/schemas/draft-2020-12-meta-format-assertion.mjs +11 -0
  38. package/dist/schemas/draft-2020-12-meta-meta-data.mjs +31 -0
  39. package/dist/schemas/draft-2020-12-meta-unevaluated.mjs +14 -0
  40. package/dist/schemas/draft-2020-12-meta-validation.mjs +80 -0
  41. package/dist/schemas/draft-2020-12-schema.mjs +55 -0
  42. package/dist/utils/array.mjs +54 -0
  43. package/dist/utils/base64.mjs +21 -0
  44. package/dist/utils/clone.mjs +42 -0
  45. package/dist/utils/constants.mjs +16 -0
  46. package/dist/utils/date.mjs +19 -0
  47. package/dist/utils/hostname.mjs +73 -0
  48. package/dist/utils/json.mjs +34 -0
  49. package/dist/utils/properties.mjs +11 -0
  50. package/dist/utils/schema-regex.mjs +49 -0
  51. package/dist/utils/symbols.mjs +5 -0
  52. package/dist/utils/time.mjs +42 -0
  53. package/dist/utils/unicode.mjs +12 -0
  54. package/dist/utils/uri.mjs +12 -0
  55. package/dist/utils/what-is.mjs +23 -0
  56. package/dist/validation/array.mjs +57 -0
  57. package/dist/validation/combinators.mjs +62 -0
  58. package/dist/validation/numeric.mjs +38 -0
  59. package/dist/validation/object.mjs +109 -0
  60. package/dist/validation/ref.mjs +49 -0
  61. package/dist/validation/shared.mjs +97 -0
  62. package/dist/validation/string.mjs +88 -0
  63. package/dist/validation/type.mjs +32 -0
  64. package/dist/z-schema-base.d.mts +85 -0
  65. package/dist/z-schema-base.mjs +230 -0
  66. package/dist/z-schema-options.d.mts +35 -0
  67. package/dist/z-schema-options.mjs +55 -0
  68. package/dist/z-schema-reader.d.mts +6 -0
  69. package/dist/z-schema-reader.mjs +10 -0
  70. package/dist/z-schema-versions.mjs +67 -0
  71. package/dist/z-schema.d.mts +193 -0
  72. package/dist/z-schema.mjs +300 -0
  73. package/package.json +49 -64
  74. package/src/index.ts +3 -3
  75. package/src/schema-compiler.ts +30 -10
  76. package/src/schema-validator.ts +1 -1
  77. package/src/utils/schema-regex.ts +13 -2
  78. package/src/z-schema-base.ts +1 -1
  79. package/src/z-schema-versions.ts +1 -2
  80. package/src/z-schema.ts +0 -1
  81. package/umd/ZSchema.js +5934 -8110
  82. package/umd/ZSchema.min.js +2 -1
  83. package/dist/errors.js +0 -72
  84. package/dist/format-validators.js +0 -392
  85. package/dist/index.js +0 -5
  86. package/dist/json-schema-versions.js +0 -8
  87. package/dist/json-schema.js +0 -84
  88. package/dist/json-validation.js +0 -728
  89. package/dist/package.json +0 -3
  90. package/dist/report.js +0 -265
  91. package/dist/schema-cache.js +0 -211
  92. package/dist/schema-compiler.js +0 -415
  93. package/dist/schema-validator.js +0 -721
  94. package/dist/schemas/draft-04-schema.json +0 -149
  95. package/dist/schemas/draft-06-schema.json +0 -155
  96. package/dist/schemas/draft-07-schema.json +0 -172
  97. package/dist/schemas/draft-2019-09-meta-applicator.json +0 -52
  98. package/dist/schemas/draft-2019-09-meta-content.json +0 -12
  99. package/dist/schemas/draft-2019-09-meta-core.json +0 -53
  100. package/dist/schemas/draft-2019-09-meta-format.json +0 -10
  101. package/dist/schemas/draft-2019-09-meta-meta-data.json +0 -32
  102. package/dist/schemas/draft-2019-09-meta-validation.json +0 -94
  103. package/dist/schemas/draft-2019-09-schema.json +0 -41
  104. package/dist/schemas/draft-2020-12-meta-applicator.json +0 -44
  105. package/dist/schemas/draft-2020-12-meta-content.json +0 -12
  106. package/dist/schemas/draft-2020-12-meta-core.json +0 -47
  107. package/dist/schemas/draft-2020-12-meta-format-annotation.json +0 -10
  108. package/dist/schemas/draft-2020-12-meta-format-assertion.json +0 -10
  109. package/dist/schemas/draft-2020-12-meta-meta-data.json +0 -32
  110. package/dist/schemas/draft-2020-12-meta-unevaluated.json +0 -11
  111. package/dist/schemas/draft-2020-12-meta-validation.json +0 -94
  112. package/dist/schemas/draft-2020-12-schema.json +0 -57
  113. package/dist/types/errors.d.ts +0 -64
  114. package/dist/types/format-validators.d.ts +0 -11
  115. package/dist/types/index.d.ts +0 -14
  116. package/dist/types/json-schema-versions.d.ts +0 -142
  117. package/dist/types/json-schema.d.ts +0 -66
  118. package/dist/types/json-validation.d.ts +0 -6
  119. package/dist/types/report.d.ts +0 -94
  120. package/dist/types/schema-cache.d.ts +0 -27
  121. package/dist/types/schema-compiler.d.ts +0 -31
  122. package/dist/types/schema-validator.d.ts +0 -10
  123. package/dist/types/utils/array.d.ts +0 -9
  124. package/dist/types/utils/base64.d.ts +0 -2
  125. package/dist/types/utils/clone.d.ts +0 -2
  126. package/dist/types/utils/constants.d.ts +0 -19
  127. package/dist/types/utils/date.d.ts +0 -1
  128. package/dist/types/utils/hostname.d.ts +0 -2
  129. package/dist/types/utils/json.d.ts +0 -9
  130. package/dist/types/utils/properties.d.ts +0 -1
  131. package/dist/types/utils/schema-regex.d.ts +0 -10
  132. package/dist/types/utils/symbols.d.ts +0 -2
  133. package/dist/types/utils/time.d.ts +0 -12
  134. package/dist/types/utils/unicode.d.ts +0 -5
  135. package/dist/types/utils/uri.d.ts +0 -4
  136. package/dist/types/utils/what-is.d.ts +0 -4
  137. package/dist/types/validation/array.d.ts +0 -12
  138. package/dist/types/validation/combinators.d.ts +0 -10
  139. package/dist/types/validation/numeric.d.ts +0 -8
  140. package/dist/types/validation/object.d.ts +0 -13
  141. package/dist/types/validation/ref.d.ts +0 -11
  142. package/dist/types/validation/shared.d.ts +0 -26
  143. package/dist/types/validation/string.d.ts +0 -9
  144. package/dist/types/validation/type.d.ts +0 -6
  145. package/dist/types/z-schema-base.d.ts +0 -87
  146. package/dist/types/z-schema-options.d.ts +0 -35
  147. package/dist/types/z-schema-reader.d.ts +0 -4
  148. package/dist/types/z-schema-versions.d.ts +0 -1
  149. package/dist/types/z-schema.d.ts +0 -191
  150. package/dist/utils/array.js +0 -69
  151. package/dist/utils/base64.js +0 -29
  152. package/dist/utils/clone.js +0 -59
  153. package/dist/utils/constants.js +0 -19
  154. package/dist/utils/date.js +0 -21
  155. package/dist/utils/hostname.js +0 -146
  156. package/dist/utils/json.js +0 -70
  157. package/dist/utils/properties.js +0 -10
  158. package/dist/utils/schema-regex.js +0 -52
  159. package/dist/utils/symbols.js +0 -2
  160. package/dist/utils/time.js +0 -50
  161. package/dist/utils/unicode.js +0 -12
  162. package/dist/utils/uri.js +0 -15
  163. package/dist/utils/what-is.js +0 -32
  164. package/dist/validation/array.js +0 -127
  165. package/dist/validation/combinators.js +0 -106
  166. package/dist/validation/numeric.js +0 -97
  167. package/dist/validation/object.js +0 -237
  168. package/dist/validation/ref.js +0 -70
  169. package/dist/validation/shared.js +0 -136
  170. package/dist/validation/string.js +0 -170
  171. package/dist/validation/type.js +0 -55
  172. package/dist/z-schema-base.js +0 -286
  173. package/dist/z-schema-options.js +0 -99
  174. package/dist/z-schema-reader.js +0 -7
  175. package/dist/z-schema-versions.js +0 -110
  176. package/dist/z-schema.js +0 -287
@@ -1,70 +0,0 @@
1
- import { DEFAULT_MAX_RECURSION_DEPTH } from './constants.js';
2
- import { isObject } from './what-is.js';
3
- export const areEqual = (json1, json2, options, _depth = 0) => {
4
- const caseInsensitiveComparison = options?.caseInsensitiveComparison || false;
5
- const maxDepth = options?.maxDepth ?? DEFAULT_MAX_RECURSION_DEPTH;
6
- // http://json-schema.org/latest/json-schema-core.html#rfc.section.3.6
7
- // Two JSON values are said to be equal if and only if:
8
- // both are nulls; or
9
- // both are booleans, and have the same value; or
10
- // both are strings, and have the same value; or
11
- // both are numbers, and have the same mathematical value; or
12
- if (json1 === json2) {
13
- return true;
14
- }
15
- if (caseInsensitiveComparison === true &&
16
- typeof json1 === 'string' &&
17
- typeof json2 === 'string' &&
18
- json1.toUpperCase() === json2.toUpperCase()) {
19
- return true;
20
- }
21
- if (_depth >= maxDepth) {
22
- throw new Error(`Maximum recursion depth (${maxDepth}) exceeded in areEqual. ` +
23
- 'If your data is deeply nested and valid, increase the maxRecursionDepth option.');
24
- }
25
- let i, len;
26
- // both are arrays, and:
27
- if (Array.isArray(json1) && Array.isArray(json2)) {
28
- // have the same number of items; and
29
- if (json1.length !== json2.length) {
30
- return false;
31
- }
32
- // items at the same index are equal according to this definition; or
33
- len = json1.length;
34
- for (i = 0; i < len; i++) {
35
- if (!areEqual(json1[i], json2[i], options, _depth + 1)) {
36
- return false;
37
- }
38
- }
39
- return true;
40
- }
41
- // both are objects, and:
42
- if (isObject(json1) && isObject(json2)) {
43
- // have the same set of property names; and
44
- const keys1 = sortedKeys(json1);
45
- const keys2 = sortedKeys(json2);
46
- if (!areEqual(keys1, keys2, options, _depth + 1)) {
47
- return false;
48
- }
49
- // values for a same property name are equal according to this definition.
50
- len = keys1.length;
51
- for (i = 0; i < len; i++) {
52
- if (!areEqual(json1[keys1[i]], json2[keys1[i]], options, _depth + 1)) {
53
- return false;
54
- }
55
- }
56
- return true;
57
- }
58
- return false;
59
- };
60
- export const decodeJSONPointer = (str) => {
61
- // http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07#section-3
62
- return decodeURIComponent(str).replace(/~[0-1]/g, (x) => (x === '~1' ? '/' : '~'));
63
- };
64
- export const sortedKeys = (obj) => Object.keys(obj).sort();
65
- export const get = (obj, path) => {
66
- if (typeof path === 'string') {
67
- path = path.split('.');
68
- }
69
- return path.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj);
70
- };
@@ -1,10 +0,0 @@
1
- export function copyProp(from, to, key, fn) {
2
- if (Object.hasOwn(from, key)) {
3
- Object.defineProperty(to, key, {
4
- value: fn ? fn(from[key]) : from[key],
5
- enumerable: true,
6
- writable: true,
7
- configurable: true,
8
- });
9
- }
10
- }
@@ -1,52 +0,0 @@
1
- // Shared regex compilation helper for JSON Schema patterns
2
- // Returns { ok: true, value: RegExp } or { ok: false, error: { pattern, message } }
3
- import { MAX_SCHEMA_REGEX_LENGTH } from './constants.js';
4
- export function compileSchemaRegex(pattern) {
5
- if (pattern.length > MAX_SCHEMA_REGEX_LENGTH) {
6
- return {
7
- ok: false,
8
- error: {
9
- pattern,
10
- message: `Pattern length ${pattern.length} exceeds maximum allowed length of ${MAX_SCHEMA_REGEX_LENGTH}`,
11
- },
12
- };
13
- }
14
- const unicodePropertyEscape = /\\[pP]{/;
15
- const nonBmpCharacter = /[\u{10000}-\u{10FFFF}]/u;
16
- const surrogatePairEscape = /\\uD[89AB][0-9A-Fa-f]{2}\\uD[CDEF][0-9A-Fa-f]{2}/;
17
- const needsUnicode = unicodePropertyEscape.test(pattern) || nonBmpCharacter.test(pattern) || surrogatePairEscape.test(pattern);
18
- // Try compiling without 'u' flag if not needed
19
- if (needsUnicode) {
20
- // Try compiling with 'u' flag only
21
- try {
22
- // lgtm[js/regex-injection] JSON Schema `pattern` is intentionally regex syntax and constrained by MAX_SCHEMA_REGEX_LENGTH.
23
- const re = new RegExp(pattern, 'u');
24
- return { ok: true, value: re };
25
- }
26
- catch (e) {
27
- return {
28
- ok: false,
29
- error: {
30
- pattern,
31
- message: e && e.message ? e.message : 'Invalid regular expression',
32
- },
33
- };
34
- }
35
- }
36
- else {
37
- try {
38
- // lgtm[js/regex-injection] JSON Schema `pattern` is intentionally regex syntax and constrained by MAX_SCHEMA_REGEX_LENGTH.
39
- const re = new RegExp(pattern);
40
- return { ok: true, value: re };
41
- }
42
- catch (e) {
43
- return {
44
- ok: false,
45
- error: {
46
- pattern,
47
- message: e && e.message ? e.message : 'Invalid regular expression',
48
- },
49
- };
50
- }
51
- }
52
- }
@@ -1,2 +0,0 @@
1
- export const jsonSymbol = Symbol.for('z-schema/json');
2
- export const schemaSymbol = Symbol.for('z-schema/schema');
@@ -1,50 +0,0 @@
1
- export const toUtcTime = (hour, minute, offsetSign, offsetHour, offsetMinute) => {
2
- const localTotalMinutes = hour * 60 + minute;
3
- const offsetTotalMinutes = offsetHour * 60 + offsetMinute;
4
- const utcTotalMinutes = offsetSign === '+' ? localTotalMinutes - offsetTotalMinutes : localTotalMinutes + offsetTotalMinutes;
5
- const normalizedUtcTotalMinutes = ((utcTotalMinutes % 1440) + 1440) % 1440;
6
- return {
7
- hour: Math.floor(normalizedUtcTotalMinutes / 60),
8
- minute: normalizedUtcTotalMinutes % 60,
9
- };
10
- };
11
- const RFC3339_TIME_REGEX = /^([0-9]{2}):([0-9]{2}):([0-9]{2})(\.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$/i;
12
- export const parseRfc3339Time = (time) => {
13
- const matches = RFC3339_TIME_REGEX.exec(time);
14
- if (matches === null) {
15
- return null;
16
- }
17
- const hour = parseInt(matches[1], 10);
18
- const minute = parseInt(matches[2], 10);
19
- const second = parseInt(matches[3], 10);
20
- if (hour > 23 || minute > 59 || second > 60) {
21
- return null;
22
- }
23
- let utcHour = hour;
24
- let utcMinute = minute;
25
- if (matches[5].toLowerCase() !== 'z') {
26
- const offsetMatches = /^([+-])([0-9]{2}):([0-9]{2})$/.exec(matches[5]);
27
- if (offsetMatches === null) {
28
- return null;
29
- }
30
- const offsetSign = offsetMatches[1];
31
- const offsetHour = parseInt(offsetMatches[2], 10);
32
- const offsetMinute = parseInt(offsetMatches[3], 10);
33
- if (offsetHour > 23 || offsetMinute > 59) {
34
- return null;
35
- }
36
- const utc = toUtcTime(hour, minute, offsetSign, offsetHour, offsetMinute);
37
- utcHour = utc.hour;
38
- utcMinute = utc.minute;
39
- }
40
- if (second === 60 && (utcHour !== 23 || utcMinute !== 59)) {
41
- return null;
42
- }
43
- return {
44
- hour,
45
- minute,
46
- second,
47
- utcHour,
48
- utcMinute,
49
- };
50
- };
@@ -1,12 +0,0 @@
1
- /**
2
- * Returns the number of Unicode code points in the string.
3
- * Uses the built-in string iterator which correctly handles surrogate pairs.
4
- */
5
- export function unicodeLength(str) {
6
- let count = 0;
7
- for (const _cp of str) {
8
- void _cp;
9
- count++;
10
- }
11
- return count;
12
- }
package/dist/utils/uri.js DELETED
@@ -1,15 +0,0 @@
1
- export const getQueryPath = (uri) => {
2
- const io = uri.indexOf('#');
3
- const res = io === -1 ? undefined : uri.slice(io + 1);
4
- // WARN: do not slice slash, #/ means take root and go down from it
5
- // if (res && res[0] === "/") { res = res.slice(1); }
6
- return res;
7
- };
8
- export const getRemotePath = (uri) => {
9
- const io = uri.indexOf('#');
10
- return io === -1 ? uri : uri.slice(0, io);
11
- };
12
- export const isAbsoluteUri = (uri) => /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(uri);
13
- export const isRelativeUri = (uri) =>
14
- // relative URIs that end with a hash sign, issue #56
15
- /.+#/.test(uri);
@@ -1,32 +0,0 @@
1
- export const whatIs = (what) => {
2
- if (typeof what === 'object') {
3
- if (what === null) {
4
- return 'null';
5
- }
6
- if (Array.isArray(what)) {
7
- return 'array';
8
- }
9
- return 'object'; // typeof what === 'object' && what === Object(what) && !Array.isArray(what);
10
- }
11
- if (typeof what === 'number') {
12
- if (Number.isFinite(what)) {
13
- if (what % 1 === 0) {
14
- return 'integer';
15
- }
16
- else {
17
- return 'number';
18
- }
19
- }
20
- if (Number.isNaN(what)) {
21
- return 'not-a-number';
22
- }
23
- return 'unknown-number';
24
- }
25
- return typeof what; // undefined, boolean, string, function
26
- };
27
- export function isObject(value) {
28
- return typeof value === 'object' && value !== null && !Array.isArray(value);
29
- }
30
- export function isInteger(value) {
31
- return typeof value === 'number' && Number.isFinite(value) && value % 1 === 0;
32
- }
@@ -1,127 +0,0 @@
1
- import { isUniqueArray } from '../utils/array.js';
2
- import { cacheValidationResult, deferOrRunSync, shouldSkipValidate } from './shared.js';
3
- // ---------------------------------------------------------------------------
4
- // additionalItems
5
- // ---------------------------------------------------------------------------
6
- export function additionalItemsValidator(report, schema, json) {
7
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.1.2
8
- if (shouldSkipValidate(this.validateOptions, ['ARRAY_ADDITIONAL_ITEMS'])) {
9
- return;
10
- }
11
- if (!Array.isArray(json)) {
12
- return;
13
- }
14
- // if the value of "additionalItems" is boolean value false and the value of "items" is an array,
15
- // the json is valid if its size is less than, or equal to, the size of "items".
16
- if (schema.additionalItems === false && Array.isArray(schema.items)) {
17
- if (json.length > schema.items.length) {
18
- report.addError('ARRAY_ADDITIONAL_ITEMS', undefined, undefined, schema, 'additionalItems');
19
- }
20
- }
21
- }
22
- // ---------------------------------------------------------------------------
23
- // items (no-op — covered in additionalItems / recurseArray)
24
- // ---------------------------------------------------------------------------
25
- export function itemsValidator() {
26
- /*report: Report, schema: JsonSchemaInternal, json: unknown*/
27
- // covered in additionalItems
28
- }
29
- // ---------------------------------------------------------------------------
30
- // prefixItems (no-op — handled in recurseArray)
31
- // ---------------------------------------------------------------------------
32
- export function prefixItemsValidator() {
33
- // handled in recurseArray
34
- }
35
- // ---------------------------------------------------------------------------
36
- // maxItems
37
- // ---------------------------------------------------------------------------
38
- export function maxItemsValidator(report, schema, json) {
39
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.2.2
40
- if (shouldSkipValidate(this.validateOptions, ['ARRAY_LENGTH_LONG'])) {
41
- return;
42
- }
43
- if (!Array.isArray(json)) {
44
- return;
45
- }
46
- if (json.length > schema.maxItems) {
47
- report.addError('ARRAY_LENGTH_LONG', [json.length, schema.maxItems], undefined, schema, 'maxItems');
48
- }
49
- }
50
- // ---------------------------------------------------------------------------
51
- // minItems
52
- // ---------------------------------------------------------------------------
53
- export function minItemsValidator(report, schema, json) {
54
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.3.2
55
- if (shouldSkipValidate(this.validateOptions, ['ARRAY_LENGTH_SHORT'])) {
56
- return;
57
- }
58
- if (!Array.isArray(json)) {
59
- return;
60
- }
61
- if (json.length < schema.minItems) {
62
- report.addError('ARRAY_LENGTH_SHORT', [json.length, schema.minItems], undefined, schema, 'minItems');
63
- }
64
- }
65
- // ---------------------------------------------------------------------------
66
- // uniqueItems
67
- // ---------------------------------------------------------------------------
68
- export function uniqueItemsValidator(report, schema, json) {
69
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.3.4.2
70
- if (shouldSkipValidate(this.validateOptions, ['ARRAY_UNIQUE'])) {
71
- return;
72
- }
73
- if (!Array.isArray(json)) {
74
- return;
75
- }
76
- if (schema.uniqueItems === true) {
77
- const matches = [];
78
- if (isUniqueArray(json, matches, this.options.maxRecursionDepth) === false) {
79
- report.addError('ARRAY_UNIQUE', matches, undefined, schema, 'uniqueItems');
80
- }
81
- }
82
- }
83
- // ---------------------------------------------------------------------------
84
- // contains
85
- // ---------------------------------------------------------------------------
86
- export function containsValidator(report, schema, json) {
87
- if (shouldSkipValidate(this.validateOptions, ['CONTAINS'])) {
88
- return;
89
- }
90
- if (!Array.isArray(json)) {
91
- return;
92
- }
93
- const containsSchema = schema.contains;
94
- if (containsSchema === undefined) {
95
- return;
96
- }
97
- const Report_ = report.constructor;
98
- const subReports = [];
99
- for (let idx = 0; idx < json.length; idx++) {
100
- const subReport = new Report_(report);
101
- subReports.push(subReport);
102
- this._jsonValidate(subReport, containsSchema, json[idx]);
103
- cacheValidationResult(report, containsSchema, json[idx], subReport.errors.length === 0);
104
- }
105
- const addContainsErrorIfNeeded = () => {
106
- let matchingItems = 0;
107
- for (const subReport of subReports) {
108
- if (subReport.errors.length === 0) {
109
- matchingItems += 1;
110
- }
111
- }
112
- const supportsContainsBounds = this.options.version === 'draft2019-09' || this.options.version === 'draft2020-12';
113
- const minContains = supportsContainsBounds && typeof schema.minContains === 'number' ? (schema.minContains ?? 1) : 1;
114
- const maxContains = supportsContainsBounds && typeof schema.maxContains === 'number' ? schema.maxContains : undefined;
115
- const hasEnoughMatches = matchingItems >= minContains;
116
- const notTooManyMatches = maxContains === undefined || matchingItems <= maxContains;
117
- if (!hasEnoughMatches || !notTooManyMatches) {
118
- report.addError('CONTAINS', undefined, subReports, schema, undefined);
119
- }
120
- };
121
- deferOrRunSync(report, subReports, addContainsErrorIfNeeded);
122
- }
123
- // ---------------------------------------------------------------------------
124
- // maxContains / minContains (no-op — handled inside contains)
125
- // ---------------------------------------------------------------------------
126
- export function maxContainsValidator() { }
127
- export function minContainsValidator() { }
@@ -1,106 +0,0 @@
1
- import { Report } from '../report.js';
2
- import { cacheValidationResult, deferOrRunSync } from './shared.js';
3
- // ---------------------------------------------------------------------------
4
- // allOf
5
- // ---------------------------------------------------------------------------
6
- export function allOfValidator(report, schema, json) {
7
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.3.2
8
- for (let i = 0; i < schema.allOf.length; i++) {
9
- const validateResult = this._jsonValidate(report, schema.allOf[i], json);
10
- if (this.options.breakOnFirstError && validateResult === false) {
11
- break;
12
- }
13
- }
14
- }
15
- // ---------------------------------------------------------------------------
16
- // anyOf
17
- // ---------------------------------------------------------------------------
18
- export function anyOfValidator(report, schema, json) {
19
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.4.2
20
- const subReports = [];
21
- for (let i = 0; i < schema.anyOf.length; i++) {
22
- const subReport = new Report(report);
23
- subReports.push(subReport);
24
- this._jsonValidate(subReport, schema.anyOf[i], json);
25
- cacheValidationResult(report, schema.anyOf[i], json, subReport.errors.length === 0);
26
- }
27
- // Aggregate async tasks and decide when ready
28
- deferOrRunSync(report, subReports, () => {
29
- let passed = false;
30
- for (const subReport of subReports) {
31
- if (subReport.errors.length === 0) {
32
- passed = true;
33
- break;
34
- }
35
- }
36
- if (passed === false) {
37
- report.addError('ANY_OF_MISSING', undefined, subReports, schema, 'anyOf');
38
- }
39
- });
40
- }
41
- // ---------------------------------------------------------------------------
42
- // oneOf
43
- // ---------------------------------------------------------------------------
44
- export function oneOfValidator(report, schema, json) {
45
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.5.2
46
- const subReports = [];
47
- for (let i = 0; i < schema.oneOf.length; i++) {
48
- const subReport = new Report(report);
49
- subReports.push(subReport);
50
- this._jsonValidate(subReport, schema.oneOf[i], json);
51
- cacheValidationResult(report, schema.oneOf[i], json, subReport.errors.length === 0);
52
- }
53
- // Aggregate async tasks and decide when ready
54
- deferOrRunSync(report, subReports, () => {
55
- let passes = 0;
56
- for (const subReport of subReports) {
57
- if (subReport.errors.length === 0) {
58
- passes++;
59
- }
60
- }
61
- if (passes === 0) {
62
- report.addError('ONE_OF_MISSING', undefined, subReports, schema, 'oneOf');
63
- }
64
- else if (passes > 1) {
65
- report.addError('ONE_OF_MULTIPLE', undefined, undefined, schema, 'oneOf');
66
- }
67
- });
68
- }
69
- // ---------------------------------------------------------------------------
70
- // not
71
- // ---------------------------------------------------------------------------
72
- export function notValidator(report, schema, json) {
73
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.6.2
74
- const subReport = new Report(report);
75
- if (this._jsonValidate(subReport, schema.not, json) === true) {
76
- report.addError('NOT_PASSED', undefined, undefined, schema, 'not');
77
- }
78
- }
79
- // ---------------------------------------------------------------------------
80
- // if / then / else
81
- // ---------------------------------------------------------------------------
82
- export function ifValidator(report, schema, json) {
83
- if (this.options.version === 'draft-04' || this.options.version === 'draft-06') {
84
- return;
85
- }
86
- const conditionSchema = schema.if;
87
- const thenSchema = schema.then;
88
- const elseSchema = schema.else;
89
- if (conditionSchema === undefined || (thenSchema === undefined && elseSchema === undefined)) {
90
- return;
91
- }
92
- const conditionReport = new Report(report);
93
- this._jsonValidate(conditionReport, conditionSchema, json);
94
- cacheValidationResult(report, conditionSchema, json, conditionReport.errors.length === 0);
95
- const branchSchema = conditionReport.errors.length === 0 ? thenSchema : elseSchema;
96
- if (branchSchema === undefined) {
97
- return;
98
- }
99
- this._jsonValidate(report, branchSchema, json);
100
- }
101
- export function thenValidator() {
102
- // handled by if
103
- }
104
- export function elseValidator() {
105
- // handled by if
106
- }
@@ -1,97 +0,0 @@
1
- import { shouldSkipValidate } from './shared.js';
2
- // ---------------------------------------------------------------------------
3
- // multipleOf
4
- // ---------------------------------------------------------------------------
5
- export function multipleOfValidator(report, schema, json) {
6
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.1.2
7
- if (shouldSkipValidate(this.validateOptions, ['MULTIPLE_OF'])) {
8
- return;
9
- }
10
- if (typeof json !== 'number') {
11
- return;
12
- }
13
- const result = json / schema.multipleOf;
14
- if (!Number.isFinite(result) || Math.abs(result - Math.round(result)) >= 1e-10) {
15
- report.addError('MULTIPLE_OF', [json, schema.multipleOf], undefined, schema, 'multipleOf');
16
- }
17
- }
18
- // ---------------------------------------------------------------------------
19
- // maximum
20
- // ---------------------------------------------------------------------------
21
- export function maximumValidator(report, schema, json) {
22
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.2.2
23
- if (shouldSkipValidate(this.validateOptions, ['MAXIMUM', 'MAXIMUM_EXCLUSIVE'])) {
24
- return;
25
- }
26
- if (typeof json !== 'number') {
27
- return;
28
- }
29
- if (schema.exclusiveMaximum !== true) {
30
- if (json > schema.maximum) {
31
- report.addError('MAXIMUM', [json, schema.maximum], undefined, schema, 'maximum');
32
- }
33
- }
34
- else {
35
- if (json >= schema.maximum) {
36
- report.addError('MAXIMUM_EXCLUSIVE', [json, schema.maximum], undefined, schema, 'maximum');
37
- }
38
- }
39
- }
40
- // ---------------------------------------------------------------------------
41
- // exclusiveMaximum
42
- // ---------------------------------------------------------------------------
43
- export function exclusiveMaximumValidator(report, schema, json) {
44
- // In draft-06+, exclusiveMaximum is a standalone number
45
- if (typeof schema.exclusiveMaximum === 'number') {
46
- if (shouldSkipValidate(this.validateOptions, ['MAXIMUM_EXCLUSIVE'])) {
47
- return;
48
- }
49
- if (typeof json !== 'number') {
50
- return;
51
- }
52
- if (json >= schema.exclusiveMaximum) {
53
- report.addError('MAXIMUM_EXCLUSIVE', [json, schema.exclusiveMaximum], undefined, schema, 'exclusiveMaximum');
54
- }
55
- }
56
- // In draft-04, exclusiveMaximum is a boolean handled inside the `maximum` validator
57
- }
58
- // ---------------------------------------------------------------------------
59
- // minimum
60
- // ---------------------------------------------------------------------------
61
- export function minimumValidator(report, schema, json) {
62
- // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.1.3.2
63
- if (shouldSkipValidate(this.validateOptions, ['MINIMUM', 'MINIMUM_EXCLUSIVE'])) {
64
- return;
65
- }
66
- if (typeof json !== 'number') {
67
- return;
68
- }
69
- if (schema.exclusiveMinimum !== true) {
70
- if (json < schema.minimum) {
71
- report.addError('MINIMUM', [json, schema.minimum], undefined, schema, 'minimum');
72
- }
73
- }
74
- else {
75
- if (json <= schema.minimum) {
76
- report.addError('MINIMUM_EXCLUSIVE', [json, schema.minimum], undefined, schema, 'minimum');
77
- }
78
- }
79
- }
80
- // ---------------------------------------------------------------------------
81
- // exclusiveMinimum
82
- // ---------------------------------------------------------------------------
83
- export function exclusiveMinimumValidator(report, schema, json) {
84
- // In draft-06+, exclusiveMinimum is a standalone number
85
- if (typeof schema.exclusiveMinimum === 'number') {
86
- if (shouldSkipValidate(this.validateOptions, ['MINIMUM_EXCLUSIVE'])) {
87
- return;
88
- }
89
- if (typeof json !== 'number') {
90
- return;
91
- }
92
- if (json <= schema.exclusiveMinimum) {
93
- report.addError('MINIMUM_EXCLUSIVE', [json, schema.exclusiveMinimum], undefined, schema, 'exclusiveMinimum');
94
- }
95
- }
96
- // In draft-04, exclusiveMinimum is a boolean handled inside the `minimum` validator
97
- }