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
@@ -0,0 +1,64 @@
1
+ import { SchemaErrorDetail } from "./report.mjs";
2
+
3
+ //#region src/errors.d.ts
4
+ type ErrorCode = keyof typeof Errors;
5
+ type ErrorParam = string | number | Array<string | number>;
6
+ declare const Errors: {
7
+ INVALID_TYPE: string;
8
+ INVALID_FORMAT: string;
9
+ ENUM_MISMATCH: string;
10
+ ENUM_CASE_MISMATCH: string;
11
+ ANY_OF_MISSING: string;
12
+ ONE_OF_MISSING: string;
13
+ ONE_OF_MULTIPLE: string;
14
+ NOT_PASSED: string;
15
+ ARRAY_LENGTH_SHORT: string;
16
+ ARRAY_LENGTH_LONG: string;
17
+ ARRAY_UNIQUE: string;
18
+ ARRAY_ADDITIONAL_ITEMS: string;
19
+ ARRAY_UNEVALUATED_ITEMS: string;
20
+ MULTIPLE_OF: string;
21
+ MINIMUM: string;
22
+ MINIMUM_EXCLUSIVE: string;
23
+ MAXIMUM: string;
24
+ MAXIMUM_EXCLUSIVE: string;
25
+ OBJECT_PROPERTIES_MINIMUM: string;
26
+ OBJECT_PROPERTIES_MAXIMUM: string;
27
+ OBJECT_MISSING_REQUIRED_PROPERTY: string;
28
+ OBJECT_ADDITIONAL_PROPERTIES: string;
29
+ OBJECT_UNEVALUATED_PROPERTIES: string;
30
+ OBJECT_DEPENDENCY_KEY: string;
31
+ MIN_LENGTH: string;
32
+ MAX_LENGTH: string;
33
+ PATTERN: string;
34
+ KEYWORD_TYPE_EXPECTED: string;
35
+ KEYWORD_UNDEFINED_STRICT: string;
36
+ KEYWORD_UNEXPECTED: string;
37
+ KEYWORD_MUST_BE: string;
38
+ KEYWORD_DEPENDENCY: string;
39
+ KEYWORD_PATTERN: string;
40
+ KEYWORD_VALUE_TYPE: string;
41
+ UNKNOWN_FORMAT: string;
42
+ CUSTOM_MODE_FORCE_PROPERTIES: string;
43
+ REF_UNRESOLVED: string;
44
+ UNRESOLVABLE_REFERENCE: string;
45
+ SCHEMA_NOT_REACHABLE: string;
46
+ SCHEMA_TYPE_EXPECTED: string;
47
+ SCHEMA_NOT_AN_OBJECT: string;
48
+ ASYNC_TIMEOUT: string;
49
+ PARENT_SCHEMA_VALIDATION_FAILED: string;
50
+ REMOTE_NOT_VALID: string;
51
+ SCHEMA_IS_FALSE: string;
52
+ CONST: string;
53
+ CONTAINS: string;
54
+ PROPERTY_NAMES: string;
55
+ COLLECT_EVALUATED_DEPTH_EXCEEDED: string;
56
+ MAX_RECURSION_DEPTH_EXCEEDED: string;
57
+ };
58
+ declare class ValidateError extends Error {
59
+ name: string;
60
+ details?: SchemaErrorDetail[];
61
+ constructor(message: string, details?: SchemaErrorDetail[]);
62
+ }
63
+ //#endregion
64
+ export { ErrorCode, ErrorParam, Errors, ValidateError };
@@ -0,0 +1,67 @@
1
+ //#region src/errors.ts
2
+ const Errors = {
3
+ INVALID_TYPE: "Expected type {0} but found type {1}",
4
+ INVALID_FORMAT: "Object didn't pass validation for format {0}: {1}",
5
+ ENUM_MISMATCH: "No enum match for: {0}",
6
+ ENUM_CASE_MISMATCH: "Enum does not match case for: {0}",
7
+ ANY_OF_MISSING: "Data does not match any schemas from 'anyOf'",
8
+ ONE_OF_MISSING: "Data does not match any schemas from 'oneOf'",
9
+ ONE_OF_MULTIPLE: "Data is valid against more than one schema from 'oneOf'",
10
+ NOT_PASSED: "Data matches schema from 'not'",
11
+ ARRAY_LENGTH_SHORT: "Array is too short ({0}), minimum {1}",
12
+ ARRAY_LENGTH_LONG: "Array is too long ({0}), maximum {1}",
13
+ ARRAY_UNIQUE: "Array items are not unique (indexes {0} and {1})",
14
+ ARRAY_ADDITIONAL_ITEMS: "Additional items not allowed",
15
+ ARRAY_UNEVALUATED_ITEMS: "Unevaluated items are not allowed",
16
+ MULTIPLE_OF: "Value {0} is not a multiple of {1}",
17
+ MINIMUM: "Value {0} is less than minimum {1}",
18
+ MINIMUM_EXCLUSIVE: "Value {0} is equal or less than exclusive minimum {1}",
19
+ MAXIMUM: "Value {0} is greater than maximum {1}",
20
+ MAXIMUM_EXCLUSIVE: "Value {0} is equal or greater than exclusive maximum {1}",
21
+ OBJECT_PROPERTIES_MINIMUM: "Too few properties defined ({0}), minimum {1}",
22
+ OBJECT_PROPERTIES_MAXIMUM: "Too many properties defined ({0}), maximum {1}",
23
+ OBJECT_MISSING_REQUIRED_PROPERTY: "Missing required property: {0}",
24
+ OBJECT_ADDITIONAL_PROPERTIES: "Additional properties not allowed: {0}",
25
+ OBJECT_UNEVALUATED_PROPERTIES: "Unevaluated properties are not allowed: {0}",
26
+ OBJECT_DEPENDENCY_KEY: "Dependency failed - key must exist: {0} (due to key: {1})",
27
+ MIN_LENGTH: "String is too short ({0} chars), minimum {1}",
28
+ MAX_LENGTH: "String is too long ({0} chars), maximum {1}",
29
+ PATTERN: "String does not match pattern {0}: {1}",
30
+ KEYWORD_TYPE_EXPECTED: "Keyword '{0}' is expected to be of type '{1}'",
31
+ KEYWORD_UNDEFINED_STRICT: "Keyword '{0}' must be defined in strict mode",
32
+ KEYWORD_UNEXPECTED: "Keyword '{0}' is not expected to appear in the schema",
33
+ KEYWORD_MUST_BE: "Keyword '{0}' must be {1}",
34
+ KEYWORD_DEPENDENCY: "Keyword '{0}' requires keyword '{1}'",
35
+ KEYWORD_PATTERN: "Keyword '{0}' is not a valid RegExp pattern: {1}",
36
+ KEYWORD_VALUE_TYPE: "Each element of keyword '{0}' array must be a '{1}'",
37
+ UNKNOWN_FORMAT: "There is no validation function for format '{0}'",
38
+ CUSTOM_MODE_FORCE_PROPERTIES: "{0} must define at least one property if present",
39
+ REF_UNRESOLVED: "Reference has not been resolved during compilation: {0}",
40
+ UNRESOLVABLE_REFERENCE: "Reference could not be resolved: {0}",
41
+ SCHEMA_NOT_REACHABLE: "Validator was not able to read schema with uri: {0}",
42
+ SCHEMA_TYPE_EXPECTED: "Schema is expected to be of type 'object'",
43
+ SCHEMA_NOT_AN_OBJECT: "Schema is not an object: {0}",
44
+ ASYNC_TIMEOUT: "{0} asynchronous task(s) have timed out after {1} ms",
45
+ PARENT_SCHEMA_VALIDATION_FAILED: "Schema failed to validate against its parent schema, see inner errors for details.",
46
+ REMOTE_NOT_VALID: "Remote reference didn't compile successfully: {0}",
47
+ SCHEMA_IS_FALSE: "Boolean schema \"false\" is always invalid.",
48
+ CONST: "Value does not match const: {0}",
49
+ CONTAINS: "Array does not contain an item matching the schema",
50
+ PROPERTY_NAMES: "Property name {0} does not match the propertyNames schema",
51
+ COLLECT_EVALUATED_DEPTH_EXCEEDED: "Schema nesting depth exceeded maximum ({0}) during unevaluated items/properties collection",
52
+ MAX_RECURSION_DEPTH_EXCEEDED: "Maximum recursion depth ({0}) exceeded. If your schema or data is deeply nested and valid, increase the maxRecursionDepth option."
53
+ };
54
+ var ValidateError = class extends Error {
55
+ name;
56
+ details;
57
+ constructor(message, details) {
58
+ super(message);
59
+ this.name = "z-schema validation error";
60
+ this.details = details;
61
+ }
62
+ };
63
+ function getValidateError({ message, details }) {
64
+ return new ValidateError(message || "", details);
65
+ }
66
+ //#endregion
67
+ export { Errors, ValidateError, getValidateError };
@@ -0,0 +1,14 @@
1
+ //#region src/format-validators.d.ts
2
+ type FormatValidatorFn = (input: unknown) => boolean | Promise<boolean>;
3
+ interface FormatValidatorsOptions {
4
+ strictUris?: boolean;
5
+ customFormats?: Record<string, FormatValidatorFn | null>;
6
+ }
7
+ declare function getFormatValidators(options?: FormatValidatorsOptions): Record<string, FormatValidatorFn>;
8
+ declare function registerFormat(name: string, validatorFunction: FormatValidatorFn): void;
9
+ declare function unregisterFormat(name: string): void;
10
+ declare function getSupportedFormats(customFormats?: Record<string, FormatValidatorFn | null>): string[];
11
+ declare function isFormatSupported(name: string, customFormats?: Record<string, FormatValidatorFn | null>): boolean;
12
+ declare function getRegisteredFormats(): string[];
13
+ //#endregion
14
+ export { FormatValidatorFn, FormatValidatorsOptions, getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat };
@@ -0,0 +1,261 @@
1
+ import { sortedKeys } from "./utils/json.mjs";
2
+ import { isValidRfc3339Date } from "./utils/date.mjs";
3
+ import { isValidHostname, isValidIdnHostname } from "./utils/hostname.mjs";
4
+ import { parseRfc3339Time } from "./utils/time.mjs";
5
+ import isEmailModule from "validator/lib/isEmail.js";
6
+ import isIPModule from "validator/lib/isIP.js";
7
+ import isURLModule from "validator/lib/isURL.js";
8
+ //#region src/format-validators.ts
9
+ const dateValidator = (date) => {
10
+ if (typeof date !== "string") return true;
11
+ const matches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(date);
12
+ if (matches === null) return false;
13
+ return isValidRfc3339Date(parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3], 10));
14
+ };
15
+ const dateTimeValidator = (dateTime) => {
16
+ if (typeof dateTime !== "string") return true;
17
+ const s = dateTime.toLowerCase().split("t");
18
+ if (s.length !== 2) return false;
19
+ const datePart = s[0];
20
+ const timePart = s[1];
21
+ const dateMatches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(datePart);
22
+ if (dateMatches === null) return false;
23
+ if (!isValidRfc3339Date(parseInt(dateMatches[1], 10), parseInt(dateMatches[2], 10), parseInt(dateMatches[3], 10))) return false;
24
+ return parseRfc3339Time(timePart) !== null;
25
+ };
26
+ const emailValidator = (email) => {
27
+ if (typeof email !== "string") return true;
28
+ if (isEmailModule.default(email, {
29
+ require_tld: true,
30
+ allow_ip_domain: true
31
+ })) return true;
32
+ const ipv6Literal = /^(.+)@\[IPv6:([^\]]+)\]$/i.exec(email);
33
+ if (!ipv6Literal) return false;
34
+ const localPart = ipv6Literal[1];
35
+ const addressPart = ipv6Literal[2];
36
+ if (!isIPModule.default(addressPart, 6)) return false;
37
+ return isEmailModule.default(`${localPart}@example.com`, { require_tld: true });
38
+ };
39
+ const hostnameValidator = (hostname) => {
40
+ if (typeof hostname !== "string") return true;
41
+ return isValidHostname(hostname);
42
+ };
43
+ const ipv4Validator = (ipv4) => {
44
+ if (typeof ipv4 !== "string") return true;
45
+ return isIPModule.default(ipv4, 4);
46
+ };
47
+ const ipv6Validator = (ipv6) => {
48
+ if (typeof ipv6 !== "string") return true;
49
+ if (ipv6.includes("%")) return false;
50
+ return isIPModule.default(ipv6, 6);
51
+ };
52
+ const regexValidator = (input) => {
53
+ if (typeof input !== "string") return true;
54
+ const invalidEscapes = new Set(["a"]);
55
+ for (let idx = 0; idx < input.length; idx++) {
56
+ if (input[idx] !== "\\") continue;
57
+ idx++;
58
+ if (idx >= input.length) return false;
59
+ const escaped = input[idx];
60
+ if (invalidEscapes.has(escaped)) return false;
61
+ }
62
+ try {
63
+ RegExp(input);
64
+ return true;
65
+ } catch (_e) {
66
+ return false;
67
+ }
68
+ };
69
+ const durationValidator = (input) => {
70
+ if (typeof input !== "string") return true;
71
+ if (!/^P[\x00-\x7F]*$/.test(input)) return false;
72
+ if (!input.startsWith("P")) return false;
73
+ const body = input.slice(1);
74
+ if (body.length === 0) return false;
75
+ if (body.includes("W")) return /^\d+W$/.test(body);
76
+ const parts = body.split("T");
77
+ if (parts.length > 2) return false;
78
+ const datePart = parts[0];
79
+ const timePart = parts.length === 2 ? parts[1] : void 0;
80
+ if (datePart.length > 0 && !/^(?:\d+Y(?:\d+M(?:\d+D)?)?|\d+M(?:\d+D)?|\d+D)$/.test(datePart)) return false;
81
+ const hasDateComponent = /\d+[YMD]/.test(datePart);
82
+ let hasTimeComponent = false;
83
+ if (timePart !== void 0) {
84
+ if (timePart.length === 0) return false;
85
+ if (!/^(?:\d+H(?:\d+M(?:\d+S)?)?|\d+M(?:\d+S)?|\d+S)$/.test(timePart)) return false;
86
+ hasTimeComponent = /\d+[HMS]/.test(timePart);
87
+ if (!hasTimeComponent) return false;
88
+ }
89
+ return hasDateComponent || hasTimeComponent;
90
+ };
91
+ const uuidValidator = (input) => {
92
+ if (typeof input !== "string") return true;
93
+ return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(input);
94
+ };
95
+ const strictUriValidator = (uri) => typeof uri !== "string" || isURLModule.default(uri);
96
+ const hasValidPercentEncoding = (str) => {
97
+ for (let i = 0; i < str.length; i++) if (str[i] === "%") {
98
+ if (i + 2 >= str.length || !/[0-9a-fA-F]/.test(str[i + 1]) || !/[0-9a-fA-F]/.test(str[i + 2])) return false;
99
+ }
100
+ return true;
101
+ };
102
+ const uriValidator = function(uri) {
103
+ if (typeof uri !== "string") return true;
104
+ if (/[^\x00-\x7F]/.test(uri)) return false;
105
+ if (!hasValidPercentEncoding(uri)) return false;
106
+ const match = uri.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):\/\/([^/?#]*)/);
107
+ if (match) {
108
+ const authority = match[2];
109
+ const atIndex = authority.indexOf("@");
110
+ if (atIndex > 0) {
111
+ const userinfo = authority.substring(0, atIndex);
112
+ if (userinfo.includes("[") || userinfo.includes("]")) return false;
113
+ }
114
+ let hostPort = atIndex >= 0 ? authority.substring(atIndex + 1) : authority;
115
+ if (hostPort.startsWith("[")) {
116
+ const bracketEnd = hostPort.indexOf("]");
117
+ if (bracketEnd >= 0) hostPort = hostPort.substring(bracketEnd + 1);
118
+ }
119
+ const colonIndex = hostPort.lastIndexOf(":");
120
+ if (colonIndex >= 0) {
121
+ const port = hostPort.substring(colonIndex + 1);
122
+ if (port.length > 0 && !/^\d+$/.test(port)) return false;
123
+ }
124
+ }
125
+ return /^[a-zA-Z][a-zA-Z0-9+.-]*:[^"\\<>^{}^`| ]*$/.test(uri);
126
+ };
127
+ const uriReferenceValidator = (uri) => {
128
+ if (typeof uri !== "string") return true;
129
+ if (/[^\x00-\x7F]/.test(uri)) return false;
130
+ return /^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/.test(uri);
131
+ };
132
+ const uriTemplateValidator = (uri) => {
133
+ if (typeof uri !== "string") return true;
134
+ if (!/^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^`| ]*$/.test(uri)) return false;
135
+ let inExpression = false;
136
+ for (let idx = 0; idx < uri.length; idx++) {
137
+ const ch = uri[idx];
138
+ if (ch === "{") {
139
+ if (inExpression) return false;
140
+ inExpression = true;
141
+ } else if (ch === "}") {
142
+ if (!inExpression) return false;
143
+ inExpression = false;
144
+ }
145
+ }
146
+ return !inExpression;
147
+ };
148
+ const hasValidTildeEscapes = (segment) => {
149
+ for (let i = 0; i < segment.length; i++) if (segment[i] === "~") {
150
+ const next = segment[i + 1];
151
+ if (next !== "0" && next !== "1") return false;
152
+ i++;
153
+ }
154
+ return true;
155
+ };
156
+ const jsonPointerValidator = (pointer) => {
157
+ if (typeof pointer !== "string") return true;
158
+ if (pointer === "") return true;
159
+ if (!/^(?:\/[^/]*)+$/.test(pointer)) return false;
160
+ const tokens = pointer.split("/").slice(1);
161
+ for (const token of tokens) if (!hasValidTildeEscapes(token)) return false;
162
+ return true;
163
+ };
164
+ const relativeJsonPointerValidator = (pointer) => {
165
+ if (typeof pointer !== "string") return true;
166
+ const match = pointer.match(/^(0|[1-9]\d*)(.*)$/);
167
+ if (!match) return false;
168
+ const suffix = match[2];
169
+ if (suffix === "" || suffix === "#") return true;
170
+ if (!suffix.startsWith("/")) return false;
171
+ if (!/^(?:\/[^/]*)+$/.test(suffix)) return false;
172
+ const tokens = suffix.split("/").slice(1);
173
+ for (const token of tokens) if (!hasValidTildeEscapes(token)) return false;
174
+ return true;
175
+ };
176
+ const timeValidator = (time) => {
177
+ if (typeof time !== "string") return true;
178
+ return parseRfc3339Time(time) !== null;
179
+ };
180
+ const idnEmailValidator = (email) => {
181
+ if (typeof email !== "string") return true;
182
+ return /^[^\s@]+@[^\s@]+$/.test(email);
183
+ };
184
+ const idnHostnameValidator = (hostname) => {
185
+ if (typeof hostname !== "string") return true;
186
+ return isValidIdnHostname(hostname);
187
+ };
188
+ const iriValidator = (iri) => {
189
+ if (typeof iri !== "string") return true;
190
+ if (!/^[a-zA-Z][a-zA-Z0-9+.-]*:[^"\\<>^{}^`| ]*$/u.test(iri)) return false;
191
+ try {
192
+ new URL(iri);
193
+ return true;
194
+ } catch (_e) {
195
+ return false;
196
+ }
197
+ };
198
+ const iriReferenceValidator = (iriReference) => {
199
+ if (typeof iriReference !== "string") return true;
200
+ return /^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/u.test(iriReference);
201
+ };
202
+ const inbuiltValidators = {
203
+ date: dateValidator,
204
+ "date-time": dateTimeValidator,
205
+ email: emailValidator,
206
+ hostname: hostnameValidator,
207
+ "host-name": hostnameValidator,
208
+ ipv4: ipv4Validator,
209
+ ipv6: ipv6Validator,
210
+ regex: regexValidator,
211
+ uri: uriValidator,
212
+ "strict-uri": strictUriValidator,
213
+ "uri-reference": uriReferenceValidator,
214
+ "uri-template": uriTemplateValidator,
215
+ "json-pointer": jsonPointerValidator,
216
+ "relative-json-pointer": relativeJsonPointerValidator,
217
+ time: timeValidator,
218
+ "idn-email": idnEmailValidator,
219
+ "idn-hostname": idnHostnameValidator,
220
+ iri: iriValidator,
221
+ "iri-reference": iriReferenceValidator,
222
+ duration: durationValidator,
223
+ uuid: uuidValidator
224
+ };
225
+ const customValidators = {};
226
+ function getFormatValidators(options) {
227
+ return {
228
+ ...inbuiltValidators,
229
+ ...options?.strictUris ? { uri: strictUriValidator } : {},
230
+ ...customValidators,
231
+ ...options?.customFormats || {}
232
+ };
233
+ }
234
+ function registerFormat(name, validatorFunction) {
235
+ customValidators[name] = validatorFunction;
236
+ }
237
+ function unregisterFormat(name) {
238
+ delete customValidators[name];
239
+ }
240
+ function getSupportedFormats(customFormats) {
241
+ const merged = {
242
+ ...inbuiltValidators,
243
+ ...customValidators,
244
+ ...customFormats
245
+ };
246
+ return sortedKeys(merged).filter((key) => merged[key] != null);
247
+ }
248
+ function isFormatSupported(name, customFormats) {
249
+ if (customFormats) {
250
+ const custom = customFormats[name];
251
+ if (custom === null) return false;
252
+ if (custom != null) return true;
253
+ }
254
+ if (name in customValidators) return customValidators[name] != null;
255
+ return name in inbuiltValidators;
256
+ }
257
+ function getRegisteredFormats() {
258
+ return sortedKeys(customValidators);
259
+ }
260
+ //#endregion
261
+ export { getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat };
@@ -0,0 +1,10 @@
1
+ import { FormatValidatorFn, FormatValidatorsOptions, getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat } from "./format-validators.mjs";
2
+ import { ZSchemaOptions } from "./z-schema-options.mjs";
3
+ import { Report, SchemaErrorDetail } from "./report.mjs";
4
+ import { ErrorCode, ErrorParam, Errors, ValidateError } from "./errors.mjs";
5
+ import { ValidateOptions, ValidateResponse } from "./z-schema-base.mjs";
6
+ import { JsonSchemaCommon, JsonSchemaType } from "./json-schema.mjs";
7
+ import { JsonSchema, JsonSchemaDraft201909, JsonSchemaDraft202012, JsonSchemaDraft4, JsonSchemaDraft6, JsonSchemaDraft7, JsonSchemaVersion } from "./json-schema-versions.mjs";
8
+ import { SchemaReader } from "./z-schema-reader.mjs";
9
+ import { ZSchema, ZSchemaAsync, ZSchemaAsyncSafe, ZSchemaSafe } from "./z-schema.mjs";
10
+ export { type ErrorCode, type ErrorParam, type Errors, type FormatValidatorFn, type FormatValidatorsOptions, type JsonSchema, type JsonSchemaCommon, type JsonSchemaDraft201909, type JsonSchemaDraft202012, type JsonSchemaDraft4, type JsonSchemaDraft6, type JsonSchemaDraft7, type JsonSchemaType, type JsonSchemaVersion, type Report, type SchemaErrorDetail, type SchemaReader, ValidateError, type ValidateOptions, type ValidateResponse, type ZSchema, type ZSchemaAsync, type ZSchemaAsyncSafe, type ZSchemaOptions, type ZSchemaSafe, ZSchema as default, getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat };
package/dist/index.mjs ADDED
@@ -0,0 +1,7 @@
1
+ import { ValidateError } from "./errors.mjs";
2
+ import { getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat } from "./format-validators.mjs";
3
+ import { ZSchema } from "./z-schema.mjs";
4
+ //#region src/index.ts
5
+ var src_default = ZSchema;
6
+ //#endregion
7
+ export { ValidateError, src_default as default, getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat };
@@ -0,0 +1,137 @@
1
+ import { JsonSchemaCommon, ZSchemaInternalProperties } from "./json-schema.mjs";
2
+
3
+ //#region src/json-schema-versions.d.ts
4
+ type JsonSchemaVersion = 'draft-04' | 'draft-06' | 'draft-07' | 'draft2019-09' | 'draft2020-12';
5
+ /** Union of all draft-specific schema interfaces — the public API type. */
6
+ type JsonSchema = JsonSchemaDraft4 | JsonSchemaDraft6 | JsonSchemaDraft7 | JsonSchemaDraft201909 | JsonSchemaDraft202012;
7
+ /**
8
+ * Superset of ALL draft-specific properties with the widest possible types.
9
+ * Use inside the validator where the active draft is not known at compile time.
10
+ *
11
+ * NOTE: this is a manually defined interface (not a computed intersection)
12
+ * because `exclusiveMinimum` is `boolean` in Draft-04 and `number` in
13
+ * Draft-06+, which would yield `never` in a plain intersection.
14
+ */
15
+ interface JsonSchemaAll extends JsonSchemaCommon {
16
+ /** Pre-`$id` identifier (draft-04 only). */
17
+ id?: string;
18
+ /** Schema identifier (replaces `id` from draft-06 onward). */
19
+ $id?: string;
20
+ const?: unknown;
21
+ contains?: JsonSchema;
22
+ propertyNames?: JsonSchema;
23
+ examples?: unknown[];
24
+ if?: JsonSchema | boolean;
25
+ then?: JsonSchema | boolean;
26
+ else?: JsonSchema | boolean;
27
+ contentEncoding?: string;
28
+ contentMediaType?: string;
29
+ $defs?: Record<string, JsonSchema>;
30
+ $anchor?: string;
31
+ $vocabulary?: Record<string, boolean>;
32
+ $recursiveAnchor?: boolean;
33
+ $recursiveRef?: string;
34
+ dependentSchemas?: Record<string, JsonSchema>;
35
+ dependentRequired?: Record<string, string[]>;
36
+ unevaluatedItems?: JsonSchema | boolean;
37
+ unevaluatedProperties?: JsonSchema | boolean;
38
+ maxContains?: number;
39
+ minContains?: number;
40
+ $dynamicAnchor?: string;
41
+ $dynamicRef?: string;
42
+ prefixItems?: Array<JsonSchema | boolean>;
43
+ }
44
+ /**
45
+ * Internal schema type used throughout the validator. Based on `JsonSchemaAll`
46
+ * so that validators can access any draft-specific property without narrowing.
47
+ */
48
+ type JsonSchemaInternal = JsonSchemaAll & ZSchemaInternalProperties;
49
+ /**
50
+ * JSON Schema Draft-04.
51
+ *
52
+ * Key differences from later drafts:
53
+ * - Uses `id` instead of `$id`.
54
+ * - `exclusiveMinimum`/`exclusiveMaximum` are boolean modifiers on `minimum`/`maximum`
55
+ * (inherited as `boolean | number` from `JsonSchemaCommon` for cross-draft compatibility).
56
+ * - No `const`, `contains`, `propertyNames`, `examples`, `if`/`then`/`else`.
57
+ *
58
+ * @see https://json-schema.org/draft-04/draft-zyp-json-schema-04
59
+ */
60
+ interface JsonSchemaDraft4 extends JsonSchemaCommon {
61
+ /** Schema identifier (draft-04). Replaced by `$id` in draft-06+. */
62
+ id?: string;
63
+ }
64
+ /**
65
+ * JSON Schema Draft-06.
66
+ *
67
+ * Additions over Draft-04:
68
+ * - `$id` replaces `id`.
69
+ * - `exclusiveMinimum`/`exclusiveMaximum` changed to standalone `number` values.
70
+ * - Added `const`, `contains`, `propertyNames`, `examples`.
71
+ *
72
+ * @see https://json-schema.org/draft-06/draft-wright-json-schema-validation-01
73
+ */
74
+ interface JsonSchemaDraft6 extends JsonSchemaCommon {
75
+ $id?: string;
76
+ const?: unknown;
77
+ contains?: JsonSchema;
78
+ propertyNames?: JsonSchema;
79
+ examples?: unknown[];
80
+ }
81
+ /**
82
+ * JSON Schema Draft-07.
83
+ *
84
+ * Additions over Draft-06:
85
+ * - `if`/`then`/`else` conditional applicators.
86
+ * - `contentEncoding`, `contentMediaType`.
87
+ *
88
+ * @see https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01
89
+ */
90
+ interface JsonSchemaDraft7 extends JsonSchemaDraft6 {
91
+ if?: JsonSchema | boolean;
92
+ then?: JsonSchema | boolean;
93
+ else?: JsonSchema | boolean;
94
+ contentEncoding?: string;
95
+ contentMediaType?: string;
96
+ }
97
+ /**
98
+ * JSON Schema Draft 2019-09.
99
+ *
100
+ * Additions over Draft-07:
101
+ * - `$defs` (replaces `definitions`), `$anchor`, `$vocabulary`.
102
+ * - `$recursiveAnchor`/`$recursiveRef` for recursive references.
103
+ * - `dependentSchemas`/`dependentRequired` (split from `dependencies`).
104
+ * - `unevaluatedItems`/`unevaluatedProperties`.
105
+ * - `maxContains`/`minContains`.
106
+ *
107
+ * @see https://json-schema.org/draft/2019-09/release-notes
108
+ */
109
+ interface JsonSchemaDraft201909 extends JsonSchemaDraft7 {
110
+ $defs?: Record<string, JsonSchema>;
111
+ $anchor?: string;
112
+ $vocabulary?: Record<string, boolean>;
113
+ $recursiveAnchor?: boolean;
114
+ $recursiveRef?: string;
115
+ dependentSchemas?: Record<string, JsonSchema>;
116
+ dependentRequired?: Record<string, string[]>;
117
+ unevaluatedItems?: JsonSchema | boolean;
118
+ unevaluatedProperties?: JsonSchema | boolean;
119
+ maxContains?: number;
120
+ minContains?: number;
121
+ }
122
+ /**
123
+ * JSON Schema Draft 2020-12.
124
+ *
125
+ * Additions over Draft 2019-09:
126
+ * - `$dynamicAnchor`/`$dynamicRef` replace `$recursiveAnchor`/`$recursiveRef`.
127
+ * - `prefixItems` replaces the array form of `items`.
128
+ *
129
+ * @see https://json-schema.org/draft/2020-12/release-notes
130
+ */
131
+ interface JsonSchemaDraft202012 extends JsonSchemaDraft201909 {
132
+ $dynamicAnchor?: string;
133
+ $dynamicRef?: string;
134
+ prefixItems?: Array<JsonSchema | boolean>;
135
+ }
136
+ //#endregion
137
+ export { JsonSchema, JsonSchemaAll, JsonSchemaDraft201909, JsonSchemaDraft202012, JsonSchemaDraft4, JsonSchemaDraft6, JsonSchemaDraft7, JsonSchemaInternal, JsonSchemaVersion };
@@ -0,0 +1,11 @@
1
+ //#region src/json-schema-versions.ts
2
+ const CURRENT_DEFAULT_SCHEMA_VERSION = "draft2020-12";
3
+ const VERSION_SCHEMA_URL_MAPPING = {
4
+ "draft-04": "http://json-schema.org/draft-04/schema#",
5
+ "draft-06": "http://json-schema.org/draft-06/schema#",
6
+ "draft-07": "http://json-schema.org/draft-07/schema#",
7
+ "draft2019-09": "https://json-schema.org/draft/2019-09/schema",
8
+ "draft2020-12": "https://json-schema.org/draft/2020-12/schema"
9
+ };
10
+ //#endregion
11
+ export { CURRENT_DEFAULT_SCHEMA_VERSION, VERSION_SCHEMA_URL_MAPPING };
@@ -0,0 +1,61 @@
1
+ import { ZSchemaOptions } from "./z-schema-options.mjs";
2
+ import { Reference } from "./schema-compiler.mjs";
3
+ import { JsonSchema, JsonSchemaInternal } from "./json-schema-versions.mjs";
4
+
5
+ //#region src/json-schema.d.ts
6
+ /**
7
+ * Properties present in ALL JSON Schema drafts (04 through 2020-12) with
8
+ * identical types. Draft-specific additions live on the individual draft
9
+ * interfaces in `json-schema-versions.ts`.
10
+ */
11
+ interface JsonSchemaCommon {
12
+ $ref?: string;
13
+ $schema?: string;
14
+ title?: string;
15
+ description?: string;
16
+ default?: unknown;
17
+ type?: string | string[];
18
+ enum?: Array<unknown>;
19
+ format?: string;
20
+ multipleOf?: number;
21
+ minimum?: number;
22
+ maximum?: number;
23
+ /** Draft-04: `boolean` modifier on `minimum`/`maximum`. Draft-06+: standalone `number`. */
24
+ exclusiveMinimum?: boolean | number;
25
+ /** Draft-04: `boolean` modifier on `minimum`/`maximum`. Draft-06+: standalone `number`. */
26
+ exclusiveMaximum?: boolean | number;
27
+ minLength?: number;
28
+ maxLength?: number;
29
+ pattern?: string;
30
+ items?: JsonSchema | boolean | Array<JsonSchema | boolean>;
31
+ additionalItems?: boolean | JsonSchema;
32
+ minItems?: number;
33
+ maxItems?: number;
34
+ uniqueItems?: boolean;
35
+ properties?: Record<string, JsonSchema | boolean>;
36
+ patternProperties?: Record<string, JsonSchema>;
37
+ additionalProperties?: boolean | JsonSchema;
38
+ required?: string[];
39
+ minProperties?: number;
40
+ maxProperties?: number;
41
+ dependencies?: Record<string, string[] | JsonSchema>;
42
+ allOf?: JsonSchema[];
43
+ anyOf?: JsonSchema[];
44
+ oneOf?: JsonSchema[];
45
+ not?: JsonSchema;
46
+ definitions?: Record<string, JsonSchema>;
47
+ }
48
+ type JsonSchemaType = 'array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string';
49
+ interface ZSchemaInternalProperties {
50
+ __$compiled?: unknown;
51
+ __$missingReferences?: Reference[];
52
+ __$refResolved?: JsonSchema;
53
+ __$dynamicRefResolved?: JsonSchema;
54
+ __$recursiveRefResolved?: JsonSchema;
55
+ __$resourceRoot?: JsonSchemaInternal;
56
+ __$schemaResolved?: unknown;
57
+ __$validated?: boolean;
58
+ __$validationOptions?: ZSchemaOptions;
59
+ }
60
+ //#endregion
61
+ export { JsonSchemaCommon, JsonSchemaType, ZSchemaInternalProperties };