z-schema 10.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +35 -17
  2. package/cjs/index.d.ts +345 -34
  3. package/cjs/index.js +4446 -1685
  4. package/dist/errors.js +5 -0
  5. package/dist/format-validators.js +131 -107
  6. package/dist/json-schema-versions.js +4 -1
  7. package/dist/json-schema.js +50 -16
  8. package/dist/json-validation.js +524 -669
  9. package/dist/report.js +37 -16
  10. package/dist/schema-cache.js +76 -18
  11. package/dist/schema-compiler.js +72 -47
  12. package/dist/schema-validator.js +117 -52
  13. package/dist/schemas/draft-07-schema.json +172 -0
  14. package/dist/schemas/draft-2019-09-meta-applicator.json +52 -0
  15. package/dist/schemas/draft-2019-09-meta-content.json +12 -0
  16. package/dist/schemas/draft-2019-09-meta-core.json +53 -0
  17. package/dist/schemas/draft-2019-09-meta-format.json +10 -0
  18. package/dist/schemas/draft-2019-09-meta-meta-data.json +32 -0
  19. package/dist/schemas/draft-2019-09-meta-validation.json +94 -0
  20. package/dist/schemas/draft-2019-09-schema.json +41 -0
  21. package/dist/schemas/draft-2020-12-meta-applicator.json +44 -0
  22. package/dist/schemas/draft-2020-12-meta-content.json +12 -0
  23. package/dist/schemas/draft-2020-12-meta-core.json +47 -0
  24. package/dist/schemas/draft-2020-12-meta-format-annotation.json +10 -0
  25. package/dist/schemas/draft-2020-12-meta-format-assertion.json +10 -0
  26. package/dist/schemas/draft-2020-12-meta-meta-data.json +32 -0
  27. package/dist/schemas/draft-2020-12-meta-unevaluated.json +11 -0
  28. package/dist/schemas/draft-2020-12-meta-validation.json +94 -0
  29. package/dist/schemas/draft-2020-12-schema.json +57 -0
  30. package/dist/types/errors.d.ts +4 -0
  31. package/dist/types/index.d.ts +2 -1
  32. package/dist/types/json-schema-versions.d.ts +128 -9
  33. package/dist/types/json-schema.d.ts +28 -11
  34. package/dist/types/json-validation.d.ts +2 -3
  35. package/dist/types/report.d.ts +14 -4
  36. package/dist/types/schema-cache.d.ts +7 -0
  37. package/dist/types/schema-compiler.d.ts +5 -3
  38. package/dist/types/schema-validator.d.ts +2 -2
  39. package/dist/types/utils/array.d.ts +8 -1
  40. package/dist/types/utils/base64.d.ts +2 -0
  41. package/dist/types/utils/clone.d.ts +1 -1
  42. package/dist/types/utils/date.d.ts +1 -0
  43. package/dist/types/utils/hostname.d.ts +2 -0
  44. package/dist/types/utils/json.d.ts +2 -1
  45. package/dist/types/utils/properties.d.ts +0 -1
  46. package/dist/types/utils/time.d.ts +12 -0
  47. package/dist/types/utils/unicode.d.ts +3 -12
  48. package/dist/types/validation/array.d.ts +12 -0
  49. package/dist/types/validation/combinators.d.ts +10 -0
  50. package/dist/types/validation/numeric.d.ts +8 -0
  51. package/dist/types/validation/object.d.ts +13 -0
  52. package/dist/types/validation/ref.d.ts +11 -0
  53. package/dist/types/validation/shared.d.ts +26 -0
  54. package/dist/types/validation/string.d.ts +9 -0
  55. package/dist/types/validation/type.d.ts +6 -0
  56. package/dist/types/z-schema-base.d.ts +39 -1
  57. package/dist/types/z-schema-options.d.ts +3 -0
  58. package/dist/types/z-schema.d.ts +144 -8
  59. package/dist/utils/array.js +49 -7
  60. package/dist/utils/base64.js +29 -0
  61. package/dist/utils/clone.js +13 -12
  62. package/dist/utils/date.js +21 -0
  63. package/dist/utils/hostname.js +146 -0
  64. package/dist/utils/json.js +11 -6
  65. package/dist/utils/properties.js +1 -6
  66. package/dist/utils/time.js +50 -0
  67. package/dist/utils/unicode.js +8 -41
  68. package/dist/utils/uri.js +1 -1
  69. package/dist/validation/array.js +128 -0
  70. package/dist/validation/combinators.js +107 -0
  71. package/dist/validation/numeric.js +97 -0
  72. package/dist/validation/object.js +238 -0
  73. package/dist/validation/ref.js +70 -0
  74. package/dist/validation/shared.js +136 -0
  75. package/dist/validation/string.js +178 -0
  76. package/dist/validation/type.js +55 -0
  77. package/dist/z-schema-base.js +52 -32
  78. package/dist/z-schema-options.js +12 -8
  79. package/dist/z-schema-versions.js +92 -9
  80. package/dist/z-schema.js +135 -38
  81. package/package.json +22 -8
  82. package/src/errors.ts +8 -0
  83. package/src/format-validators.ts +146 -105
  84. package/src/index.ts +10 -1
  85. package/src/json-schema-versions.ts +181 -11
  86. package/src/json-schema.ts +102 -35
  87. package/src/json-validation.ts +653 -724
  88. package/src/report.ts +42 -20
  89. package/src/schema-cache.ts +94 -18
  90. package/src/schema-compiler.ts +94 -51
  91. package/src/schema-validator.ts +132 -56
  92. package/src/schemas/draft-07-schema.json +172 -0
  93. package/src/schemas/draft-2019-09-meta-applicator.json +53 -0
  94. package/src/schemas/draft-2019-09-meta-content.json +14 -0
  95. package/src/schemas/draft-2019-09-meta-core.json +54 -0
  96. package/src/schemas/draft-2019-09-meta-format.json +11 -0
  97. package/src/schemas/draft-2019-09-meta-meta-data.json +34 -0
  98. package/src/schemas/draft-2019-09-meta-validation.json +95 -0
  99. package/src/schemas/draft-2019-09-schema.json +42 -0
  100. package/src/schemas/draft-2020-12-meta-applicator.json +45 -0
  101. package/src/schemas/draft-2020-12-meta-content.json +14 -0
  102. package/src/schemas/draft-2020-12-meta-core.json +48 -0
  103. package/src/schemas/draft-2020-12-meta-format-annotation.json +11 -0
  104. package/src/schemas/draft-2020-12-meta-format-assertion.json +11 -0
  105. package/src/schemas/draft-2020-12-meta-meta-data.json +34 -0
  106. package/src/schemas/draft-2020-12-meta-unevaluated.json +12 -0
  107. package/src/schemas/draft-2020-12-meta-validation.json +95 -0
  108. package/src/schemas/draft-2020-12-schema.json +58 -0
  109. package/src/utils/array.ts +51 -7
  110. package/src/utils/base64.ts +32 -0
  111. package/src/utils/clone.ts +16 -12
  112. package/src/utils/date.ts +23 -0
  113. package/src/utils/hostname.ts +174 -0
  114. package/src/utils/json.ts +15 -6
  115. package/src/utils/properties.ts +1 -7
  116. package/src/utils/time.ts +73 -0
  117. package/src/utils/unicode.ts +8 -39
  118. package/src/utils/uri.ts +1 -1
  119. package/src/validation/array.ts +158 -0
  120. package/src/validation/combinators.ts +132 -0
  121. package/src/validation/numeric.ts +120 -0
  122. package/src/validation/object.ts +318 -0
  123. package/src/validation/ref.ts +85 -0
  124. package/src/validation/shared.ts +191 -0
  125. package/src/validation/string.ts +224 -0
  126. package/src/validation/type.ts +66 -0
  127. package/src/z-schema-base.ts +54 -36
  128. package/src/z-schema-options.ts +15 -8
  129. package/src/z-schema-versions.ts +107 -12
  130. package/src/z-schema.ts +158 -42
  131. package/umd/ZSchema.js +4446 -1685
  132. package/umd/ZSchema.min.js +1 -1
  133. package/dist/schemas/draft-04-hyper-schema.json +0 -135
  134. package/dist/schemas/draft-06-hyper-schema.json +0 -132
  135. package/dist/schemas/draft-06-links.json +0 -43
  136. package/src/schemas/draft-04-hyper-schema.json +0 -136
  137. package/src/schemas/draft-06-hyper-schema.json +0 -133
  138. package/src/schemas/draft-06-links.json +0 -43
@@ -4,6 +4,8 @@ import type { Report } from './report.js';
4
4
  import { CURRENT_DEFAULT_SCHEMA_VERSION, type JsonSchemaVersion } from './json-schema-versions.js';
5
5
  import { shallowClone } from './utils/clone.js';
6
6
 
7
+ export const DEFAULT_MAX_RECURSION_DEPTH = 100;
8
+
7
9
  export interface ZSchemaOptions {
8
10
  version?: JsonSchemaVersion | 'none';
9
11
  asyncTimeout?: number;
@@ -27,8 +29,10 @@ export interface ZSchemaOptions {
27
29
  breakOnFirstError?: boolean;
28
30
  pedanticCheck?: boolean;
29
31
  ignoreUnknownFormats?: boolean;
32
+ formatAssertions?: boolean | null;
30
33
  customValidator?: (report: Report, schema: unknown, json: unknown) => void;
31
34
  customFormats?: Record<string, FormatValidatorFn | null>;
35
+ maxRecursionDepth?: number;
32
36
  }
33
37
 
34
38
  export const defaultOptions: ZSchemaOptions = {
@@ -54,7 +58,7 @@ export const defaultOptions: ZSchemaOptions = {
54
58
  forceMaxLength: false,
55
59
  // force properties or patternProperties to be defined on "object" types
56
60
  forceProperties: false,
57
- // ignore references that cannot be resolved (remote schemas) // TODO: make sure this is only for remote schemas, not local ones
61
+ // ignore references that cannot be resolved (remote schemas)
58
62
  ignoreUnresolvableReferences: false,
59
63
  // disallow usage of keywords that this validator can't handle
60
64
  noExtraKeywords: false,
@@ -76,8 +80,16 @@ export const defaultOptions: ZSchemaOptions = {
76
80
  pedanticCheck: false,
77
81
  // ignore unknown formats (do not report them as an error)
78
82
  ignoreUnknownFormats: false,
83
+ // control format assertion behavior:
84
+ // true - respect vocabulary: for draft 2019-09/2020-12, check meta-schema $vocabulary
85
+ // to determine if format is assertion or annotation-only
86
+ // false - format is always annotation-only (never asserts)
87
+ // null - legacy behavior: always assert format validation
88
+ formatAssertions: null,
79
89
  // function to be called on every schema
80
90
  customValidator: null as unknown as undefined,
91
+ // maximum recursion depth for deeply nested schema/data traversal (prevents stack overflow)
92
+ maxRecursionDepth: DEFAULT_MAX_RECURSION_DEPTH,
81
93
  };
82
94
 
83
95
  export const normalizeOptions = (options?: ZSchemaOptions) => {
@@ -86,12 +98,9 @@ export const normalizeOptions = (options?: ZSchemaOptions) => {
86
98
  // options
87
99
  if (typeof options === 'object') {
88
100
  let keys = Object.keys(options) as Array<keyof ZSchemaOptions>;
89
- let idx = keys.length;
90
- let key;
91
101
 
92
102
  // check that the options are correctly configured
93
- while (idx--) {
94
- key = keys[idx];
103
+ for (const key of keys) {
95
104
  if (defaultOptions[key] === undefined) {
96
105
  throw new Error('Unexpected option passed to constructor: ' + key);
97
106
  }
@@ -99,9 +108,7 @@ export const normalizeOptions = (options?: ZSchemaOptions) => {
99
108
 
100
109
  // copy the default options into passed options
101
110
  keys = Object.keys(defaultOptions) as Array<keyof ZSchemaOptions>;
102
- idx = keys.length;
103
- while (idx--) {
104
- key = keys[idx];
111
+ for (const key of keys) {
105
112
  if (options[key] === undefined) {
106
113
  (options as any)[key] = shallowClone(defaultOptions[key]);
107
114
  }
@@ -1,21 +1,67 @@
1
1
  // import schemas so they don't have to be downloaded for validation purposes
2
- import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
2
+ import type {
3
+ JsonSchema,
4
+ JsonSchemaDraft4,
5
+ JsonSchemaDraft6,
6
+ JsonSchemaDraft7,
7
+ JsonSchemaDraft201909,
8
+ JsonSchemaDraft202012,
9
+ JsonSchemaInternal,
10
+ } from './json-schema-versions.js';
3
11
  import type { ZSchemaOptions } from './z-schema-options.js';
4
12
 
5
13
  import { SchemaCache } from './schema-cache.js';
6
14
  import { normalizeOptions } from './z-schema-options.js';
7
15
 
8
- import _Draft4HyperSchema from './schemas/draft-04-hyper-schema.json' with { type: 'json' };
16
+ // draft-04
9
17
  import _Draft4Schema from './schemas/draft-04-schema.json' with { type: 'json' };
10
- import _Draft6HyperSchema from './schemas/draft-06-hyper-schema.json' with { type: 'json' };
11
- import _Draft6Links from './schemas/draft-06-links.json' with { type: 'json' };
18
+ // draft-06
12
19
  import _Draft6Schema from './schemas/draft-06-schema.json' with { type: 'json' };
20
+ // draft-07
21
+ import _Draft7Schema from './schemas/draft-07-schema.json' with { type: 'json' };
22
+ // draft2019-09
23
+ import _Draft201909MetaApplicator from './schemas/draft-2019-09-meta-applicator.json' with { type: 'json' };
24
+ import _Draft201909MetaContent from './schemas/draft-2019-09-meta-content.json' with { type: 'json' };
25
+ import _Draft201909MetaCore from './schemas/draft-2019-09-meta-core.json' with { type: 'json' };
26
+ import _Draft201909MetaFormat from './schemas/draft-2019-09-meta-format.json' with { type: 'json' };
27
+ import _Draft201909MetaMetaData from './schemas/draft-2019-09-meta-meta-data.json' with { type: 'json' };
28
+ import _Draft201909MetaValidation from './schemas/draft-2019-09-meta-validation.json' with { type: 'json' };
29
+ import _Draft201909Schema from './schemas/draft-2019-09-schema.json' with { type: 'json' };
30
+ // draft2020-12
31
+ import _Draft202012MetaApplicator from './schemas/draft-2020-12-meta-applicator.json' with { type: 'json' };
32
+ import _Draft202012MetaContent from './schemas/draft-2020-12-meta-content.json' with { type: 'json' };
33
+ import _Draft202012MetaCore from './schemas/draft-2020-12-meta-core.json' with { type: 'json' };
34
+ import _Draft202012MetaFormatAnnotation from './schemas/draft-2020-12-meta-format-annotation.json' with { type: 'json' };
35
+ import _Draft202012MetaFormatAssertion from './schemas/draft-2020-12-meta-format-assertion.json' with { type: 'json' };
36
+ import _Draft202012MetaMetaData from './schemas/draft-2020-12-meta-meta-data.json' with { type: 'json' };
37
+ import _Draft202012MetaUnevaluated from './schemas/draft-2020-12-meta-unevaluated.json' with { type: 'json' };
38
+ import _Draft202012MetaValidation from './schemas/draft-2020-12-meta-validation.json' with { type: 'json' };
39
+ import _Draft202012Schema from './schemas/draft-2020-12-schema.json' with { type: 'json' };
13
40
 
14
- const Draft4Schema: JsonSchema = _Draft4Schema;
15
- const Draft4HyperSchema: JsonSchema = _Draft4HyperSchema;
16
- const Draft6Schema: JsonSchema = _Draft6Schema;
17
- const Draft6HyperSchema: JsonSchema = _Draft6HyperSchema;
18
- const Draft6Links: JsonSchema = _Draft6Links;
41
+ // draft-04
42
+ const Draft4Schema: JsonSchemaDraft4 = _Draft4Schema;
43
+ // draft-06
44
+ const Draft6Schema: JsonSchemaDraft6 = _Draft6Schema;
45
+ // draft-07
46
+ const Draft7Schema: JsonSchemaDraft7 = _Draft7Schema;
47
+ // draft2019-09
48
+ const Draft201909Schema: JsonSchemaDraft201909 = _Draft201909Schema;
49
+ const Draft201909MetaApplicator: JsonSchemaDraft201909 = _Draft201909MetaApplicator;
50
+ const Draft201909MetaContent: JsonSchemaDraft201909 = _Draft201909MetaContent;
51
+ const Draft201909MetaCore: JsonSchemaDraft201909 = _Draft201909MetaCore;
52
+ const Draft201909MetaFormat: JsonSchemaDraft201909 = _Draft201909MetaFormat;
53
+ const Draft201909MetaMetaData: JsonSchemaDraft201909 = _Draft201909MetaMetaData;
54
+ const Draft201909MetaValidation: JsonSchemaDraft201909 = _Draft201909MetaValidation;
55
+ // draft2020-12
56
+ const Draft202012Schema: JsonSchemaDraft202012 = _Draft202012Schema;
57
+ const Draft202012MetaApplicator: JsonSchemaDraft202012 = _Draft202012MetaApplicator;
58
+ const Draft202012MetaContent: JsonSchemaDraft202012 = _Draft202012MetaContent;
59
+ const Draft202012MetaCore: JsonSchemaDraft202012 = _Draft202012MetaCore;
60
+ const Draft202012MetaFormatAnnotation: JsonSchemaDraft202012 = _Draft202012MetaFormatAnnotation;
61
+ const Draft202012MetaFormatAssertion: JsonSchemaDraft202012 = _Draft202012MetaFormatAssertion;
62
+ const Draft202012MetaMetaData: JsonSchemaDraft202012 = _Draft202012MetaMetaData;
63
+ const Draft202012MetaUnevaluated: JsonSchemaDraft202012 = _Draft202012MetaUnevaluated;
64
+ const Draft202012MetaValidation: JsonSchemaDraft202012 = _Draft202012MetaValidation;
19
65
 
20
66
  const registerRemoteReference = (uri: string, schema: JsonSchema, validationOptions?: ZSchemaOptions) => {
21
67
  const preparedSchema = schema as JsonSchemaInternal;
@@ -31,8 +77,57 @@ const registerRemoteReference = (uri: string, schema: JsonSchema, validationOpti
31
77
  SchemaCache.cacheSchemaByUri(uri, preparedSchema);
32
78
  };
33
79
 
80
+ // draft-04
34
81
  registerRemoteReference('http://json-schema.org/draft-04/schema', Draft4Schema, { version: 'none' });
35
- registerRemoteReference('http://json-schema.org/draft-04/hyper-schema', Draft4HyperSchema, { version: 'none' });
82
+ // draft-06
36
83
  registerRemoteReference('http://json-schema.org/draft-06/schema', Draft6Schema, { version: 'none' });
37
- registerRemoteReference('http://json-schema.org/draft-06/hyper-schema', Draft6HyperSchema, { version: 'none' });
38
- registerRemoteReference('http://json-schema.org/draft-06/links', Draft6Links, { version: 'none' });
84
+ // draft-07
85
+ registerRemoteReference('http://json-schema.org/draft-07/schema', Draft7Schema, { version: 'none' });
86
+ // draft2019-09
87
+ registerRemoteReference('https://json-schema.org/draft/2019-09/schema', Draft201909Schema, { version: 'none' });
88
+ registerRemoteReference('https://json-schema.org/draft/2019-09/meta/applicator', Draft201909MetaApplicator, {
89
+ version: 'none',
90
+ });
91
+ registerRemoteReference('https://json-schema.org/draft/2019-09/meta/content', Draft201909MetaContent, {
92
+ version: 'none',
93
+ });
94
+ registerRemoteReference('https://json-schema.org/draft/2019-09/meta/core', Draft201909MetaCore, {
95
+ version: 'none',
96
+ });
97
+ registerRemoteReference('https://json-schema.org/draft/2019-09/meta/format', Draft201909MetaFormat, {
98
+ version: 'none',
99
+ });
100
+ registerRemoteReference('https://json-schema.org/draft/2019-09/meta/meta-data', Draft201909MetaMetaData, {
101
+ version: 'none',
102
+ });
103
+ registerRemoteReference('https://json-schema.org/draft/2019-09/meta/validation', Draft201909MetaValidation, {
104
+ version: 'none',
105
+ });
106
+ // draft2020-12
107
+ registerRemoteReference('https://json-schema.org/draft/2020-12/schema', Draft202012Schema, { version: 'none' });
108
+ registerRemoteReference('https://json-schema.org/draft/2020-12/meta/applicator', Draft202012MetaApplicator, {
109
+ version: 'none',
110
+ });
111
+ registerRemoteReference('https://json-schema.org/draft/2020-12/meta/content', Draft202012MetaContent, {
112
+ version: 'none',
113
+ });
114
+ registerRemoteReference('https://json-schema.org/draft/2020-12/meta/core', Draft202012MetaCore, {
115
+ version: 'none',
116
+ });
117
+ registerRemoteReference(
118
+ 'https://json-schema.org/draft/2020-12/meta/format-annotation',
119
+ Draft202012MetaFormatAnnotation,
120
+ { version: 'none' }
121
+ );
122
+ registerRemoteReference('https://json-schema.org/draft/2020-12/meta/format-assertion', Draft202012MetaFormatAssertion, {
123
+ version: 'none',
124
+ });
125
+ registerRemoteReference('https://json-schema.org/draft/2020-12/meta/meta-data', Draft202012MetaMetaData, {
126
+ version: 'none',
127
+ });
128
+ registerRemoteReference('https://json-schema.org/draft/2020-12/meta/unevaluated', Draft202012MetaUnevaluated, {
129
+ version: 'none',
130
+ });
131
+ registerRemoteReference('https://json-schema.org/draft/2020-12/meta/validation', Draft202012MetaValidation, {
132
+ version: 'none',
133
+ });
package/src/z-schema.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ValidateError } from './errors.js';
2
2
  import type { FormatValidatorFn } from './format-validators.js';
3
- import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
3
+ import type { JsonSchema } from './json-schema-versions.js';
4
4
  import type { ValidateOptions, ValidateResponse } from './z-schema-base.js';
5
5
  import type { ZSchemaOptions } from './z-schema-options.js';
6
6
  import type { SchemaReader } from './z-schema-reader.js';
@@ -8,63 +8,70 @@ import type { SchemaReader } from './z-schema-reader.js';
8
8
  import './z-schema-versions.js';
9
9
 
10
10
  import { getRegisteredFormats, registerFormat, unregisterFormat } from './format-validators.js';
11
- import { SchemaCache } from './schema-cache.js';
11
+ import { prepareRemoteSchema, SchemaCache } from './schema-cache.js';
12
12
  import { deepClone } from './utils/clone.js';
13
13
  import { jsonSymbol, schemaSymbol } from './utils/symbols.js';
14
- import { ZSchemaBase } from './z-schema-base.js';
15
- import { defaultOptions, normalizeOptions } from './z-schema-options.js';
14
+ import { FACTORY_TOKEN, ZSchemaBase } from './z-schema-base.js';
15
+ import { defaultOptions } from './z-schema-options.js';
16
16
  import { getSchemaReader, setSchemaReader } from './z-schema-reader.js';
17
17
 
18
18
  export class ZSchema extends ZSchemaBase {
19
- /** @deprecated Use ZSchema.create() instead. */
20
- private constructor(options?: ZSchemaOptions) {
21
- super(options);
19
+ /** @internal Use ZSchema.create() instead. */
20
+ constructor(options: ZSchemaOptions | undefined, token: symbol) {
21
+ super(options, token);
22
22
  }
23
23
 
24
24
  // ----- static methods start -----
25
25
 
26
26
  // class scoped format functions
27
+
28
+ /**
29
+ * Register a global format validator available to all instances.
30
+ * @param name - The format name (e.g. `'email'`, `'date'`).
31
+ * @param validatorFunction - A sync or async function `(value: unknown) => boolean | Promise<boolean>`.
32
+ */
27
33
  public static registerFormat(name: string, validatorFunction: FormatValidatorFn): void {
28
34
  return registerFormat(name, validatorFunction);
29
35
  }
30
36
 
37
+ /**
38
+ * Remove a globally registered format validator.
39
+ * @param name - The format name to unregister.
40
+ */
31
41
  public static unregisterFormat(name: string): void {
32
42
  return unregisterFormat(name);
33
43
  }
34
44
 
45
+ /** Returns the names of all globally registered format validators. */
35
46
  public static getRegisteredFormats(): string[] {
36
47
  return getRegisteredFormats();
37
48
  }
38
49
 
39
- // default options for validator instance
50
+ /** Returns a deep clone of the default options. */
40
51
  public static getDefaultOptions(): ZSchemaOptions {
41
52
  return deepClone(defaultOptions);
42
53
  }
43
54
 
55
+ /**
56
+ * Register a remote schema in the global cache so any instance can resolve `$ref` to it.
57
+ * @param uri - The URI the schema will be known by.
58
+ * @param schema - The schema object or JSON string.
59
+ * @param validationOptions - Optional options used for schema preparation.
60
+ */
44
61
  public static setRemoteReference(uri: string, schema: string | JsonSchema, validationOptions?: ZSchemaOptions) {
45
- let _schema: JsonSchemaInternal;
46
-
47
- if (typeof schema === 'string') {
48
- _schema = JSON.parse(schema);
49
- } else {
50
- _schema = deepClone(schema);
51
- }
52
-
53
- if (!_schema.id) {
54
- _schema.id = uri;
55
- }
56
-
57
- if (validationOptions) {
58
- _schema.__$validationOptions = normalizeOptions(validationOptions);
59
- }
60
-
62
+ const _schema = prepareRemoteSchema(schema, uri, validationOptions);
61
63
  SchemaCache.cacheSchemaByUri(uri, _schema);
62
64
  }
63
65
 
66
+ /** Returns the current global schema reader, or `undefined` if none is set. */
64
67
  public static getSchemaReader() {
65
68
  return getSchemaReader();
66
69
  }
67
70
 
71
+ /**
72
+ * Set a global schema reader function used to resolve remote `$ref` URIs.
73
+ * @param schemaReader - A function `(uri: string) => JsonSchema | undefined`, or `undefined` to clear.
74
+ */
68
75
  public static setSchemaReader(schemaReader: SchemaReader | undefined) {
69
76
  return setSchemaReader(schemaReader);
70
77
  }
@@ -75,6 +82,27 @@ export class ZSchema extends ZSchemaBase {
75
82
 
76
83
  // ----- static methods end -----
77
84
 
85
+ /**
86
+ * Create a validator instance.
87
+ *
88
+ * The returned type depends on the `async` and `safe` options:
89
+ * - `{}` → `ZSchema` — `validate()` returns `true` or throws.
90
+ * - `{ safe: true }` → `ZSchemaSafe` — `validate()` returns `{ valid, err? }`.
91
+ * - `{ async: true }` → `ZSchemaAsync` — `validate()` returns `Promise<true>` or rejects.
92
+ * - `{ async: true, safe: true }` → `ZSchemaAsyncSafe` — `validate()` returns `Promise<{ valid, err? }>`.
93
+ *
94
+ * @param options - Validator configuration. See `ZSchemaOptions` for all available settings.
95
+ * @returns A validator instance of the appropriate variant.
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * const validator = ZSchema.create();
100
+ * validator.validate(data, schema); // throws on error
101
+ *
102
+ * const safe = ZSchema.create({ safe: true });
103
+ * const result = safe.validate(data, schema); // { valid, err? }
104
+ * ```
105
+ */
78
106
  public static create(options: ZSchemaOptions & { async: true; safe: true }): ZSchemaAsyncSafe;
79
107
  public static create(options: ZSchemaOptions & { async: true }): ZSchemaAsync;
80
108
  public static create(options: ZSchemaOptions & { safe: true }): ZSchemaSafe;
@@ -86,27 +114,37 @@ export class ZSchema extends ZSchemaBase {
86
114
  const isSafe = options.safe;
87
115
  delete options.async;
88
116
  delete options.safe;
89
- (options as any).__called_from_factory__ = true;
90
117
  if (isAsync && isSafe) {
91
- // @ts-expect-error Factory can use private/deprecated constructor
92
- return new ZSchemaAsyncSafe(options);
118
+ return new ZSchemaAsyncSafe(options, FACTORY_TOKEN);
93
119
  }
94
120
  if (isAsync) {
95
- // @ts-expect-error Factory can use private/deprecated constructor
96
- return new ZSchemaAsync(options);
121
+ return new ZSchemaAsync(options, FACTORY_TOKEN);
97
122
  }
98
123
  if (isSafe) {
99
- // @ts-expect-error Factory can use private/deprecated constructor
100
- return new ZSchemaSafe(options);
124
+ return new ZSchemaSafe(options, FACTORY_TOKEN);
101
125
  }
102
- // Factory can use private/deprecated constructor
103
- return new ZSchema(options);
126
+ return new ZSchema(options, FACTORY_TOKEN);
104
127
  }
105
128
 
129
+ /**
130
+ * Validate JSON data against a schema.
131
+ * @param json - The data to validate.
132
+ * @param schema - A JSON Schema object or a schema id string (previously registered via `validateSchema`).
133
+ * @param options - Per-call options (`schemaPath`, `includeErrors`, `excludeErrors`).
134
+ * @returns `true` if valid.
135
+ * @throws {@link ValidateError} if validation fails, with a `details` array of structured errors.
136
+ */
106
137
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): true {
107
138
  return this._validate(json, schema, options);
108
139
  }
109
140
 
141
+ /**
142
+ * Validate JSON data against a schema, returning a result object instead of throwing.
143
+ * @param json - The data to validate.
144
+ * @param schema - A JSON Schema object or a schema id string.
145
+ * @param options - Per-call options.
146
+ * @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
147
+ */
110
148
  validateSafe(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): ValidateResponse {
111
149
  try {
112
150
  this._validate(json, schema, options ?? {});
@@ -116,6 +154,14 @@ export class ZSchema extends ZSchemaBase {
116
154
  }
117
155
  }
118
156
 
157
+ /**
158
+ * Validate JSON data against a schema asynchronously (supports async format validators).
159
+ * @param json - The data to validate.
160
+ * @param schema - A JSON Schema object or a schema id string.
161
+ * @param options - Per-call options.
162
+ * @returns A promise that resolves to `true` if valid.
163
+ * @throws {@link ValidateError} if validation fails (the promise rejects).
164
+ */
119
165
  validateAsync(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): Promise<true> {
120
166
  return new Promise((resolve, reject) => {
121
167
  try {
@@ -128,6 +174,14 @@ export class ZSchema extends ZSchemaBase {
128
174
  });
129
175
  }
130
176
 
177
+ /**
178
+ * Validate JSON data against a schema asynchronously, returning a result object.
179
+ * The promise always resolves (never rejects).
180
+ * @param json - The data to validate.
181
+ * @param schema - A JSON Schema object or a schema id string.
182
+ * @param options - Per-call options.
183
+ * @returns A promise resolving to `{ valid: true }` or `{ valid: false, err: ValidateError }`.
184
+ */
131
185
  validateAsyncSafe(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): Promise<ValidateResponse> {
132
186
  return new Promise((resolve) => {
133
187
  try {
@@ -140,10 +194,21 @@ export class ZSchema extends ZSchemaBase {
140
194
  });
141
195
  }
142
196
 
197
+ /**
198
+ * Validate one or more JSON Schemas, compiling and caching them for later use with `validate()`.
199
+ * @param schemaOrArr - A single schema or an array of schemas (for cross-referencing).
200
+ * @returns `true` if all schemas are valid.
201
+ * @throws {@link ValidateError} if any schema is invalid.
202
+ */
143
203
  validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): true {
144
204
  return this._validateSchema(schemaOrArr);
145
205
  }
146
206
 
207
+ /**
208
+ * Validate one or more JSON Schemas, returning a result object instead of throwing.
209
+ * @param schemaOrArr - A single schema or an array of schemas.
210
+ * @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
211
+ */
147
212
  validateSchemaSafe(schemaOrArr: JsonSchema | JsonSchema[]): ValidateResponse {
148
213
  try {
149
214
  this._validateSchema(schemaOrArr);
@@ -154,12 +219,23 @@ export class ZSchema extends ZSchemaBase {
154
219
  }
155
220
  }
156
221
 
222
+ /**
223
+ * Synchronous safe validator — `validate()` returns `{ valid, err? }` instead of throwing.
224
+ * Created via `ZSchema.create({ safe: true })`.
225
+ */
157
226
  export class ZSchemaSafe extends ZSchemaBase {
158
- /** @deprecated Use ZSchema.create() instead. */
159
- private constructor(options?: ZSchemaOptions) {
160
- super(options);
227
+ /** @internal Use ZSchema.create() instead. */
228
+ constructor(options: ZSchemaOptions | undefined, token: symbol) {
229
+ super(options, token);
161
230
  }
162
231
 
232
+ /**
233
+ * Validate JSON data against a schema.
234
+ * @param json - The data to validate.
235
+ * @param schema - A JSON Schema object or a schema id string.
236
+ * @param options - Per-call options.
237
+ * @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
238
+ */
163
239
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): ValidateResponse {
164
240
  try {
165
241
  this._validate(json, schema, options);
@@ -169,6 +245,11 @@ export class ZSchemaSafe extends ZSchemaBase {
169
245
  }
170
246
  }
171
247
 
248
+ /**
249
+ * Validate one or more JSON Schemas.
250
+ * @param schemaOrArr - A single schema or an array of schemas.
251
+ * @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
252
+ */
172
253
  validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): ValidateResponse {
173
254
  try {
174
255
  this._validateSchema(schemaOrArr);
@@ -179,12 +260,24 @@ export class ZSchemaSafe extends ZSchemaBase {
179
260
  }
180
261
  }
181
262
 
263
+ /**
264
+ * Asynchronous throw validator — `validate()` returns `Promise<true>` or rejects.
265
+ * Created via `ZSchema.create({ async: true })`.
266
+ */
182
267
  export class ZSchemaAsync extends ZSchemaBase {
183
- /** @deprecated Use ZSchema.create() instead. */
184
- private constructor(options?: ZSchemaOptions) {
185
- super(options);
268
+ /** @internal Use ZSchema.create() instead. */
269
+ constructor(options: ZSchemaOptions | undefined, token: symbol) {
270
+ super(options, token);
186
271
  }
187
272
 
273
+ /**
274
+ * Validate JSON data against a schema asynchronously.
275
+ * @param json - The data to validate.
276
+ * @param schema - A JSON Schema object or a schema id string.
277
+ * @param options - Per-call options.
278
+ * @returns A promise that resolves to `true` if valid.
279
+ * @throws {@link ValidateError} if validation fails (the promise rejects).
280
+ */
188
281
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): Promise<true> {
189
282
  return new Promise((resolve, reject) => {
190
283
  try {
@@ -195,17 +288,35 @@ export class ZSchemaAsync extends ZSchemaBase {
195
288
  });
196
289
  }
197
290
 
291
+ /**
292
+ * Validate one or more JSON Schemas (synchronous, throws on error).
293
+ * @param schemaOrArr - A single schema or an array of schemas.
294
+ * @returns `true` if all schemas are valid.
295
+ * @throws {@link ValidateError} if any schema is invalid.
296
+ */
198
297
  validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): true {
199
298
  return this._validateSchema(schemaOrArr);
200
299
  }
201
300
  }
202
301
 
302
+ /**
303
+ * Asynchronous safe validator — `validate()` returns `Promise<{ valid, err? }>` (never rejects).
304
+ * Created via `ZSchema.create({ async: true, safe: true })`.
305
+ */
203
306
  export class ZSchemaAsyncSafe extends ZSchemaBase {
204
- /** @deprecated Use ZSchema.create() instead. */
205
- private constructor(options?: ZSchemaOptions) {
206
- super(options);
307
+ /** @internal Use ZSchema.create() instead. */
308
+ constructor(options: ZSchemaOptions | undefined, token: symbol) {
309
+ super(options, token);
207
310
  }
208
311
 
312
+ /**
313
+ * Validate JSON data against a schema asynchronously.
314
+ * The promise always resolves (never rejects).
315
+ * @param json - The data to validate.
316
+ * @param schema - A JSON Schema object or a schema id string.
317
+ * @param options - Per-call options.
318
+ * @returns A promise resolving to `{ valid: true }` or `{ valid: false, err: ValidateError }`.
319
+ */
209
320
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): Promise<ValidateResponse> {
210
321
  return new Promise((resolve) => {
211
322
  try {
@@ -218,6 +329,11 @@ export class ZSchemaAsyncSafe extends ZSchemaBase {
218
329
  });
219
330
  }
220
331
 
332
+ /**
333
+ * Validate one or more JSON Schemas.
334
+ * @param schemaOrArr - A single schema or an array of schemas.
335
+ * @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
336
+ */
221
337
  validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): ValidateResponse {
222
338
  try {
223
339
  this._validateSchema(schemaOrArr);