z-schema 12.1.1 → 12.3.1

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 (110) hide show
  1. package/README.md +2 -2
  2. package/bin/z-schema +4 -5
  3. package/cjs/{index.js → index.cjs} +696 -687
  4. package/cjs/{index.d.ts → index.d.cts} +47 -26
  5. package/dist/{errors.d.mts → errors.d.ts} +2 -2
  6. package/dist/{errors.mjs → errors.js} +1 -2
  7. package/dist/{format-validators.mjs → format-validators.js} +43 -36
  8. package/dist/{index.d.mts → index.d.ts} +9 -9
  9. package/dist/{index.mjs → index.js} +3 -3
  10. package/dist/{json-schema-versions.d.mts → json-schema-versions.d.ts} +34 -3
  11. package/dist/{json-schema.d.mts → json-schema.d.ts} +7 -7
  12. package/dist/{json-schema.mjs → json-schema.js} +7 -12
  13. package/dist/{json-validation.mjs → json-validation.js} +143 -127
  14. package/dist/{report.d.mts → report.d.ts} +7 -8
  15. package/dist/{report.mjs → report.js} +28 -31
  16. package/dist/{schema-cache.d.mts → schema-cache.d.ts} +4 -4
  17. package/dist/{schema-cache.mjs → schema-cache.js} +10 -11
  18. package/dist/{schema-compiler.d.mts → schema-compiler.d.ts} +4 -4
  19. package/dist/{schema-compiler.mjs → schema-compiler.js} +95 -77
  20. package/dist/{schema-validator.d.mts → schema-validator.d.ts} +5 -5
  21. package/dist/{schema-validator.mjs → schema-validator.js} +138 -166
  22. package/dist/utils/{array.mjs → array.js} +4 -3
  23. package/dist/utils/{base64.mjs → base64.js} +3 -2
  24. package/dist/utils/{clone.mjs → clone.js} +18 -20
  25. package/dist/utils/{hostname.mjs → hostname.js} +19 -22
  26. package/dist/utils/{json.mjs → json.js} +11 -7
  27. package/dist/utils/{schema-regex.mjs → schema-regex.js} +5 -5
  28. package/dist/utils/{time.mjs → time.js} +5 -5
  29. package/dist/utils/unicode.js +22 -0
  30. package/dist/utils/{what-is.mjs → what-is.js} +1 -2
  31. package/dist/validation/{array.mjs → array.js} +18 -20
  32. package/dist/validation/{combinators.mjs → combinators.js} +16 -16
  33. package/dist/validation/{numeric.mjs → numeric.js} +11 -11
  34. package/dist/validation/{object.mjs → object.js} +35 -34
  35. package/dist/validation/{ref.mjs → ref.js} +4 -4
  36. package/dist/validation/{shared.mjs → shared.js} +12 -11
  37. package/dist/validation/{string.mjs → string.js} +32 -32
  38. package/dist/validation/type.js +34 -0
  39. package/dist/{z-schema-base.d.mts → z-schema-base.d.ts} +11 -12
  40. package/dist/{z-schema-base.mjs → z-schema-base.js} +45 -40
  41. package/dist/{z-schema-options.d.mts → z-schema-options.d.ts} +3 -3
  42. package/dist/{z-schema-options.mjs → z-schema-options.js} +4 -4
  43. package/dist/{z-schema-reader.d.mts → z-schema-reader.d.ts} +1 -1
  44. package/dist/{z-schema-versions.mjs → z-schema-versions.js} +21 -21
  45. package/dist/{z-schema.d.mts → z-schema.d.ts} +5 -13
  46. package/dist/{z-schema.mjs → z-schema.js} +37 -47
  47. package/package.json +25 -23
  48. package/src/errors.ts +1 -2
  49. package/src/format-validators.ts +139 -59
  50. package/src/json-schema-versions.ts +56 -2
  51. package/src/json-schema.ts +10 -9
  52. package/src/json-validation.ts +189 -146
  53. package/src/report.ts +37 -49
  54. package/src/schema-cache.ts +13 -13
  55. package/src/schema-compiler.ts +170 -117
  56. package/src/schema-validator.ts +239 -238
  57. package/src/utils/array.ts +9 -6
  58. package/src/utils/base64.ts +13 -2
  59. package/src/utils/clone.ts +28 -30
  60. package/src/utils/date.ts +6 -3
  61. package/src/utils/hostname.ts +27 -27
  62. package/src/utils/json.ts +16 -9
  63. package/src/utils/properties.ts +2 -2
  64. package/src/utils/schema-regex.ts +4 -4
  65. package/src/utils/time.ts +5 -5
  66. package/src/utils/unicode.ts +12 -5
  67. package/src/utils/what-is.ts +1 -5
  68. package/src/validation/array.ts +24 -22
  69. package/src/validation/combinators.ts +14 -14
  70. package/src/validation/numeric.ts +14 -28
  71. package/src/validation/object.ts +32 -36
  72. package/src/validation/ref.ts +5 -6
  73. package/src/validation/shared.ts +22 -21
  74. package/src/validation/string.ts +29 -39
  75. package/src/validation/type.ts +17 -17
  76. package/src/z-schema-base.ts +49 -38
  77. package/src/z-schema-options.ts +4 -3
  78. package/src/z-schema.ts +35 -45
  79. package/umd/ZSchema.js +723 -697
  80. package/umd/ZSchema.min.js +2 -2
  81. package/umd/package.json +3 -0
  82. package/dist/utils/unicode.mjs +0 -12
  83. package/dist/validation/type.mjs +0 -32
  84. /package/dist/{format-validators.d.mts → format-validators.d.ts} +0 -0
  85. /package/dist/{json-schema-versions.mjs → json-schema-versions.js} +0 -0
  86. /package/dist/schemas/{draft-04-schema.mjs → draft-04-schema.js} +0 -0
  87. /package/dist/schemas/{draft-06-schema.mjs → draft-06-schema.js} +0 -0
  88. /package/dist/schemas/{draft-07-schema.mjs → draft-07-schema.js} +0 -0
  89. /package/dist/schemas/{draft-2019-09-meta-applicator.mjs → draft-2019-09-meta-applicator.js} +0 -0
  90. /package/dist/schemas/{draft-2019-09-meta-content.mjs → draft-2019-09-meta-content.js} +0 -0
  91. /package/dist/schemas/{draft-2019-09-meta-core.mjs → draft-2019-09-meta-core.js} +0 -0
  92. /package/dist/schemas/{draft-2019-09-meta-format.mjs → draft-2019-09-meta-format.js} +0 -0
  93. /package/dist/schemas/{draft-2019-09-meta-meta-data.mjs → draft-2019-09-meta-meta-data.js} +0 -0
  94. /package/dist/schemas/{draft-2019-09-meta-validation.mjs → draft-2019-09-meta-validation.js} +0 -0
  95. /package/dist/schemas/{draft-2019-09-schema.mjs → draft-2019-09-schema.js} +0 -0
  96. /package/dist/schemas/{draft-2020-12-meta-applicator.mjs → draft-2020-12-meta-applicator.js} +0 -0
  97. /package/dist/schemas/{draft-2020-12-meta-content.mjs → draft-2020-12-meta-content.js} +0 -0
  98. /package/dist/schemas/{draft-2020-12-meta-core.mjs → draft-2020-12-meta-core.js} +0 -0
  99. /package/dist/schemas/{draft-2020-12-meta-format-annotation.mjs → draft-2020-12-meta-format-annotation.js} +0 -0
  100. /package/dist/schemas/{draft-2020-12-meta-format-assertion.mjs → draft-2020-12-meta-format-assertion.js} +0 -0
  101. /package/dist/schemas/{draft-2020-12-meta-meta-data.mjs → draft-2020-12-meta-meta-data.js} +0 -0
  102. /package/dist/schemas/{draft-2020-12-meta-unevaluated.mjs → draft-2020-12-meta-unevaluated.js} +0 -0
  103. /package/dist/schemas/{draft-2020-12-meta-validation.mjs → draft-2020-12-meta-validation.js} +0 -0
  104. /package/dist/schemas/{draft-2020-12-schema.mjs → draft-2020-12-schema.js} +0 -0
  105. /package/dist/utils/{constants.mjs → constants.js} +0 -0
  106. /package/dist/utils/{date.mjs → date.js} +0 -0
  107. /package/dist/utils/{properties.mjs → properties.js} +0 -0
  108. /package/dist/utils/{symbols.mjs → symbols.js} +0 -0
  109. /package/dist/utils/{uri.mjs → uri.js} +0 -0
  110. /package/dist/{z-schema-reader.mjs → z-schema-reader.js} +0 -0
@@ -109,11 +109,10 @@ declare class Report {
109
109
  options: ZSchemaOptions;
110
110
  reportOptions: ReportOptions;
111
111
  validateOptions: ValidateOptions;
112
- constructor(zschemaOptions: ZSchemaOptions, validateOptions?: ValidateOptions);
113
- constructor(parentReport: Report, validateOptions?: ValidateOptions);
112
+ constructor(parentOrOptions: ZSchemaOptions | Report, validateOptions?: ValidateOptions);
114
113
  constructor(parentReport: Report, reportOptions: ReportOptions, validateOptions?: ValidateOptions);
115
114
  isValid(): boolean;
116
- addAsyncTask<FV, FN extends (...args: any[]) => FV>(fn: FN, args: Parameters<FN>, asyncTaskResultProcessFn: (result: ReturnType<FN>) => void): void;
115
+ addAsyncTask<FN extends (...args: any[]) => any>(fn: FN, args: Parameters<FN>, asyncTaskResultProcessFn: (result: ReturnType<FN>) => void): void;
117
116
  /**
118
117
  * Like {@link addAsyncTask}, but automatically saves the current `path` and
119
118
  * restores it around `processFn`. This eliminates the manual
@@ -126,7 +125,7 @@ declare class Report {
126
125
  getPath(returnPathAsString?: boolean): string | (string | number)[];
127
126
  getSchemaPath(): Array<string | number>;
128
127
  getSchemaId(): string | undefined;
129
- hasError(errCode: string, errParams: Array<any>): boolean;
128
+ hasError(errCode: string, errParams: any[]): boolean;
130
129
  addError(errCode: ErrorCode, errParams?: ErrorParam[], subReports?: Report | Report[], schema?: JsonSchema | boolean, keyword?: keyof JsonSchemaAll): void;
131
130
  getJson(): unknown;
132
131
  addCustomError(errorCode: ErrorCode, errorMessage: string, params?: ErrorParam[], subReports?: Report | Report[], schema?: JsonSchema | boolean, keyword?: keyof JsonSchemaAll): void;
@@ -188,7 +187,7 @@ declare const Errors: {
188
187
  MAX_RECURSION_DEPTH_EXCEEDED: string;
189
188
  };
190
189
  declare class ValidateError extends Error {
191
- name: string;
190
+ readonly name: string;
192
191
  details?: SchemaErrorDetail[];
193
192
  constructor(message: string, details?: SchemaErrorDetail[]);
194
193
  }
@@ -196,9 +195,9 @@ declare class ValidateError extends Error {
196
195
  //#region src/schema-cache.d.ts
197
196
  type SchemaCacheStorage = Record<string, JsonSchemaInternal>;
198
197
  declare class SchemaCache {
199
- private validator;
200
198
  static global_cache: SchemaCacheStorage;
201
199
  cache: SchemaCacheStorage;
200
+ private readonly validator;
202
201
  constructor(validator: ZSchemaBase);
203
202
  static cacheSchemaByUri(uri: string, schema: JsonSchemaInternal): void;
204
203
  cacheSchemaByUri(uri: string, schema: JsonSchemaInternal): void;
@@ -213,7 +212,7 @@ declare class SchemaCache {
213
212
  //#endregion
214
213
  //#region src/schema-validator.d.ts
215
214
  declare class SchemaValidator {
216
- private validator;
215
+ private readonly validator;
217
216
  constructor(validator: ZSchemaBase);
218
217
  get options(): ZSchemaOptions;
219
218
  validateArrayOfSchemas(report: Report, arr: Array<JsonSchemaInternal | boolean>): boolean;
@@ -226,10 +225,10 @@ interface ValidateOptions {
226
225
  includeErrors?: Array<keyof typeof Errors>;
227
226
  excludeErrors?: Array<keyof typeof Errors>;
228
227
  }
229
- type ValidateResponse = {
228
+ interface ValidateResponse {
230
229
  valid: boolean;
231
230
  err?: ValidateError;
232
- };
231
+ }
233
232
  type ValidateCallback = (err: ValidateResponse['err'], valid: ValidateResponse['valid']) => void;
234
233
  declare class ZSchemaBase {
235
234
  scache: SchemaCache;
@@ -249,8 +248,7 @@ declare class ZSchemaBase {
249
248
  getDefaultSchemaId(): string;
250
249
  _validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions, callback: ValidateCallback): void;
251
250
  _validate(json: unknown, schema: JsonSchema | string, callback: ValidateCallback): void;
252
- _validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions): true;
253
- _validate(json: unknown, schema: JsonSchema | string): true;
251
+ _validate(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): true;
254
252
  _validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): true;
255
253
  /**
256
254
  * Register a format validator on this instance only (does not affect other instances or the global registry).
@@ -303,7 +301,7 @@ interface Reference {
303
301
  path: Array<string | number>;
304
302
  }
305
303
  declare class SchemaCompiler {
306
- private validator;
304
+ private readonly validator;
307
305
  constructor(validator: ZSchemaBase);
308
306
  collectAndCacheIds(schema: JsonSchemaInternal): void;
309
307
  compileSchema(report: Report, schema: JsonSchemaInternal | JsonSchemaInternal[], options?: {
@@ -326,7 +324,7 @@ interface JsonSchemaCommon {
326
324
  description?: string;
327
325
  default?: unknown;
328
326
  type?: string | string[];
329
- enum?: Array<unknown>;
327
+ enum?: unknown[];
330
328
  format?: string;
331
329
  multipleOf?: number;
332
330
  minimum?: number;
@@ -360,9 +358,9 @@ type JsonSchemaType = 'array' | 'boolean' | 'integer' | 'null' | 'number' | 'obj
360
358
  interface ZSchemaInternalProperties {
361
359
  __$compiled?: unknown;
362
360
  __$missingReferences?: Reference[];
363
- __$refResolved?: JsonSchema;
364
- __$dynamicRefResolved?: JsonSchema;
365
- __$recursiveRefResolved?: JsonSchema;
361
+ __$refResolved?: JsonSchemaInternal;
362
+ __$dynamicRefResolved?: JsonSchemaInternal;
363
+ __$recursiveRefResolved?: JsonSchemaInternal;
366
364
  __$resourceRoot?: JsonSchemaInternal;
367
365
  __$schemaResolved?: unknown;
368
366
  __$validated?: boolean;
@@ -410,11 +408,42 @@ interface JsonSchemaAll extends JsonSchemaCommon {
410
408
  $dynamicRef?: string;
411
409
  prefixItems?: Array<JsonSchema | boolean>;
412
410
  }
411
+ /**
412
+ * Sub-schema-valued keywords. On the internal type these point at
413
+ * `JsonSchemaInternal` (rather than the public `JsonSchema`) so the validator
414
+ * can traverse nested schemas without asserting `as JsonSchemaInternal` at
415
+ * every step.
416
+ */
417
+ type InternalSchemaKeys = 'items' | 'additionalItems' | 'properties' | 'patternProperties' | 'additionalProperties' | 'dependencies' | 'allOf' | 'anyOf' | 'oneOf' | 'not' | 'definitions' | 'contains' | 'propertyNames' | 'if' | 'then' | 'else' | '$defs' | 'dependentSchemas' | 'unevaluatedItems' | 'unevaluatedProperties' | 'prefixItems';
413
418
  /**
414
419
  * Internal schema type used throughout the validator. Based on `JsonSchemaAll`
415
- * so that validators can access any draft-specific property without narrowing.
420
+ * so that validators can access any draft-specific property without narrowing,
421
+ * but with every sub-schema keyword re-typed to `JsonSchemaInternal` so nested
422
+ * traversal needs no type assertions.
416
423
  */
417
- type JsonSchemaInternal = JsonSchemaAll & ZSchemaInternalProperties;
424
+ type JsonSchemaInternal = Omit<JsonSchemaAll, InternalSchemaKeys> & ZSchemaInternalProperties & {
425
+ items?: JsonSchemaInternal | boolean | Array<JsonSchemaInternal | boolean>;
426
+ additionalItems?: boolean | JsonSchemaInternal;
427
+ properties?: Record<string, JsonSchemaInternal | boolean>;
428
+ patternProperties?: Record<string, JsonSchemaInternal>;
429
+ additionalProperties?: boolean | JsonSchemaInternal;
430
+ dependencies?: Record<string, string[] | JsonSchemaInternal>;
431
+ allOf?: JsonSchemaInternal[];
432
+ anyOf?: JsonSchemaInternal[];
433
+ oneOf?: JsonSchemaInternal[];
434
+ not?: JsonSchemaInternal;
435
+ definitions?: Record<string, JsonSchemaInternal>;
436
+ contains?: JsonSchemaInternal;
437
+ propertyNames?: JsonSchemaInternal;
438
+ if?: JsonSchemaInternal | boolean;
439
+ then?: JsonSchemaInternal | boolean;
440
+ else?: JsonSchemaInternal | boolean;
441
+ $defs?: Record<string, JsonSchemaInternal>;
442
+ dependentSchemas?: Record<string, JsonSchemaInternal>;
443
+ unevaluatedItems?: JsonSchemaInternal | boolean;
444
+ unevaluatedProperties?: JsonSchemaInternal | boolean;
445
+ prefixItems?: Array<JsonSchemaInternal | boolean>;
446
+ };
418
447
  /**
419
448
  * JSON Schema Draft-04.
420
449
  *
@@ -508,8 +537,6 @@ type SchemaReader = (uri: string) => JsonSchema;
508
537
  //#endregion
509
538
  //#region src/z-schema.d.ts
510
539
  declare class ZSchema extends ZSchemaBase {
511
- /** @internal Use ZSchema.create() instead. */
512
- constructor(options: ZSchemaOptions | undefined, token: symbol);
513
540
  /**
514
541
  * Register a global format validator available to all instances.
515
542
  * @param name - The format name (e.g. `'email'`, `'date'`).
@@ -627,8 +654,6 @@ declare class ZSchema extends ZSchemaBase {
627
654
  * Created via `ZSchema.create({ safe: true })`.
628
655
  */
629
656
  declare class ZSchemaSafe extends ZSchemaBase {
630
- /** @internal Use ZSchema.create() instead. */
631
- constructor(options: ZSchemaOptions | undefined, token: symbol);
632
657
  /**
633
658
  * Validate JSON data against a schema.
634
659
  * @param json - The data to validate.
@@ -649,8 +674,6 @@ declare class ZSchemaSafe extends ZSchemaBase {
649
674
  * Created via `ZSchema.create({ async: true })`.
650
675
  */
651
676
  declare class ZSchemaAsync extends ZSchemaBase {
652
- /** @internal Use ZSchema.create() instead. */
653
- constructor(options: ZSchemaOptions | undefined, token: symbol);
654
677
  /**
655
678
  * Validate JSON data against a schema asynchronously.
656
679
  * @param json - The data to validate.
@@ -673,8 +696,6 @@ declare class ZSchemaAsync extends ZSchemaBase {
673
696
  * Created via `ZSchema.create({ async: true, safe: true })`.
674
697
  */
675
698
  declare class ZSchemaAsyncSafe extends ZSchemaBase {
676
- /** @internal Use ZSchema.create() instead. */
677
- constructor(options: ZSchemaOptions | undefined, token: symbol);
678
699
  /**
679
700
  * Validate JSON data against a schema asynchronously.
680
701
  * The promise always resolves (never rejects).
@@ -1,4 +1,4 @@
1
- import { SchemaErrorDetail } from "./report.mjs";
1
+ import { SchemaErrorDetail } from "./report.js";
2
2
 
3
3
  //#region src/errors.d.ts
4
4
  type ErrorCode = keyof typeof Errors;
@@ -56,7 +56,7 @@ declare const Errors: {
56
56
  MAX_RECURSION_DEPTH_EXCEEDED: string;
57
57
  };
58
58
  declare class ValidateError extends Error {
59
- name: string;
59
+ readonly name: string;
60
60
  details?: SchemaErrorDetail[];
61
61
  constructor(message: string, details?: SchemaErrorDetail[]);
62
62
  }
@@ -52,11 +52,10 @@ const Errors = {
52
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
53
  };
54
54
  var ValidateError = class extends Error {
55
- name;
55
+ name = "ValidateError";
56
56
  details;
57
57
  constructor(message, details) {
58
58
  super(message);
59
- this.name = "z-schema validation error";
60
59
  this.details = details;
61
60
  }
62
61
  };
@@ -1,7 +1,7 @@
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";
1
+ import { sortedKeys } from "./utils/json.js";
2
+ import { isValidRfc3339Date } from "./utils/date.js";
3
+ import { isValidHostname, isValidIdnHostname } from "./utils/hostname.js";
4
+ import { parseRfc3339Time } from "./utils/time.js";
5
5
  import isEmailModule from "validator/lib/isEmail.js";
6
6
  import isIPModule from "validator/lib/isIP.js";
7
7
  import isURLModule from "validator/lib/isURL.js";
@@ -10,17 +10,18 @@ const dateValidator = (date) => {
10
10
  if (typeof date !== "string") return true;
11
11
  const matches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(date);
12
12
  if (matches === null) return false;
13
- return isValidRfc3339Date(parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3], 10));
13
+ return isValidRfc3339Date(Number.parseInt(matches[1], 10), Number.parseInt(matches[2], 10), Number.parseInt(matches[3], 10));
14
14
  };
15
15
  const dateTimeValidator = (dateTime) => {
16
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];
17
+ let tIdx = dateTime.indexOf("T");
18
+ if (tIdx === -1) tIdx = dateTime.indexOf("t");
19
+ if (tIdx === -1) return false;
20
+ const datePart = dateTime.slice(0, tIdx);
21
+ const timePart = dateTime.slice(tIdx + 1);
21
22
  const dateMatches = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.exec(datePart);
22
23
  if (dateMatches === null) return false;
23
- if (!isValidRfc3339Date(parseInt(dateMatches[1], 10), parseInt(dateMatches[2], 10), parseInt(dateMatches[3], 10))) return false;
24
+ if (!isValidRfc3339Date(Number.parseInt(dateMatches[1], 10), Number.parseInt(dateMatches[2], 10), Number.parseInt(dateMatches[3], 10))) return false;
24
25
  return parseRfc3339Time(timePart) !== null;
25
26
  };
26
27
  const emailValidator = (email) => {
@@ -49,26 +50,26 @@ const ipv6Validator = (ipv6) => {
49
50
  if (ipv6.includes("%")) return false;
50
51
  return isIPModule.default(ipv6, 6);
51
52
  };
53
+ const INVALID_REGEX_ESCAPES = new Set(["a"]);
52
54
  const regexValidator = (input) => {
53
55
  if (typeof input !== "string") return true;
54
- const invalidEscapes = new Set(["a"]);
55
56
  for (let idx = 0; idx < input.length; idx++) {
56
57
  if (input[idx] !== "\\") continue;
57
58
  idx++;
58
59
  if (idx >= input.length) return false;
59
60
  const escaped = input[idx];
60
- if (invalidEscapes.has(escaped)) return false;
61
+ if (INVALID_REGEX_ESCAPES.has(escaped)) return false;
61
62
  }
62
63
  try {
63
- RegExp(input);
64
+ new RegExp(input);
64
65
  return true;
65
- } catch (_e) {
66
+ } catch {
66
67
  return false;
67
68
  }
68
69
  };
69
70
  const durationValidator = (input) => {
70
71
  if (typeof input !== "string") return true;
71
- if (!/^P[\x00-\x7F]*$/.test(input)) return false;
72
+ if (!/^P[\u0000-\u007F]*$/.test(input)) return false;
72
73
  if (!input.startsWith("P")) return false;
73
74
  const body = input.slice(1);
74
75
  if (body.length === 0) return false;
@@ -78,7 +79,7 @@ const durationValidator = (input) => {
78
79
  const datePart = parts[0];
79
80
  const timePart = parts.length === 2 ? parts[1] : void 0;
80
81
  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
+ const hasDateComponent = datePart.length > 0;
82
83
  let hasTimeComponent = false;
83
84
  if (timePart !== void 0) {
84
85
  if (timePart.length === 0) return false;
@@ -93,32 +94,31 @@ const uuidValidator = (input) => {
93
94
  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
  };
95
96
  const strictUriValidator = (uri) => typeof uri !== "string" || isURLModule.default(uri);
97
+ const isHexChar = (c) => c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102;
96
98
  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
- }
99
+ for (let i = 0; i < str.length; i++) if (str[i] === "%" && (i + 2 >= str.length || !isHexChar(str.charCodeAt(i + 1)) || !isHexChar(str.charCodeAt(i + 2)))) return false;
100
100
  return true;
101
101
  };
102
- const uriValidator = function(uri) {
102
+ const uriValidator = (uri) => {
103
103
  if (typeof uri !== "string") return true;
104
- if (/[^\x00-\x7F]/.test(uri)) return false;
104
+ if (/[^\u0000-\u007F]/.test(uri)) return false;
105
105
  if (!hasValidPercentEncoding(uri)) return false;
106
- const match = uri.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):\/\/([^/?#]*)/);
106
+ const match = /^([a-zA-Z][a-zA-Z0-9+.-]*):\/\/([^/?#]*)/.exec(uri);
107
107
  if (match) {
108
108
  const authority = match[2];
109
109
  const atIndex = authority.indexOf("@");
110
110
  if (atIndex > 0) {
111
- const userinfo = authority.substring(0, atIndex);
111
+ const userinfo = authority.slice(0, atIndex);
112
112
  if (userinfo.includes("[") || userinfo.includes("]")) return false;
113
113
  }
114
- let hostPort = atIndex >= 0 ? authority.substring(atIndex + 1) : authority;
114
+ let hostPort = atIndex === -1 ? authority : authority.slice(atIndex + 1);
115
115
  if (hostPort.startsWith("[")) {
116
116
  const bracketEnd = hostPort.indexOf("]");
117
- if (bracketEnd >= 0) hostPort = hostPort.substring(bracketEnd + 1);
117
+ if (bracketEnd !== -1) hostPort = hostPort.slice(bracketEnd + 1);
118
118
  }
119
119
  const colonIndex = hostPort.lastIndexOf(":");
120
- if (colonIndex >= 0) {
121
- const port = hostPort.substring(colonIndex + 1);
120
+ if (colonIndex !== -1) {
121
+ const port = hostPort.slice(colonIndex + 1);
122
122
  if (port.length > 0 && !/^\d+$/.test(port)) return false;
123
123
  }
124
124
  }
@@ -126,7 +126,7 @@ const uriValidator = function(uri) {
126
126
  };
127
127
  const uriReferenceValidator = (uri) => {
128
128
  if (typeof uri !== "string") return true;
129
- if (/[^\x00-\x7F]/.test(uri)) return false;
129
+ if (/[^\u0000-\u007F]/.test(uri)) return false;
130
130
  return /^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/.test(uri);
131
131
  };
132
132
  const uriTemplateValidator = (uri) => {
@@ -157,20 +157,20 @@ const jsonPointerValidator = (pointer) => {
157
157
  if (typeof pointer !== "string") return true;
158
158
  if (pointer === "") return true;
159
159
  if (!/^(?:\/[^/]*)+$/.test(pointer)) return false;
160
- const tokens = pointer.split("/").slice(1);
161
- for (const token of tokens) if (!hasValidTildeEscapes(token)) return false;
160
+ const tokens = pointer.split("/");
161
+ for (let i = 1; i < tokens.length; i++) if (!hasValidTildeEscapes(tokens[i])) return false;
162
162
  return true;
163
163
  };
164
164
  const relativeJsonPointerValidator = (pointer) => {
165
165
  if (typeof pointer !== "string") return true;
166
- const match = pointer.match(/^(0|[1-9]\d*)(.*)$/);
166
+ const match = /^(0|[1-9]\d*)(.*)$/.exec(pointer);
167
167
  if (!match) return false;
168
168
  const suffix = match[2];
169
169
  if (suffix === "" || suffix === "#") return true;
170
170
  if (!suffix.startsWith("/")) return false;
171
171
  if (!/^(?:\/[^/]*)+$/.test(suffix)) return false;
172
- const tokens = suffix.split("/").slice(1);
173
- for (const token of tokens) if (!hasValidTildeEscapes(token)) return false;
172
+ const tokens = suffix.split("/");
173
+ for (let i = 1; i < tokens.length; i++) if (!hasValidTildeEscapes(tokens[i])) return false;
174
174
  return true;
175
175
  };
176
176
  const timeValidator = (time) => {
@@ -191,7 +191,7 @@ const iriValidator = (iri) => {
191
191
  try {
192
192
  new URL(iri);
193
193
  return true;
194
- } catch (_e) {
194
+ } catch {
195
195
  return false;
196
196
  }
197
197
  };
@@ -228,9 +228,16 @@ function getFormatValidators(options) {
228
228
  ...inbuiltValidators,
229
229
  ...options?.strictUris ? { uri: strictUriValidator } : {},
230
230
  ...customValidators,
231
- ...options?.customFormats || {}
231
+ ...options?.customFormats
232
232
  };
233
233
  }
234
+ function resolveFormatValidator(name, options) {
235
+ const custom = options?.customFormats;
236
+ if (custom && Object.hasOwn(custom, name)) return custom[name];
237
+ if (Object.hasOwn(customValidators, name)) return customValidators[name];
238
+ if (options?.strictUris && name === "uri") return strictUriValidator;
239
+ return inbuiltValidators[name];
240
+ }
234
241
  function registerFormat(name, validatorFunction) {
235
242
  customValidators[name] = validatorFunction;
236
243
  }
@@ -258,4 +265,4 @@ function getRegisteredFormats() {
258
265
  return sortedKeys(customValidators);
259
266
  }
260
267
  //#endregion
261
- export { getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat };
268
+ export { getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, resolveFormatValidator, unregisterFormat };
@@ -1,10 +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";
1
+ import { FormatValidatorFn, FormatValidatorsOptions, getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat } from "./format-validators.js";
2
+ import { ZSchemaOptions } from "./z-schema-options.js";
3
+ import { Report, SchemaErrorDetail } from "./report.js";
4
+ import { ErrorCode, ErrorParam, Errors, ValidateError } from "./errors.js";
5
+ import { ValidateOptions, ValidateResponse } from "./z-schema-base.js";
6
+ import { JsonSchemaCommon, JsonSchemaType } from "./json-schema.js";
7
+ import { JsonSchema, JsonSchemaDraft201909, JsonSchemaDraft202012, JsonSchemaDraft4, JsonSchemaDraft6, JsonSchemaDraft7, JsonSchemaVersion } from "./json-schema-versions.js";
8
+ import { SchemaReader } from "./z-schema-reader.js";
9
+ import { ZSchema, ZSchemaAsync, ZSchemaAsyncSafe, ZSchemaSafe } from "./z-schema.js";
10
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 };
@@ -1,6 +1,6 @@
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";
1
+ import { ValidateError } from "./errors.js";
2
+ import { getFormatValidators, getRegisteredFormats, getSupportedFormats, isFormatSupported, registerFormat, unregisterFormat } from "./format-validators.js";
3
+ import { ZSchema } from "./z-schema.js";
4
4
  //#region src/index.ts
5
5
  var src_default = ZSchema;
6
6
  //#endregion
@@ -1,4 +1,4 @@
1
- import { JsonSchemaCommon, ZSchemaInternalProperties } from "./json-schema.mjs";
1
+ import { JsonSchemaCommon, ZSchemaInternalProperties } from "./json-schema.js";
2
2
 
3
3
  //#region src/json-schema-versions.d.ts
4
4
  type JsonSchemaVersion = 'draft-04' | 'draft-06' | 'draft-07' | 'draft2019-09' | 'draft2020-12';
@@ -41,11 +41,42 @@ interface JsonSchemaAll extends JsonSchemaCommon {
41
41
  $dynamicRef?: string;
42
42
  prefixItems?: Array<JsonSchema | boolean>;
43
43
  }
44
+ /**
45
+ * Sub-schema-valued keywords. On the internal type these point at
46
+ * `JsonSchemaInternal` (rather than the public `JsonSchema`) so the validator
47
+ * can traverse nested schemas without asserting `as JsonSchemaInternal` at
48
+ * every step.
49
+ */
50
+ type InternalSchemaKeys = 'items' | 'additionalItems' | 'properties' | 'patternProperties' | 'additionalProperties' | 'dependencies' | 'allOf' | 'anyOf' | 'oneOf' | 'not' | 'definitions' | 'contains' | 'propertyNames' | 'if' | 'then' | 'else' | '$defs' | 'dependentSchemas' | 'unevaluatedItems' | 'unevaluatedProperties' | 'prefixItems';
44
51
  /**
45
52
  * Internal schema type used throughout the validator. Based on `JsonSchemaAll`
46
- * so that validators can access any draft-specific property without narrowing.
53
+ * so that validators can access any draft-specific property without narrowing,
54
+ * but with every sub-schema keyword re-typed to `JsonSchemaInternal` so nested
55
+ * traversal needs no type assertions.
47
56
  */
48
- type JsonSchemaInternal = JsonSchemaAll & ZSchemaInternalProperties;
57
+ type JsonSchemaInternal = Omit<JsonSchemaAll, InternalSchemaKeys> & ZSchemaInternalProperties & {
58
+ items?: JsonSchemaInternal | boolean | Array<JsonSchemaInternal | boolean>;
59
+ additionalItems?: boolean | JsonSchemaInternal;
60
+ properties?: Record<string, JsonSchemaInternal | boolean>;
61
+ patternProperties?: Record<string, JsonSchemaInternal>;
62
+ additionalProperties?: boolean | JsonSchemaInternal;
63
+ dependencies?: Record<string, string[] | JsonSchemaInternal>;
64
+ allOf?: JsonSchemaInternal[];
65
+ anyOf?: JsonSchemaInternal[];
66
+ oneOf?: JsonSchemaInternal[];
67
+ not?: JsonSchemaInternal;
68
+ definitions?: Record<string, JsonSchemaInternal>;
69
+ contains?: JsonSchemaInternal;
70
+ propertyNames?: JsonSchemaInternal;
71
+ if?: JsonSchemaInternal | boolean;
72
+ then?: JsonSchemaInternal | boolean;
73
+ else?: JsonSchemaInternal | boolean;
74
+ $defs?: Record<string, JsonSchemaInternal>;
75
+ dependentSchemas?: Record<string, JsonSchemaInternal>;
76
+ unevaluatedItems?: JsonSchemaInternal | boolean;
77
+ unevaluatedProperties?: JsonSchemaInternal | boolean;
78
+ prefixItems?: Array<JsonSchemaInternal | boolean>;
79
+ };
49
80
  /**
50
81
  * JSON Schema Draft-04.
51
82
  *
@@ -1,6 +1,6 @@
1
- import { ZSchemaOptions } from "./z-schema-options.mjs";
2
- import { Reference } from "./schema-compiler.mjs";
3
- import { JsonSchema, JsonSchemaInternal } from "./json-schema-versions.mjs";
1
+ import { ZSchemaOptions } from "./z-schema-options.js";
2
+ import { Reference } from "./schema-compiler.js";
3
+ import { JsonSchema, JsonSchemaInternal } from "./json-schema-versions.js";
4
4
 
5
5
  //#region src/json-schema.d.ts
6
6
  /**
@@ -15,7 +15,7 @@ interface JsonSchemaCommon {
15
15
  description?: string;
16
16
  default?: unknown;
17
17
  type?: string | string[];
18
- enum?: Array<unknown>;
18
+ enum?: unknown[];
19
19
  format?: string;
20
20
  multipleOf?: number;
21
21
  minimum?: number;
@@ -49,9 +49,9 @@ type JsonSchemaType = 'array' | 'boolean' | 'integer' | 'null' | 'number' | 'obj
49
49
  interface ZSchemaInternalProperties {
50
50
  __$compiled?: unknown;
51
51
  __$missingReferences?: Reference[];
52
- __$refResolved?: JsonSchema;
53
- __$dynamicRefResolved?: JsonSchema;
54
- __$recursiveRefResolved?: JsonSchema;
52
+ __$refResolved?: JsonSchemaInternal;
53
+ __$dynamicRefResolved?: JsonSchemaInternal;
54
+ __$recursiveRefResolved?: JsonSchemaInternal;
55
55
  __$resourceRoot?: JsonSchemaInternal;
56
56
  __$schemaResolved?: unknown;
57
57
  __$validated?: boolean;
@@ -1,16 +1,11 @@
1
- import { getRemotePath, isAbsoluteUri } from "./utils/uri.mjs";
2
- import { isObject } from "./utils/what-is.mjs";
3
- //#region src/json-schema.ts
4
- /**
5
- * Keywords whose values are not JSON Schema sub-schemas and must not be
6
- * traversed during schema walking (id collection, reference collection, etc.).
7
- */
8
- const NON_SCHEMA_KEYWORDS = [
1
+ import { getRemotePath, isAbsoluteUri } from "./utils/uri.js";
2
+ import { isObject } from "./utils/what-is.js";
3
+ const NON_SCHEMA_KEYWORDS_SET = new Set([
9
4
  "enum",
10
5
  "const",
11
6
  "default",
12
7
  "examples"
13
- ];
8
+ ]);
14
9
  /** Returns true if the key is an internal z-schema property (prefixed with `__$`). */
15
10
  const isInternalKey = (key) => key.startsWith("__$");
16
11
  const getId = (schema) => {
@@ -31,7 +26,7 @@ const findId = (schema, id, targetBaseUri, currentBaseUri, maxDepth = 100, _dept
31
26
  } catch {}
32
27
  }
33
28
  if (!targetBaseUri || nextBaseUri === targetBaseUri) {
34
- if (schemaId && (schemaId === id || schemaId[0] === "#" && schemaId.substring(1) === id)) return schema;
29
+ if (schemaId && (schemaId === id || schemaId.startsWith("#") && schemaId.slice(1) === id)) return schema;
35
30
  if (schema.$anchor === id || schema.$dynamicAnchor === id) return schema;
36
31
  }
37
32
  let result;
@@ -43,11 +38,11 @@ const findId = (schema, id, targetBaseUri, currentBaseUri, maxDepth = 100, _dept
43
38
  const keys = Object.keys(schema);
44
39
  for (let i = keys.length - 1; i >= 0; i--) {
45
40
  const k = keys[i];
46
- if (isInternalKey(k) || NON_SCHEMA_KEYWORDS.includes(k)) continue;
41
+ if (isInternalKey(k) || NON_SCHEMA_KEYWORDS_SET.has(k)) continue;
47
42
  result = findId(schema[k], id, targetBaseUri, nextBaseUri, maxDepth, _depth + 1);
48
43
  if (result) return result;
49
44
  }
50
45
  }
51
46
  };
52
47
  //#endregion
53
- export { NON_SCHEMA_KEYWORDS, findId, getId, isInternalKey };
48
+ export { NON_SCHEMA_KEYWORDS_SET, findId, getId, isInternalKey };