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
@@ -2,7 +2,7 @@ import type { JsonSchemaInternal } from '../json-schema-versions.js';
2
2
  import type { Report } from '../report.js';
3
3
  import type { ZSchemaBase } from '../z-schema-base.js';
4
4
 
5
- import { getFormatValidators } from '../format-validators.js';
5
+ import { resolveFormatValidator } from '../format-validators.js';
6
6
  import { decodeBase64, isValidBase64 } from '../utils/base64.js';
7
7
  import { compileSchemaRegex } from '../utils/schema-regex.js';
8
8
  import { unicodeLength } from '../utils/unicode.js';
@@ -13,9 +13,9 @@ import { isFormatAssertionVocabEnabled, shouldSkipValidate } from './shared.js';
13
13
  // minLength
14
14
  // ---------------------------------------------------------------------------
15
15
 
16
- export function minLengthValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
16
+ export function minLengthValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
17
17
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.2.2
18
- if (shouldSkipValidate(this.validateOptions, ['MIN_LENGTH'])) {
18
+ if (shouldSkipValidate(ctx.validateOptions, ['MIN_LENGTH'])) {
19
19
  return;
20
20
  }
21
21
  if (typeof json !== 'string') {
@@ -30,9 +30,9 @@ export function minLengthValidator(this: ZSchemaBase, report: Report, schema: Js
30
30
  // maxLength
31
31
  // ---------------------------------------------------------------------------
32
32
 
33
- export function maxLengthValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
33
+ export function maxLengthValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
34
34
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.1.2
35
- if (shouldSkipValidate(this.validateOptions, ['MAX_LENGTH'])) {
35
+ if (shouldSkipValidate(ctx.validateOptions, ['MAX_LENGTH'])) {
36
36
  return;
37
37
  }
38
38
  if (typeof json !== 'string') {
@@ -47,9 +47,9 @@ export function maxLengthValidator(this: ZSchemaBase, report: Report, schema: Js
47
47
  // pattern
48
48
  // ---------------------------------------------------------------------------
49
49
 
50
- export function patternValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
50
+ export function patternValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
51
51
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.3.2
52
- if (shouldSkipValidate(this.validateOptions, ['PATTERN'])) {
52
+ if (shouldSkipValidate(ctx.validateOptions, ['PATTERN'])) {
53
53
  return;
54
54
  }
55
55
  if (typeof json !== 'string') {
@@ -70,27 +70,24 @@ export function patternValidator(this: ZSchemaBase, report: Report, schema: Json
70
70
  // format
71
71
  // ---------------------------------------------------------------------------
72
72
 
73
- export function formatValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
73
+ export function formatValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
74
74
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.7.2
75
- if (this.options.formatAssertions === false) {
75
+ if (ctx.options.formatAssertions === false) {
76
76
  return;
77
77
  }
78
78
 
79
79
  // When formatAssertions is explicitly true, respect the meta-schema vocabulary:
80
80
  // for draft 2019-09/2020-12, format is annotation-only unless the format-assertion
81
81
  // vocabulary is enabled in the meta-schema.
82
- if (this.options.formatAssertions === true) {
83
- if (!isFormatAssertionVocabEnabled(schema, report, this.options.version)) {
84
- return;
85
- }
82
+ if (ctx.options.formatAssertions === true && !isFormatAssertionVocabEnabled(schema, report, ctx.options.version)) {
83
+ return;
86
84
  }
87
85
 
88
- const isModernDraft = this.options.version === 'draft2019-09' || this.options.version === 'draft2020-12';
86
+ const isModernDraft = ctx.options.version === 'draft2019-09' || ctx.options.version === 'draft2020-12';
89
87
 
90
- const formatValidators = getFormatValidators(this.options);
91
- const formatValidatorFn = formatValidators[schema.format!];
88
+ const formatValidatorFn = resolveFormatValidator(schema.format!, ctx.options);
92
89
  if (typeof formatValidatorFn === 'function') {
93
- if (shouldSkipValidate(this.validateOptions, ['INVALID_FORMAT'])) {
90
+ if (shouldSkipValidate(ctx.validateOptions, ['INVALID_FORMAT'])) {
94
91
  return;
95
92
  }
96
93
  if (report.hasError('INVALID_TYPE', [schema.type, whatIs(json)])) {
@@ -98,40 +95,38 @@ export function formatValidator(this: ZSchemaBase, report: Report, schema: JsonS
98
95
  }
99
96
  if (formatValidatorFn.length === 2) {
100
97
  // callback-based async
101
- report.addAsyncTaskWithPath(formatValidatorFn, [json], function (result) {
98
+ report.addAsyncTaskWithPath(formatValidatorFn, [json], (result) => {
102
99
  if (result !== true) {
103
100
  report.addError('INVALID_FORMAT', [schema.format!, JSON.stringify(json)], undefined, schema, 'format');
104
101
  }
105
102
  });
106
103
  } else {
107
- const result = formatValidatorFn.call(this, json);
104
+ const result = formatValidatorFn.call(ctx, json);
108
105
  if (result instanceof Promise) {
109
106
  // Promise-based async
110
107
  const promiseResult = result;
111
108
  report.addAsyncTaskWithPath(
112
- async (callback) => {
109
+ async (callback: (result: unknown) => void) => {
113
110
  try {
114
111
  const resolved = await promiseResult;
115
112
  callback(resolved);
116
- } catch (_error) {
113
+ } catch {
117
114
  callback(false);
118
115
  }
119
116
  },
120
- [] as any,
121
- function (resolvedResult) {
117
+ [],
118
+ (resolvedResult) => {
122
119
  if (resolvedResult !== true) {
123
120
  report.addError('INVALID_FORMAT', [schema.format!, JSON.stringify(json)], undefined, schema, 'format');
124
121
  }
125
122
  }
126
123
  );
127
- } else {
124
+ } else if (!result) {
128
125
  // sync
129
- if (result !== true) {
130
- report.addError('INVALID_FORMAT', [schema.format!, JSON.stringify(json)], undefined, schema, 'format');
131
- }
126
+ report.addError('INVALID_FORMAT', [schema.format!, JSON.stringify(json)], undefined, schema, 'format');
132
127
  }
133
128
  }
134
- } else if (this.options.ignoreUnknownFormats !== true && !isModernDraft) {
129
+ } else if (ctx.options.ignoreUnknownFormats !== true && !isModernDraft) {
135
130
  report.addError('UNKNOWN_FORMAT', [schema.format!], undefined, schema, 'format');
136
131
  }
137
132
  }
@@ -140,15 +135,15 @@ export function formatValidator(this: ZSchemaBase, report: Report, schema: JsonS
140
135
  // contentEncoding
141
136
  // ---------------------------------------------------------------------------
142
137
 
143
- export function contentEncodingValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
144
- if (this.options.version !== 'draft-07') {
138
+ export function contentEncodingValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
139
+ if (ctx.options.version !== 'draft-07') {
145
140
  return;
146
141
  }
147
142
  if (typeof json !== 'string') {
148
143
  return;
149
144
  }
150
145
 
151
- const contentEncoding = schema.contentEncoding;
146
+ const { contentEncoding } = schema;
152
147
  if (contentEncoding !== 'base64') {
153
148
  return;
154
149
  }
@@ -168,20 +163,15 @@ export function contentEncodingValidator(this: ZSchemaBase, report: Report, sche
168
163
  // contentMediaType
169
164
  // ---------------------------------------------------------------------------
170
165
 
171
- export function contentMediaTypeValidator(
172
- this: ZSchemaBase,
173
- report: Report,
174
- schema: JsonSchemaInternal,
175
- json: unknown
176
- ) {
177
- if (this.options.version !== 'draft-07') {
166
+ export function contentMediaTypeValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
167
+ if (ctx.options.version !== 'draft-07') {
178
168
  return;
179
169
  }
180
170
  if (typeof json !== 'string') {
181
171
  return;
182
172
  }
183
173
 
184
- const contentMediaType = schema.contentMediaType;
174
+ const { contentMediaType } = schema;
185
175
  if (contentMediaType !== 'application/json') {
186
176
  return;
187
177
  }
@@ -10,9 +10,9 @@ import { shouldSkipValidate } from './shared.js';
10
10
  // type
11
11
  // ---------------------------------------------------------------------------
12
12
 
13
- export function typeValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
13
+ export function typeValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
14
14
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.2.2
15
- if (shouldSkipValidate(this.validateOptions, ['INVALID_TYPE'])) {
15
+ if (shouldSkipValidate(ctx.validateOptions, ['INVALID_TYPE'])) {
16
16
  return;
17
17
  }
18
18
  const jsonType = whatIs(json);
@@ -20,10 +20,8 @@ export function typeValidator(this: ZSchemaBase, report: Report, schema: JsonSch
20
20
  if (jsonType !== schema.type && (jsonType !== 'integer' || schema.type !== 'number')) {
21
21
  report.addError('INVALID_TYPE', [schema.type, jsonType], undefined, schema, 'type');
22
22
  }
23
- } else {
24
- if (!schema.type!.includes(jsonType) && (jsonType !== 'integer' || !schema.type!.includes('number'))) {
25
- report.addError('INVALID_TYPE', [JSON.stringify(schema.type), jsonType], undefined, schema, 'type');
26
- }
23
+ } else if (!schema.type!.includes(jsonType) && (jsonType !== 'integer' || !schema.type!.includes('number'))) {
24
+ report.addError('INVALID_TYPE', [JSON.stringify(schema.type), jsonType], undefined, schema, 'type');
27
25
  }
28
26
  }
29
27
 
@@ -31,25 +29,27 @@ export function typeValidator(this: ZSchemaBase, report: Report, schema: JsonSch
31
29
  // enum
32
30
  // ---------------------------------------------------------------------------
33
31
 
34
- export function enumValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
32
+ export function enumValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
35
33
  // http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.5.1.2
36
- if (shouldSkipValidate(this.validateOptions, ['ENUM_CASE_MISMATCH', 'ENUM_MISMATCH'])) {
34
+ if (shouldSkipValidate(ctx.validateOptions, ['ENUM_CASE_MISMATCH', 'ENUM_MISMATCH'])) {
37
35
  return;
38
36
  }
39
- let match = false,
40
- caseInsensitiveMatch = false;
37
+ const eqOpts = { maxDepth: ctx.options.maxRecursionDepth };
38
+ const eqOptsCI = { caseInsensitiveComparison: true, maxDepth: ctx.options.maxRecursionDepth };
39
+ let caseInsensitiveMatch = false,
40
+ match = false;
41
41
  for (const enumVal of schema.enum!) {
42
- if (areEqual(json, enumVal, { maxDepth: this.options.maxRecursionDepth })) {
42
+ if (areEqual(json, enumVal, eqOpts)) {
43
43
  match = true;
44
44
  break;
45
- } else if (areEqual(json, enumVal, { caseInsensitiveComparison: true, maxDepth: this.options.maxRecursionDepth })) {
45
+ } else if (areEqual(json, enumVal, eqOptsCI)) {
46
46
  caseInsensitiveMatch = true;
47
47
  }
48
48
  }
49
49
 
50
- if (match === false) {
50
+ if (!match) {
51
51
  const error =
52
- caseInsensitiveMatch && this.options.enumCaseInsensitiveComparison ? 'ENUM_CASE_MISMATCH' : 'ENUM_MISMATCH';
52
+ caseInsensitiveMatch && ctx.options.enumCaseInsensitiveComparison ? 'ENUM_CASE_MISMATCH' : 'ENUM_MISMATCH';
53
53
  report.addError(error, [JSON.stringify(json)], undefined, schema, 'enum');
54
54
  }
55
55
  }
@@ -58,9 +58,9 @@ export function enumValidator(this: ZSchemaBase, report: Report, schema: JsonSch
58
58
  // const
59
59
  // ---------------------------------------------------------------------------
60
60
 
61
- export function constValidator(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
61
+ export function constValidator(ctx: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown) {
62
62
  const constValue = schema.const;
63
- if (areEqual(json, constValue, { maxDepth: this.options.maxRecursionDepth }) === false) {
64
- report.addError('CONST', [JSON.stringify(constValue)], undefined, schema, undefined);
63
+ if (!areEqual(json, constValue, { maxDepth: ctx.options.maxRecursionDepth })) {
64
+ report.addError('CONST', [JSON.stringify(constValue)], undefined, schema);
65
65
  }
66
66
  }
@@ -1,10 +1,10 @@
1
- import type { ValidateError } from './errors.js';
1
+ import type { Errors, ValidateError } from './errors.js';
2
2
  import type { FormatValidatorFn } from './format-validators.js';
3
3
  import type { JsonSchema, JsonSchemaInternal, JsonSchemaVersion } from './json-schema-versions.js';
4
4
  import type { SchemaErrorDetail } from './report.js';
5
5
  import type { ZSchemaOptions } from './z-schema-options.js';
6
6
 
7
- import { type Errors, getValidateError } from './errors.js';
7
+ import { getValidateError } from './errors.js';
8
8
  import { getSupportedFormats } from './format-validators.js';
9
9
  import { VERSION_SCHEMA_URL_MAPPING } from './json-schema-versions.js';
10
10
  import { isInternalKey } from './json-schema.js';
@@ -26,7 +26,10 @@ export interface ValidateOptions {
26
26
  excludeErrors?: Array<keyof typeof Errors>;
27
27
  }
28
28
 
29
- export type ValidateResponse = { valid: boolean; err?: ValidateError };
29
+ export interface ValidateResponse {
30
+ valid: boolean;
31
+ err?: ValidateError;
32
+ }
30
33
 
31
34
  export type ValidateCallback = (err: ValidateResponse['err'], valid: ValidateResponse['valid']) => void;
32
35
 
@@ -62,7 +65,7 @@ export class ZSchemaBase {
62
65
  * create a circular dependency).
63
66
  */
64
67
  _jsonValidate(report: Report, schema: boolean | JsonSchemaInternal, json: unknown): boolean {
65
- return validateJson.call(this, report, schema, json);
68
+ return validateJson(this, report, schema, json);
66
69
  }
67
70
 
68
71
  getDefaultSchemaId(): string {
@@ -73,8 +76,7 @@ export class ZSchemaBase {
73
76
 
74
77
  _validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions, callback: ValidateCallback): void;
75
78
  _validate(json: unknown, schema: JsonSchema | string, callback: ValidateCallback): void;
76
- _validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions): true;
77
- _validate(json: unknown, schema: JsonSchema | string): true;
79
+ _validate(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): true;
78
80
  _validate(
79
81
  json: unknown,
80
82
  schema: JsonSchema | string,
@@ -93,10 +95,10 @@ export class ZSchemaBase {
93
95
 
94
96
  if (typeof schema !== 'string' && typeof schema !== 'boolean' && !isObject(schema)) {
95
97
  const e = new Error(
96
- 'Invalid .validate call - schema must be a string or object but ' + whatIs(schema) + ' was passed!'
98
+ `Invalid .validate call - schema must be a string or object but ${whatIs(schema)} was passed!`
97
99
  );
98
100
  if (callback) {
99
- setTimeout(function () {
101
+ setTimeout(() => {
100
102
  callback(e, false);
101
103
  }, 0);
102
104
  return;
@@ -113,9 +115,9 @@ export class ZSchemaBase {
113
115
  const schemaName = schema;
114
116
  _schema = this.scache.getSchema(report, schemaName)!;
115
117
  if (!_schema) {
116
- const e = new Error("Schema with id '" + schemaName + "' wasn't found in the validator cache!");
118
+ const e = new Error(`Schema with id '${schemaName}' wasn't found in the validator cache!`);
117
119
  if (callback) {
118
- setTimeout(function () {
120
+ setTimeout(() => {
119
121
  callback(e, false);
120
122
  }, 0);
121
123
  return;
@@ -144,11 +146,11 @@ export class ZSchemaBase {
144
146
 
145
147
  if (options.schemaPath) {
146
148
  report.rootSchema = _schema;
147
- _schema = get(_schema, options.schemaPath);
149
+ _schema = get(_schema, options.schemaPath) as JsonSchemaInternal;
148
150
  if (!_schema) {
149
- const e = new Error("Schema path '" + options.schemaPath + "' wasn't found in the schema!");
151
+ const e = new Error(`Schema path '${options.schemaPath}' wasn't found in the schema!`);
150
152
  if (callback) {
151
- setTimeout(function () {
153
+ setTimeout(() => {
152
154
  callback(e, false);
153
155
  }, 0);
154
156
  return;
@@ -158,7 +160,7 @@ export class ZSchemaBase {
158
160
  }
159
161
 
160
162
  if (!foundError) {
161
- validateJson.call(this, report, _schema, json);
163
+ validateJson(this, report, _schema, json);
162
164
  }
163
165
 
164
166
  if (callback) {
@@ -187,13 +189,13 @@ export class ZSchemaBase {
187
189
  const report = new Report(this.options);
188
190
 
189
191
  if (Array.isArray(schemaOrArr)) {
190
- const arr = this.scache.getSchema(report, schemaOrArr)!;
192
+ const arr = this.scache.getSchema(report, schemaOrArr);
191
193
  const compiled = this.sc.compileSchema(report, arr);
192
194
  if (compiled) {
193
195
  this.sv.validateSchema(report, arr);
194
196
  }
195
197
  } else {
196
- const schema = this.scache.getSchema(report, schemaOrArr)!;
198
+ const schema = this.scache.getSchema(report, schemaOrArr);
197
199
  const compiled = this.sc.compileSchema(report, schema);
198
200
  if (compiled) {
199
201
  this.sv.validateSchema(report, schema);
@@ -256,11 +258,13 @@ export class ZSchemaBase {
256
258
  * @returns An array of unresolvable reference URIs.
257
259
  */
258
260
  getMissingReferences(err: ValidateError): string[] {
259
- if (!err) return [];
261
+ if (!err) {
262
+ return [];
263
+ }
260
264
  const details = err.details || [];
261
265
  const missingRefs: string[] = [];
262
- function collect(details: SchemaErrorDetail[]) {
263
- for (const detail of details) {
266
+ function collect(items: SchemaErrorDetail[]) {
267
+ for (const detail of items) {
264
268
  if (detail.code === 'UNRESOLVABLE_REFERENCE' || detail.code === 'SCHEMA_NOT_REACHABLE') {
265
269
  missingRefs.push(detail.params[0] as string);
266
270
  }
@@ -281,9 +285,11 @@ export class ZSchemaBase {
281
285
  getMissingRemoteReferences(err: ValidateError) {
282
286
  const missingReferences = this.getMissingReferences(err);
283
287
  const missingRemoteReferences: string[] = [];
288
+ const seen = new Set<string>();
284
289
  for (const ref of missingReferences) {
285
290
  const remoteReference = getRemotePath(ref);
286
- if (remoteReference && !missingRemoteReferences.includes(remoteReference)) {
291
+ if (remoteReference && !seen.has(remoteReference)) {
292
+ seen.add(remoteReference);
287
293
  missingRemoteReferences.push(remoteReference);
288
294
  }
289
295
  }
@@ -299,41 +305,46 @@ export class ZSchemaBase {
299
305
  getResolvedSchema(schemaId: string): JsonSchema | undefined {
300
306
  const report = new Report(this.options);
301
307
  const schema = this.scache.getSchemaByUri(report, schemaId);
302
- if (!schema) return undefined;
308
+ if (!schema) {
309
+ return undefined;
310
+ }
303
311
 
304
312
  const clonedSchema = deepClone(schema, this.options.maxRecursionDepth);
305
313
 
306
314
  const visited = new WeakSet<object>();
307
315
 
308
316
  // clean-up the schema and resolve references
309
- const cleanup = function (schema: any) {
310
- let key;
311
- const typeOf = whatIs(schema);
317
+ const cleanup = (node: unknown) => {
318
+ const typeOf = whatIs(node);
312
319
  if (typeOf !== 'object' && typeOf !== 'array') {
313
320
  return;
314
321
  }
315
322
 
316
- if (visited.has(schema)) {
323
+ if (visited.has(node as object)) {
317
324
  return;
318
325
  }
319
326
 
320
- visited.add(schema);
321
-
322
- if (schema.$ref && schema.__$refResolved) {
323
- const from = schema.__$refResolved;
324
- const to = schema;
325
- delete schema.$ref;
326
- delete schema.__$refResolved;
327
- for (key in from) {
328
- copyProp(from, to, key);
327
+ visited.add(node as object);
328
+
329
+ const schemaNode = node as JsonSchemaInternal;
330
+ if (schemaNode.$ref && schemaNode.__$refResolved) {
331
+ const from = schemaNode.__$refResolved;
332
+ const to = schemaNode;
333
+ delete schemaNode.$ref;
334
+ delete schemaNode.__$refResolved;
335
+ for (const key in from) {
336
+ if (Object.hasOwn(from, key)) {
337
+ copyProp(from, to, key);
338
+ }
329
339
  }
330
340
  }
331
- for (key in schema) {
332
- if (Object.hasOwn(schema, key)) {
341
+ const record = node as Record<string, unknown>;
342
+ for (const key in record) {
343
+ if (Object.hasOwn(record, key)) {
333
344
  if (isInternalKey(key)) {
334
- delete (schema as any)[key];
345
+ delete record[key];
335
346
  } else {
336
- cleanup((schema as any)[key]);
347
+ cleanup(record[key]);
337
348
  }
338
349
  }
339
350
  }
@@ -1,7 +1,8 @@
1
1
  import type { FormatValidatorFn } from './format-validators.js';
2
+ import type { JsonSchemaVersion } from './json-schema-versions.js';
2
3
  import type { Report } from './report.js';
3
4
 
4
- import { CURRENT_DEFAULT_SCHEMA_VERSION, type JsonSchemaVersion } from './json-schema-versions.js';
5
+ import { CURRENT_DEFAULT_SCHEMA_VERSION } from './json-schema-versions.js';
5
6
  import { shallowClone } from './utils/clone.js';
6
7
  import { DEFAULT_MAX_RECURSION_DEPTH, MAX_ASYNC_TIMEOUT } from './utils/constants.js';
7
8
 
@@ -103,7 +104,7 @@ export const normalizeOptions = (options?: ZSchemaOptions) => {
103
104
  // check that the options are correctly configured
104
105
  for (const key of keys) {
105
106
  if (defaultOptions[key] === undefined) {
106
- throw new Error('Unexpected option passed to constructor: ' + key);
107
+ throw new Error(`Unexpected option passed to constructor: ${key}`);
107
108
  }
108
109
  }
109
110
 
@@ -111,7 +112,7 @@ export const normalizeOptions = (options?: ZSchemaOptions) => {
111
112
  keys = Object.keys(defaultOptions) as Array<keyof ZSchemaOptions>;
112
113
  for (const key of keys) {
113
114
  if (options[key] === undefined) {
114
- (options as any)[key] = shallowClone(defaultOptions[key]);
115
+ (options as Record<string, unknown>)[key] = shallowClone(defaultOptions[key]);
115
116
  }
116
117
  }
117
118
 
package/src/z-schema.ts CHANGED
@@ -15,11 +15,6 @@ import { defaultOptions } from './z-schema-options.js';
15
15
  import { getSchemaReader, setSchemaReader } from './z-schema-reader.js';
16
16
 
17
17
  export class ZSchema extends ZSchemaBase {
18
- /** @internal Use ZSchema.create() instead. */
19
- constructor(options: ZSchemaOptions | undefined, token: symbol) {
20
- super(options, token);
21
- }
22
-
23
18
  // ----- static methods start -----
24
19
 
25
20
  // class scoped format functions
@@ -30,7 +25,7 @@ export class ZSchema extends ZSchemaBase {
30
25
  * @param validatorFunction - A sync or async function `(value: unknown) => boolean | Promise<boolean>`.
31
26
  */
32
27
  public static registerFormat(name: string, validatorFunction: FormatValidatorFn): void {
33
- return registerFormat(name, validatorFunction);
28
+ registerFormat(name, validatorFunction);
34
29
  }
35
30
 
36
31
  /**
@@ -38,7 +33,7 @@ export class ZSchema extends ZSchemaBase {
38
33
  * @param name - The format name to unregister.
39
34
  */
40
35
  public static unregisterFormat(name: string): void {
41
- return unregisterFormat(name);
36
+ unregisterFormat(name);
42
37
  }
43
38
 
44
39
  /** Returns the names of all globally registered format validators. */
@@ -72,7 +67,7 @@ export class ZSchema extends ZSchemaBase {
72
67
  * @param schemaReader - A function `(uri: string) => JsonSchema | undefined`, or `undefined` to clear.
73
68
  */
74
69
  public static setSchemaReader(schemaReader: SchemaReader | undefined) {
75
- return setSchemaReader(schemaReader);
70
+ setSchemaReader(schemaReader);
76
71
  }
77
72
 
78
73
  public static schemaSymbol = schemaSymbol;
@@ -148,8 +143,8 @@ export class ZSchema extends ZSchemaBase {
148
143
  try {
149
144
  this._validate(json, schema, options ?? {});
150
145
  return { valid: true };
151
- } catch (err) {
152
- return { valid: false, err: err as ValidateError };
146
+ } catch (error) {
147
+ return { valid: false, err: error as ValidateError };
153
148
  }
154
149
  }
155
150
 
@@ -164,11 +159,15 @@ export class ZSchema extends ZSchemaBase {
164
159
  validateAsync(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): Promise<true> {
165
160
  return new Promise((resolve, reject) => {
166
161
  try {
167
- this._validate(json, schema, options || {}, (err, valid) =>
168
- err || valid !== true ? reject(err) : resolve(valid)
169
- );
170
- } catch (err) {
171
- reject(err);
162
+ this._validate(json, schema, options || {}, (err, valid) => {
163
+ if (err || !valid) {
164
+ reject(err ?? new Error('Validation failed'));
165
+ } else {
166
+ resolve(valid);
167
+ }
168
+ });
169
+ } catch (error) {
170
+ reject(error instanceof Error ? error : new Error(String(error), { cause: error }));
172
171
  }
173
172
  });
174
173
  }
@@ -187,8 +186,8 @@ export class ZSchema extends ZSchemaBase {
187
186
  this._validate(json, schema, options || {}, (err, valid) => {
188
187
  resolve({ valid, err });
189
188
  });
190
- } catch (err) {
191
- resolve({ valid: false, err: err as ValidateError });
189
+ } catch (error) {
190
+ resolve({ valid: false, err: error as ValidateError });
192
191
  }
193
192
  });
194
193
  }
@@ -212,8 +211,8 @@ export class ZSchema extends ZSchemaBase {
212
211
  try {
213
212
  this._validateSchema(schemaOrArr);
214
213
  return { valid: true };
215
- } catch (err) {
216
- return { valid: false, err: err as ValidateError };
214
+ } catch (error) {
215
+ return { valid: false, err: error as ValidateError };
217
216
  }
218
217
  }
219
218
  }
@@ -223,11 +222,6 @@ export class ZSchema extends ZSchemaBase {
223
222
  * Created via `ZSchema.create({ safe: true })`.
224
223
  */
225
224
  export class ZSchemaSafe extends ZSchemaBase {
226
- /** @internal Use ZSchema.create() instead. */
227
- constructor(options: ZSchemaOptions | undefined, token: symbol) {
228
- super(options, token);
229
- }
230
-
231
225
  /**
232
226
  * Validate JSON data against a schema.
233
227
  * @param json - The data to validate.
@@ -239,8 +233,8 @@ export class ZSchemaSafe extends ZSchemaBase {
239
233
  try {
240
234
  this._validate(json, schema, options);
241
235
  return { valid: true };
242
- } catch (err) {
243
- return { valid: false, err: err as ValidateError };
236
+ } catch (error) {
237
+ return { valid: false, err: error as ValidateError };
244
238
  }
245
239
  }
246
240
 
@@ -253,8 +247,8 @@ export class ZSchemaSafe extends ZSchemaBase {
253
247
  try {
254
248
  this._validateSchema(schemaOrArr);
255
249
  return { valid: true };
256
- } catch (err) {
257
- return { valid: false, err: err as ValidateError };
250
+ } catch (error) {
251
+ return { valid: false, err: error as ValidateError };
258
252
  }
259
253
  }
260
254
  }
@@ -264,11 +258,6 @@ export class ZSchemaSafe extends ZSchemaBase {
264
258
  * Created via `ZSchema.create({ async: true })`.
265
259
  */
266
260
  export class ZSchemaAsync extends ZSchemaBase {
267
- /** @internal Use ZSchema.create() instead. */
268
- constructor(options: ZSchemaOptions | undefined, token: symbol) {
269
- super(options, token);
270
- }
271
-
272
261
  /**
273
262
  * Validate JSON data against a schema asynchronously.
274
263
  * @param json - The data to validate.
@@ -280,9 +269,15 @@ export class ZSchemaAsync extends ZSchemaBase {
280
269
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): Promise<true> {
281
270
  return new Promise((resolve, reject) => {
282
271
  try {
283
- this._validate(json, schema, options, (err, valid) => (err || valid !== true ? reject(err) : resolve(valid)));
284
- } catch (err) {
285
- reject(err);
272
+ this._validate(json, schema, options, (err, valid) => {
273
+ if (err || !valid) {
274
+ reject(err ?? new Error('Validation failed'));
275
+ } else {
276
+ resolve(valid);
277
+ }
278
+ });
279
+ } catch (error) {
280
+ reject(error instanceof Error ? error : new Error(String(error), { cause: error }));
286
281
  }
287
282
  });
288
283
  }
@@ -303,11 +298,6 @@ export class ZSchemaAsync extends ZSchemaBase {
303
298
  * Created via `ZSchema.create({ async: true, safe: true })`.
304
299
  */
305
300
  export class ZSchemaAsyncSafe extends ZSchemaBase {
306
- /** @internal Use ZSchema.create() instead. */
307
- constructor(options: ZSchemaOptions | undefined, token: symbol) {
308
- super(options, token);
309
- }
310
-
311
301
  /**
312
302
  * Validate JSON data against a schema asynchronously.
313
303
  * The promise always resolves (never rejects).
@@ -322,8 +312,8 @@ export class ZSchemaAsyncSafe extends ZSchemaBase {
322
312
  this._validate(json, schema, options, (err, valid) => {
323
313
  resolve({ valid, err });
324
314
  });
325
- } catch (err) {
326
- resolve({ valid: false, err: err as ValidateError });
315
+ } catch (error) {
316
+ resolve({ valid: false, err: error as ValidateError });
327
317
  }
328
318
  });
329
319
  }
@@ -337,8 +327,8 @@ export class ZSchemaAsyncSafe extends ZSchemaBase {
337
327
  try {
338
328
  this._validateSchema(schemaOrArr);
339
329
  return { valid: true };
340
- } catch (err) {
341
- return { valid: false, err: err as ValidateError };
330
+ } catch (error) {
331
+ return { valid: false, err: error as ValidateError };
342
332
  }
343
333
  }
344
334
  }