z-schema 12.0.4 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/z-schema +7 -2
- package/cjs/index.d.ts +541 -530
- package/cjs/index.js +3963 -7740
- package/dist/errors.d.mts +64 -0
- package/dist/errors.mjs +67 -0
- package/dist/format-validators.d.mts +14 -0
- package/dist/format-validators.mjs +261 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.mjs +7 -0
- package/dist/json-schema-versions.d.mts +137 -0
- package/dist/json-schema-versions.mjs +11 -0
- package/dist/json-schema.d.mts +61 -0
- package/dist/json-schema.mjs +53 -0
- package/dist/json-validation.mjs +441 -0
- package/dist/report.d.mts +97 -0
- package/dist/report.mjs +194 -0
- package/dist/schema-cache.d.mts +23 -0
- package/dist/schema-cache.mjs +144 -0
- package/dist/schema-compiler.d.mts +23 -0
- package/dist/schema-compiler.mjs +265 -0
- package/dist/schema-validator.d.mts +15 -0
- package/dist/schema-validator.mjs +446 -0
- package/dist/schemas/draft-04-schema.mjs +125 -0
- package/dist/schemas/draft-06-schema.mjs +126 -0
- package/dist/schemas/draft-07-schema.mjs +141 -0
- package/dist/schemas/draft-2019-09-meta-applicator.mjs +46 -0
- package/dist/schemas/draft-2019-09-meta-content.mjs +15 -0
- package/dist/schemas/draft-2019-09-meta-core.mjs +52 -0
- package/dist/schemas/draft-2019-09-meta-format.mjs +11 -0
- package/dist/schemas/draft-2019-09-meta-meta-data.mjs +31 -0
- package/dist/schemas/draft-2019-09-meta-validation.mjs +80 -0
- package/dist/schemas/draft-2019-09-schema.mjs +39 -0
- package/dist/schemas/draft-2020-12-meta-applicator.mjs +45 -0
- package/dist/schemas/draft-2020-12-meta-content.mjs +15 -0
- package/dist/schemas/draft-2020-12-meta-core.mjs +46 -0
- package/dist/schemas/draft-2020-12-meta-format-annotation.mjs +11 -0
- package/dist/schemas/draft-2020-12-meta-format-assertion.mjs +11 -0
- package/dist/schemas/draft-2020-12-meta-meta-data.mjs +31 -0
- package/dist/schemas/draft-2020-12-meta-unevaluated.mjs +14 -0
- package/dist/schemas/draft-2020-12-meta-validation.mjs +80 -0
- package/dist/schemas/draft-2020-12-schema.mjs +55 -0
- package/dist/utils/array.mjs +54 -0
- package/dist/utils/base64.mjs +21 -0
- package/dist/utils/clone.mjs +42 -0
- package/dist/utils/constants.mjs +16 -0
- package/dist/utils/date.mjs +19 -0
- package/dist/utils/hostname.mjs +73 -0
- package/dist/utils/json.mjs +34 -0
- package/dist/utils/properties.mjs +11 -0
- package/dist/utils/schema-regex.mjs +49 -0
- package/dist/utils/symbols.mjs +5 -0
- package/dist/utils/time.mjs +42 -0
- package/dist/utils/unicode.mjs +12 -0
- package/dist/utils/uri.mjs +12 -0
- package/dist/utils/what-is.mjs +23 -0
- package/dist/validation/array.mjs +57 -0
- package/dist/validation/combinators.mjs +62 -0
- package/dist/validation/numeric.mjs +38 -0
- package/dist/validation/object.mjs +109 -0
- package/dist/validation/ref.mjs +49 -0
- package/dist/validation/shared.mjs +97 -0
- package/dist/validation/string.mjs +88 -0
- package/dist/validation/type.mjs +32 -0
- package/dist/z-schema-base.d.mts +85 -0
- package/dist/z-schema-base.mjs +230 -0
- package/dist/z-schema-options.d.mts +35 -0
- package/dist/z-schema-options.mjs +55 -0
- package/dist/z-schema-reader.d.mts +6 -0
- package/dist/z-schema-reader.mjs +10 -0
- package/dist/z-schema-versions.mjs +67 -0
- package/dist/z-schema.d.mts +193 -0
- package/dist/z-schema.mjs +300 -0
- package/package.json +49 -64
- package/src/index.ts +3 -3
- package/src/schema-compiler.ts +30 -10
- package/src/schema-validator.ts +1 -1
- package/src/utils/schema-regex.ts +13 -2
- package/src/z-schema-base.ts +1 -1
- package/src/z-schema-versions.ts +1 -2
- package/src/z-schema.ts +0 -1
- package/umd/ZSchema.js +5934 -8110
- package/umd/ZSchema.min.js +2 -1
- package/dist/errors.js +0 -72
- package/dist/format-validators.js +0 -392
- package/dist/index.js +0 -5
- package/dist/json-schema-versions.js +0 -8
- package/dist/json-schema.js +0 -84
- package/dist/json-validation.js +0 -728
- package/dist/package.json +0 -3
- package/dist/report.js +0 -265
- package/dist/schema-cache.js +0 -211
- package/dist/schema-compiler.js +0 -415
- package/dist/schema-validator.js +0 -721
- package/dist/schemas/draft-04-schema.json +0 -149
- package/dist/schemas/draft-06-schema.json +0 -155
- package/dist/schemas/draft-07-schema.json +0 -172
- package/dist/schemas/draft-2019-09-meta-applicator.json +0 -52
- package/dist/schemas/draft-2019-09-meta-content.json +0 -12
- package/dist/schemas/draft-2019-09-meta-core.json +0 -53
- package/dist/schemas/draft-2019-09-meta-format.json +0 -10
- package/dist/schemas/draft-2019-09-meta-meta-data.json +0 -32
- package/dist/schemas/draft-2019-09-meta-validation.json +0 -94
- package/dist/schemas/draft-2019-09-schema.json +0 -41
- package/dist/schemas/draft-2020-12-meta-applicator.json +0 -44
- package/dist/schemas/draft-2020-12-meta-content.json +0 -12
- package/dist/schemas/draft-2020-12-meta-core.json +0 -47
- package/dist/schemas/draft-2020-12-meta-format-annotation.json +0 -10
- package/dist/schemas/draft-2020-12-meta-format-assertion.json +0 -10
- package/dist/schemas/draft-2020-12-meta-meta-data.json +0 -32
- package/dist/schemas/draft-2020-12-meta-unevaluated.json +0 -11
- package/dist/schemas/draft-2020-12-meta-validation.json +0 -94
- package/dist/schemas/draft-2020-12-schema.json +0 -57
- package/dist/types/errors.d.ts +0 -64
- package/dist/types/format-validators.d.ts +0 -11
- package/dist/types/index.d.ts +0 -14
- package/dist/types/json-schema-versions.d.ts +0 -142
- package/dist/types/json-schema.d.ts +0 -66
- package/dist/types/json-validation.d.ts +0 -6
- package/dist/types/report.d.ts +0 -94
- package/dist/types/schema-cache.d.ts +0 -27
- package/dist/types/schema-compiler.d.ts +0 -31
- package/dist/types/schema-validator.d.ts +0 -10
- package/dist/types/utils/array.d.ts +0 -9
- package/dist/types/utils/base64.d.ts +0 -2
- package/dist/types/utils/clone.d.ts +0 -2
- package/dist/types/utils/constants.d.ts +0 -19
- package/dist/types/utils/date.d.ts +0 -1
- package/dist/types/utils/hostname.d.ts +0 -2
- package/dist/types/utils/json.d.ts +0 -9
- package/dist/types/utils/properties.d.ts +0 -1
- package/dist/types/utils/schema-regex.d.ts +0 -10
- package/dist/types/utils/symbols.d.ts +0 -2
- package/dist/types/utils/time.d.ts +0 -12
- package/dist/types/utils/unicode.d.ts +0 -5
- package/dist/types/utils/uri.d.ts +0 -4
- package/dist/types/utils/what-is.d.ts +0 -4
- package/dist/types/validation/array.d.ts +0 -12
- package/dist/types/validation/combinators.d.ts +0 -10
- package/dist/types/validation/numeric.d.ts +0 -8
- package/dist/types/validation/object.d.ts +0 -13
- package/dist/types/validation/ref.d.ts +0 -11
- package/dist/types/validation/shared.d.ts +0 -26
- package/dist/types/validation/string.d.ts +0 -9
- package/dist/types/validation/type.d.ts +0 -6
- package/dist/types/z-schema-base.d.ts +0 -87
- package/dist/types/z-schema-options.d.ts +0 -35
- package/dist/types/z-schema-reader.d.ts +0 -4
- package/dist/types/z-schema-versions.d.ts +0 -1
- package/dist/types/z-schema.d.ts +0 -191
- package/dist/utils/array.js +0 -69
- package/dist/utils/base64.js +0 -29
- package/dist/utils/clone.js +0 -59
- package/dist/utils/constants.js +0 -19
- package/dist/utils/date.js +0 -21
- package/dist/utils/hostname.js +0 -146
- package/dist/utils/json.js +0 -70
- package/dist/utils/properties.js +0 -10
- package/dist/utils/schema-regex.js +0 -52
- package/dist/utils/symbols.js +0 -2
- package/dist/utils/time.js +0 -50
- package/dist/utils/unicode.js +0 -12
- package/dist/utils/uri.js +0 -15
- package/dist/utils/what-is.js +0 -32
- package/dist/validation/array.js +0 -127
- package/dist/validation/combinators.js +0 -106
- package/dist/validation/numeric.js +0 -97
- package/dist/validation/object.js +0 -237
- package/dist/validation/ref.js +0 -70
- package/dist/validation/shared.js +0 -136
- package/dist/validation/string.js +0 -170
- package/dist/validation/type.js +0 -55
- package/dist/z-schema-base.js +0 -286
- package/dist/z-schema-options.js +0 -99
- package/dist/z-schema-reader.js +0 -7
- package/dist/z-schema-versions.js +0 -110
- package/dist/z-schema.js +0 -287
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { deepClone } from "./utils/clone.mjs";
|
|
2
|
+
import { jsonSymbol, schemaSymbol } from "./utils/symbols.mjs";
|
|
3
|
+
import { defaultOptions } from "./z-schema-options.mjs";
|
|
4
|
+
import { SchemaCache, prepareRemoteSchema } from "./schema-cache.mjs";
|
|
5
|
+
import "./z-schema-versions.mjs";
|
|
6
|
+
import { getRegisteredFormats, registerFormat, unregisterFormat } from "./format-validators.mjs";
|
|
7
|
+
import { getSchemaReader, setSchemaReader } from "./z-schema-reader.mjs";
|
|
8
|
+
import { FACTORY_TOKEN, ZSchemaBase } from "./z-schema-base.mjs";
|
|
9
|
+
//#region src/z-schema.ts
|
|
10
|
+
var ZSchema = class ZSchema extends ZSchemaBase {
|
|
11
|
+
/** @internal Use ZSchema.create() instead. */
|
|
12
|
+
constructor(options, token) {
|
|
13
|
+
super(options, token);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Register a global format validator available to all instances.
|
|
17
|
+
* @param name - The format name (e.g. `'email'`, `'date'`).
|
|
18
|
+
* @param validatorFunction - A sync or async function `(value: unknown) => boolean | Promise<boolean>`.
|
|
19
|
+
*/
|
|
20
|
+
static registerFormat(name, validatorFunction) {
|
|
21
|
+
return registerFormat(name, validatorFunction);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Remove a globally registered format validator.
|
|
25
|
+
* @param name - The format name to unregister.
|
|
26
|
+
*/
|
|
27
|
+
static unregisterFormat(name) {
|
|
28
|
+
return unregisterFormat(name);
|
|
29
|
+
}
|
|
30
|
+
/** Returns the names of all globally registered format validators. */
|
|
31
|
+
static getRegisteredFormats() {
|
|
32
|
+
return getRegisteredFormats();
|
|
33
|
+
}
|
|
34
|
+
/** Returns a deep clone of the default options. */
|
|
35
|
+
static getDefaultOptions() {
|
|
36
|
+
return deepClone(defaultOptions);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Register a remote schema in the global cache so any instance can resolve `$ref` to it.
|
|
40
|
+
* @param uri - The URI the schema will be known by.
|
|
41
|
+
* @param schema - The schema object or JSON string.
|
|
42
|
+
* @param validationOptions - Optional options used for schema preparation.
|
|
43
|
+
*/
|
|
44
|
+
static setRemoteReference(uri, schema, validationOptions) {
|
|
45
|
+
const _schema = prepareRemoteSchema(schema, uri, validationOptions);
|
|
46
|
+
SchemaCache.cacheSchemaByUri(uri, _schema);
|
|
47
|
+
}
|
|
48
|
+
/** Returns the current global schema reader, or `undefined` if none is set. */
|
|
49
|
+
static getSchemaReader() {
|
|
50
|
+
return getSchemaReader();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Set a global schema reader function used to resolve remote `$ref` URIs.
|
|
54
|
+
* @param schemaReader - A function `(uri: string) => JsonSchema | undefined`, or `undefined` to clear.
|
|
55
|
+
*/
|
|
56
|
+
static setSchemaReader(schemaReader) {
|
|
57
|
+
return setSchemaReader(schemaReader);
|
|
58
|
+
}
|
|
59
|
+
static schemaSymbol = schemaSymbol;
|
|
60
|
+
static jsonSymbol = jsonSymbol;
|
|
61
|
+
static create(options = {}) {
|
|
62
|
+
const isAsync = options.async;
|
|
63
|
+
const isSafe = options.safe;
|
|
64
|
+
delete options.async;
|
|
65
|
+
delete options.safe;
|
|
66
|
+
if (isAsync && isSafe) return new ZSchemaAsyncSafe(options, FACTORY_TOKEN);
|
|
67
|
+
if (isAsync) return new ZSchemaAsync(options, FACTORY_TOKEN);
|
|
68
|
+
if (isSafe) return new ZSchemaSafe(options, FACTORY_TOKEN);
|
|
69
|
+
return new ZSchema(options, FACTORY_TOKEN);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Validate JSON data against a schema.
|
|
73
|
+
* @param json - The data to validate.
|
|
74
|
+
* @param schema - A JSON Schema object or a schema id string (previously registered via `validateSchema`).
|
|
75
|
+
* @param options - Per-call options (`schemaPath`, `includeErrors`, `excludeErrors`).
|
|
76
|
+
* @returns `true` if valid.
|
|
77
|
+
* @throws {@link ValidateError} if validation fails, with a `details` array of structured errors.
|
|
78
|
+
*/
|
|
79
|
+
validate(json, schema, options = {}) {
|
|
80
|
+
return this._validate(json, schema, options);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validate JSON data against a schema, returning a result object instead of throwing.
|
|
84
|
+
* @param json - The data to validate.
|
|
85
|
+
* @param schema - A JSON Schema object or a schema id string.
|
|
86
|
+
* @param options - Per-call options.
|
|
87
|
+
* @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
|
|
88
|
+
*/
|
|
89
|
+
validateSafe(json, schema, options) {
|
|
90
|
+
try {
|
|
91
|
+
this._validate(json, schema, options ?? {});
|
|
92
|
+
return { valid: true };
|
|
93
|
+
} catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
valid: false,
|
|
96
|
+
err
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Validate JSON data against a schema asynchronously (supports async format validators).
|
|
102
|
+
* @param json - The data to validate.
|
|
103
|
+
* @param schema - A JSON Schema object or a schema id string.
|
|
104
|
+
* @param options - Per-call options.
|
|
105
|
+
* @returns A promise that resolves to `true` if valid.
|
|
106
|
+
* @throws {@link ValidateError} if validation fails (the promise rejects).
|
|
107
|
+
*/
|
|
108
|
+
validateAsync(json, schema, options) {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
try {
|
|
111
|
+
this._validate(json, schema, options || {}, (err, valid) => err || valid !== true ? reject(err) : resolve(valid));
|
|
112
|
+
} catch (err) {
|
|
113
|
+
reject(err);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Validate JSON data against a schema asynchronously, returning a result object.
|
|
119
|
+
* The promise always resolves (never rejects).
|
|
120
|
+
* @param json - The data to validate.
|
|
121
|
+
* @param schema - A JSON Schema object or a schema id string.
|
|
122
|
+
* @param options - Per-call options.
|
|
123
|
+
* @returns A promise resolving to `{ valid: true }` or `{ valid: false, err: ValidateError }`.
|
|
124
|
+
*/
|
|
125
|
+
validateAsyncSafe(json, schema, options) {
|
|
126
|
+
return new Promise((resolve) => {
|
|
127
|
+
try {
|
|
128
|
+
this._validate(json, schema, options || {}, (err, valid) => {
|
|
129
|
+
resolve({
|
|
130
|
+
valid,
|
|
131
|
+
err
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
} catch (err) {
|
|
135
|
+
resolve({
|
|
136
|
+
valid: false,
|
|
137
|
+
err
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Validate one or more JSON Schemas, compiling and caching them for later use with `validate()`.
|
|
144
|
+
* @param schemaOrArr - A single schema or an array of schemas (for cross-referencing).
|
|
145
|
+
* @returns `true` if all schemas are valid.
|
|
146
|
+
* @throws {@link ValidateError} if any schema is invalid.
|
|
147
|
+
*/
|
|
148
|
+
validateSchema(schemaOrArr) {
|
|
149
|
+
return this._validateSchema(schemaOrArr);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Validate one or more JSON Schemas, returning a result object instead of throwing.
|
|
153
|
+
* @param schemaOrArr - A single schema or an array of schemas.
|
|
154
|
+
* @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
|
|
155
|
+
*/
|
|
156
|
+
validateSchemaSafe(schemaOrArr) {
|
|
157
|
+
try {
|
|
158
|
+
this._validateSchema(schemaOrArr);
|
|
159
|
+
return { valid: true };
|
|
160
|
+
} catch (err) {
|
|
161
|
+
return {
|
|
162
|
+
valid: false,
|
|
163
|
+
err
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Synchronous safe validator — `validate()` returns `{ valid, err? }` instead of throwing.
|
|
170
|
+
* Created via `ZSchema.create({ safe: true })`.
|
|
171
|
+
*/
|
|
172
|
+
var ZSchemaSafe = class extends ZSchemaBase {
|
|
173
|
+
/** @internal Use ZSchema.create() instead. */
|
|
174
|
+
constructor(options, token) {
|
|
175
|
+
super(options, token);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Validate JSON data against a schema.
|
|
179
|
+
* @param json - The data to validate.
|
|
180
|
+
* @param schema - A JSON Schema object or a schema id string.
|
|
181
|
+
* @param options - Per-call options.
|
|
182
|
+
* @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
|
|
183
|
+
*/
|
|
184
|
+
validate(json, schema, options = {}) {
|
|
185
|
+
try {
|
|
186
|
+
this._validate(json, schema, options);
|
|
187
|
+
return { valid: true };
|
|
188
|
+
} catch (err) {
|
|
189
|
+
return {
|
|
190
|
+
valid: false,
|
|
191
|
+
err
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Validate one or more JSON Schemas.
|
|
197
|
+
* @param schemaOrArr - A single schema or an array of schemas.
|
|
198
|
+
* @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
|
|
199
|
+
*/
|
|
200
|
+
validateSchema(schemaOrArr) {
|
|
201
|
+
try {
|
|
202
|
+
this._validateSchema(schemaOrArr);
|
|
203
|
+
return { valid: true };
|
|
204
|
+
} catch (err) {
|
|
205
|
+
return {
|
|
206
|
+
valid: false,
|
|
207
|
+
err
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Asynchronous throw validator — `validate()` returns `Promise<true>` or rejects.
|
|
214
|
+
* Created via `ZSchema.create({ async: true })`.
|
|
215
|
+
*/
|
|
216
|
+
var ZSchemaAsync = class extends ZSchemaBase {
|
|
217
|
+
/** @internal Use ZSchema.create() instead. */
|
|
218
|
+
constructor(options, token) {
|
|
219
|
+
super(options, token);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Validate JSON data against a schema asynchronously.
|
|
223
|
+
* @param json - The data to validate.
|
|
224
|
+
* @param schema - A JSON Schema object or a schema id string.
|
|
225
|
+
* @param options - Per-call options.
|
|
226
|
+
* @returns A promise that resolves to `true` if valid.
|
|
227
|
+
* @throws {@link ValidateError} if validation fails (the promise rejects).
|
|
228
|
+
*/
|
|
229
|
+
validate(json, schema, options = {}) {
|
|
230
|
+
return new Promise((resolve, reject) => {
|
|
231
|
+
try {
|
|
232
|
+
this._validate(json, schema, options, (err, valid) => err || valid !== true ? reject(err) : resolve(valid));
|
|
233
|
+
} catch (err) {
|
|
234
|
+
reject(err);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Validate one or more JSON Schemas (synchronous, throws on error).
|
|
240
|
+
* @param schemaOrArr - A single schema or an array of schemas.
|
|
241
|
+
* @returns `true` if all schemas are valid.
|
|
242
|
+
* @throws {@link ValidateError} if any schema is invalid.
|
|
243
|
+
*/
|
|
244
|
+
validateSchema(schemaOrArr) {
|
|
245
|
+
return this._validateSchema(schemaOrArr);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Asynchronous safe validator — `validate()` returns `Promise<{ valid, err? }>` (never rejects).
|
|
250
|
+
* Created via `ZSchema.create({ async: true, safe: true })`.
|
|
251
|
+
*/
|
|
252
|
+
var ZSchemaAsyncSafe = class extends ZSchemaBase {
|
|
253
|
+
/** @internal Use ZSchema.create() instead. */
|
|
254
|
+
constructor(options, token) {
|
|
255
|
+
super(options, token);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Validate JSON data against a schema asynchronously.
|
|
259
|
+
* The promise always resolves (never rejects).
|
|
260
|
+
* @param json - The data to validate.
|
|
261
|
+
* @param schema - A JSON Schema object or a schema id string.
|
|
262
|
+
* @param options - Per-call options.
|
|
263
|
+
* @returns A promise resolving to `{ valid: true }` or `{ valid: false, err: ValidateError }`.
|
|
264
|
+
*/
|
|
265
|
+
validate(json, schema, options = {}) {
|
|
266
|
+
return new Promise((resolve) => {
|
|
267
|
+
try {
|
|
268
|
+
this._validate(json, schema, options, (err, valid) => {
|
|
269
|
+
resolve({
|
|
270
|
+
valid,
|
|
271
|
+
err
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
} catch (err) {
|
|
275
|
+
resolve({
|
|
276
|
+
valid: false,
|
|
277
|
+
err
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Validate one or more JSON Schemas.
|
|
284
|
+
* @param schemaOrArr - A single schema or an array of schemas.
|
|
285
|
+
* @returns `{ valid: true }` on success, or `{ valid: false, err: ValidateError }` on failure.
|
|
286
|
+
*/
|
|
287
|
+
validateSchema(schemaOrArr) {
|
|
288
|
+
try {
|
|
289
|
+
this._validateSchema(schemaOrArr);
|
|
290
|
+
return { valid: true };
|
|
291
|
+
} catch (err) {
|
|
292
|
+
return {
|
|
293
|
+
valid: false,
|
|
294
|
+
err
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
//#endregion
|
|
300
|
+
export { ZSchema };
|
package/package.json
CHANGED
|
@@ -1,53 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "z-schema",
|
|
3
|
-
"version": "12.0
|
|
4
|
-
"engines": {
|
|
5
|
-
"node": ">=22.0.0"
|
|
6
|
-
},
|
|
7
|
-
"sideEffects": [
|
|
8
|
-
"./dist/z-schema-versions.js"
|
|
9
|
-
],
|
|
3
|
+
"version": "12.1.0",
|
|
10
4
|
"description": "Fast, lightweight JSON Schema validator for Node.js and browsers — full support for draft-04, draft-06, draft-07, draft-2019-09, and draft-2020-12 (latest)",
|
|
11
|
-
"homepage": "https://github.com/zaggino/z-schema",
|
|
12
|
-
"authors": [
|
|
13
|
-
"Martin Zagora <zaggino@gmail.com>"
|
|
14
|
-
],
|
|
15
|
-
"license": "MIT",
|
|
16
5
|
"keywords": [
|
|
17
|
-
"json-schema",
|
|
18
|
-
"json",
|
|
19
|
-
"schema",
|
|
20
|
-
"validator",
|
|
21
|
-
"validation",
|
|
22
|
-
"json-schema-validator",
|
|
23
6
|
"draft-04",
|
|
24
7
|
"draft-06",
|
|
25
8
|
"draft-07",
|
|
26
9
|
"draft-2019-09",
|
|
27
10
|
"draft-2020-12",
|
|
11
|
+
"esm",
|
|
12
|
+
"json",
|
|
13
|
+
"json-schema",
|
|
14
|
+
"json-schema-validator",
|
|
28
15
|
"jsonschema",
|
|
16
|
+
"schema",
|
|
29
17
|
"typescript",
|
|
30
|
-
"
|
|
18
|
+
"validation",
|
|
19
|
+
"validator"
|
|
31
20
|
],
|
|
32
|
-
"
|
|
33
|
-
"type": "git",
|
|
34
|
-
"url": "git+https://github.com/zaggino/z-schema.git"
|
|
35
|
-
},
|
|
21
|
+
"homepage": "https://github.com/zaggino/z-schema",
|
|
36
22
|
"bugs": {
|
|
37
23
|
"url": "https://github.com/zaggino/z-schema/issues"
|
|
38
24
|
},
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"default": "./dist/index.js"
|
|
44
|
-
},
|
|
45
|
-
"require": {
|
|
46
|
-
"types": "./cjs/index.d.ts",
|
|
47
|
-
"default": "./cjs/index.js"
|
|
48
|
-
},
|
|
49
|
-
"default": "./dist/index.js"
|
|
50
|
-
}
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/zaggino/z-schema.git"
|
|
51
29
|
},
|
|
52
30
|
"bin": {
|
|
53
31
|
"z-schema": "bin/z-schema"
|
|
@@ -61,20 +39,34 @@
|
|
|
61
39
|
"LICENSE",
|
|
62
40
|
"README.md"
|
|
63
41
|
],
|
|
42
|
+
"sideEffects": [
|
|
43
|
+
"./dist/z-schema-versions.mjs"
|
|
44
|
+
],
|
|
45
|
+
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"import": {
|
|
48
|
+
"types": "./dist/index.d.mts",
|
|
49
|
+
"default": "./dist/index.mjs"
|
|
50
|
+
},
|
|
51
|
+
"require": {
|
|
52
|
+
"types": "./cjs/index.d.ts",
|
|
53
|
+
"default": "./cjs/index.js"
|
|
54
|
+
},
|
|
55
|
+
"default": "./dist/index.mjs"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
64
58
|
"scripts": {
|
|
65
59
|
"prepare": "husky",
|
|
66
60
|
"pre-commit": "npx lint-staged",
|
|
67
61
|
"pre-push": "npm run build && npm run build:tests",
|
|
68
|
-
"format": "
|
|
69
|
-
"format:check": "
|
|
70
|
-
"lint": "
|
|
71
|
-
"lint:check": "
|
|
62
|
+
"format": "oxfmt",
|
|
63
|
+
"format:check": "oxfmt --check",
|
|
64
|
+
"lint": "oxlint --fix",
|
|
65
|
+
"lint:check": "oxlint",
|
|
72
66
|
"clean": "rimraf ./cjs && rimraf ./dist && rimraf ./umd && rimraf --glob \"./src/schemas/*.json\"",
|
|
73
|
-
"build": "npm run copy:schemas &&
|
|
74
|
-
"build:
|
|
75
|
-
"build:watch": "rollup -c -w",
|
|
67
|
+
"build": "npm run copy:schemas && tsdown",
|
|
68
|
+
"build:watch": "npm run copy:schemas && tsdown --watch",
|
|
76
69
|
"build:tests": "tsc --noEmit --project test/tsconfig.json",
|
|
77
|
-
"copy:module-json": "node -e \"fs.copyFileSync('./src/package.json', './dist/package.json')\"",
|
|
78
70
|
"copy:schemas": "node ./scripts/copy-schemas.mts",
|
|
79
71
|
"coverage:artifacts": "node ./scripts/generate-test-coverage-report.mts",
|
|
80
72
|
"coverage:update-badge": "node ./scripts/update-readme-coverage-badge.mts",
|
|
@@ -87,20 +79,10 @@
|
|
|
87
79
|
},
|
|
88
80
|
"dependencies": {
|
|
89
81
|
"punycode": "^2.3.1",
|
|
82
|
+
"safe-regex2": "^5.1.0",
|
|
90
83
|
"validator": "^13.15.26"
|
|
91
84
|
},
|
|
92
|
-
"optionalDependencies": {
|
|
93
|
-
"commander": "^14.0.3"
|
|
94
|
-
},
|
|
95
85
|
"devDependencies": {
|
|
96
|
-
"@eslint/js": "^9.39.2",
|
|
97
|
-
"@eslint/json": "^1.0.0",
|
|
98
|
-
"@eslint/markdown": "^7.5.1",
|
|
99
|
-
"@rollup/plugin-commonjs": "^29.0.0",
|
|
100
|
-
"@rollup/plugin-json": "^6.1.0",
|
|
101
|
-
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
102
|
-
"@rollup/plugin-terser": "^1.0.0",
|
|
103
|
-
"@rollup/plugin-typescript": "^12.3.0",
|
|
104
86
|
"@types/lodash.isequal": "^4.5.8",
|
|
105
87
|
"@types/node": "^25.2.0",
|
|
106
88
|
"@types/punycode": "^2.1.4",
|
|
@@ -108,20 +90,23 @@
|
|
|
108
90
|
"@vitest/browser-playwright": "^4.0.18",
|
|
109
91
|
"@vitest/coverage-istanbul": "^4.0.18",
|
|
110
92
|
"@vitest/coverage-v8": "^4.0.18",
|
|
111
|
-
"@vitest/eslint-plugin": "^1.6.6",
|
|
112
|
-
"eslint": "^9.39.2",
|
|
113
|
-
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
114
|
-
"globals": "^17.3.0",
|
|
115
93
|
"husky": "^9.1.7",
|
|
116
94
|
"lint-staged": "^16.2.7",
|
|
117
95
|
"lodash.isequal": "^4.5.0",
|
|
118
|
-
"
|
|
96
|
+
"oxfmt": "^0.41.0",
|
|
97
|
+
"oxlint": "^1.56.0",
|
|
119
98
|
"rimraf": "^6.1.2",
|
|
120
|
-
"
|
|
121
|
-
"rollup-plugin-dts": "^6.3.0",
|
|
122
|
-
"tslib": "^2.8.1",
|
|
99
|
+
"tsdown": "^0.21.4",
|
|
123
100
|
"typescript": "^5.9.3",
|
|
124
|
-
"typescript-eslint": "^8.54.0",
|
|
125
101
|
"vitest": "^4.0.18"
|
|
126
|
-
}
|
|
102
|
+
},
|
|
103
|
+
"optionalDependencies": {
|
|
104
|
+
"commander": "^14.0.3"
|
|
105
|
+
},
|
|
106
|
+
"engines": {
|
|
107
|
+
"node": ">=22.0.0"
|
|
108
|
+
},
|
|
109
|
+
"authors": [
|
|
110
|
+
"Martin Zagora <zaggino@gmail.com>"
|
|
111
|
+
]
|
|
127
112
|
}
|
package/src/index.ts
CHANGED
|
@@ -26,8 +26,8 @@ export type {
|
|
|
26
26
|
} from './json-schema-versions.js';
|
|
27
27
|
export type { Report, SchemaErrorDetail } from './report.js';
|
|
28
28
|
export type { ZSchema, ZSchemaAsync, ZSchemaAsyncSafe, ZSchemaSafe } from './z-schema.js';
|
|
29
|
-
export { ValidateOptions, ValidateResponse } from './z-schema-base.js';
|
|
30
|
-
export { ZSchemaOptions } from './z-schema-options.js';
|
|
31
|
-
export { SchemaReader } from './z-schema-reader.js';
|
|
29
|
+
export type { ValidateOptions, ValidateResponse } from './z-schema-base.js';
|
|
30
|
+
export type { ZSchemaOptions } from './z-schema-options.js';
|
|
31
|
+
export type { SchemaReader } from './z-schema-reader.js';
|
|
32
32
|
|
|
33
33
|
export default ZSchema;
|
package/src/schema-compiler.ts
CHANGED
|
@@ -7,14 +7,20 @@ import { DEFAULT_MAX_RECURSION_DEPTH } from './utils/constants.js';
|
|
|
7
7
|
import { getRemotePath, isAbsoluteUri } from './utils/uri.js';
|
|
8
8
|
import { getSchemaReader } from './z-schema-reader.js';
|
|
9
9
|
|
|
10
|
+
const UNSAFE_TARGETS = [
|
|
11
|
+
Object.prototype as unknown as Record<string, unknown>,
|
|
12
|
+
Function.prototype as unknown as Record<string, unknown>,
|
|
13
|
+
Array.prototype as unknown as Record<string, unknown>,
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
/** Returns true if `obj` is a built-in prototype that must not be mutated. */
|
|
17
|
+
function isUnsafeTarget(obj: Record<string, unknown>): boolean {
|
|
18
|
+
return UNSAFE_TARGETS.includes(obj);
|
|
19
|
+
}
|
|
20
|
+
|
|
10
21
|
/** Safely assign a property on `obj`, refusing prototype-polluting keys. */
|
|
11
22
|
function safeSetProperty(obj: Record<string, unknown>, key: string, value: unknown): void {
|
|
12
|
-
|
|
13
|
-
Object.prototype as unknown as Record<string, unknown>,
|
|
14
|
-
Function.prototype as unknown as Record<string, unknown>,
|
|
15
|
-
Array.prototype as unknown as Record<string, unknown>,
|
|
16
|
-
];
|
|
17
|
-
if (unsafeTargets.includes(obj)) {
|
|
23
|
+
if (isUnsafeTarget(obj)) {
|
|
18
24
|
return;
|
|
19
25
|
}
|
|
20
26
|
/** Reject property names that could pollute Object.prototype (CWE-1321). */
|
|
@@ -23,6 +29,16 @@ function safeSetProperty(obj: Record<string, unknown>, key: string, value: unkno
|
|
|
23
29
|
}
|
|
24
30
|
}
|
|
25
31
|
|
|
32
|
+
/** Safely delete a property from `obj`, refusing to mutate built-in prototypes (CWE-1321). */
|
|
33
|
+
function safeDeleteProperty(obj: Record<string, unknown>, key: string): void {
|
|
34
|
+
if (isUnsafeTarget(obj)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {
|
|
38
|
+
delete obj[key];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
26
42
|
interface Id {
|
|
27
43
|
id: string;
|
|
28
44
|
type: 'absolute' | 'relative' | 'root';
|
|
@@ -348,7 +364,7 @@ export class SchemaCompiler {
|
|
|
348
364
|
// delete all __$missingReferences from previous compilation attempts
|
|
349
365
|
const isValidExceptReferences = report.isValid();
|
|
350
366
|
if (canMutateSchemaObject) {
|
|
351
|
-
|
|
367
|
+
safeDeleteProperty(schema as unknown as Record<string, unknown>, '__$missingReferences');
|
|
352
368
|
}
|
|
353
369
|
|
|
354
370
|
// collect all references that need to be resolved - $ref and $schema
|
|
@@ -412,8 +428,12 @@ export class SchemaCompiler {
|
|
|
412
428
|
report.addError('UNRESOLVABLE_REFERENCE', [refObj.ref]);
|
|
413
429
|
report.path = report.path.slice(0, -refObj.path.length);
|
|
414
430
|
|
|
415
|
-
//
|
|
416
|
-
if (
|
|
431
|
+
// publish unresolved references out
|
|
432
|
+
if (
|
|
433
|
+
isValidExceptReferences &&
|
|
434
|
+
canMutateSchemaObject &&
|
|
435
|
+
!isUnsafeTarget(schema as unknown as Record<string, unknown>)
|
|
436
|
+
) {
|
|
417
437
|
schema.__$missingReferences = schema.__$missingReferences || [];
|
|
418
438
|
schema.__$missingReferences.push(refObj);
|
|
419
439
|
}
|
|
@@ -471,7 +491,7 @@ export class SchemaCompiler {
|
|
|
471
491
|
}
|
|
472
492
|
}
|
|
473
493
|
if (sch.__$missingReferences.length === 0) {
|
|
474
|
-
|
|
494
|
+
safeDeleteProperty(sch as unknown as Record<string, unknown>, '__$missingReferences');
|
|
475
495
|
}
|
|
476
496
|
}
|
|
477
497
|
}
|
package/src/schema-validator.ts
CHANGED
|
@@ -689,7 +689,7 @@ const SchemaValidators = {
|
|
|
689
689
|
report.addError('KEYWORD_TYPE_EXPECTED', ['description', 'string'], undefined, schema, 'description');
|
|
690
690
|
}
|
|
691
691
|
},
|
|
692
|
-
default: function (this: SchemaValidator /* report, schema */
|
|
692
|
+
default: function (this: SchemaValidator) /* report, schema */ {
|
|
693
693
|
// http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.2
|
|
694
694
|
// There are no restrictions placed on the value of this keyword.
|
|
695
695
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Shared regex compilation helper for JSON Schema patterns
|
|
2
2
|
// Returns { ok: true, value: RegExp } or { ok: false, error: { pattern, message } }
|
|
3
3
|
|
|
4
|
+
import isSafeRegex from 'safe-regex2';
|
|
5
|
+
|
|
4
6
|
import { MAX_SCHEMA_REGEX_LENGTH } from './constants.js';
|
|
5
7
|
|
|
6
8
|
export function compileSchemaRegex(
|
|
@@ -16,6 +18,17 @@ export function compileSchemaRegex(
|
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
|
|
21
|
+
// Reject patterns vulnerable to catastrophic backtracking (ReDoS) before compiling
|
|
22
|
+
if (!isSafeRegex(pattern)) {
|
|
23
|
+
return {
|
|
24
|
+
ok: false,
|
|
25
|
+
error: {
|
|
26
|
+
pattern,
|
|
27
|
+
message: 'Pattern rejected as potentially unsafe (ReDoS)',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
19
32
|
const unicodePropertyEscape = /\\[pP]{/;
|
|
20
33
|
const nonBmpCharacter = /[\u{10000}-\u{10FFFF}]/u;
|
|
21
34
|
const surrogatePairEscape = /\\uD[89AB][0-9A-Fa-f]{2}\\uD[CDEF][0-9A-Fa-f]{2}/;
|
|
@@ -25,7 +38,6 @@ export function compileSchemaRegex(
|
|
|
25
38
|
if (needsUnicode) {
|
|
26
39
|
// Try compiling with 'u' flag only
|
|
27
40
|
try {
|
|
28
|
-
// lgtm[js/regex-injection] JSON Schema `pattern` is intentionally regex syntax and constrained by MAX_SCHEMA_REGEX_LENGTH.
|
|
29
41
|
const re = new RegExp(pattern, 'u');
|
|
30
42
|
return { ok: true, value: re };
|
|
31
43
|
} catch (e: any) {
|
|
@@ -39,7 +51,6 @@ export function compileSchemaRegex(
|
|
|
39
51
|
}
|
|
40
52
|
} else {
|
|
41
53
|
try {
|
|
42
|
-
// lgtm[js/regex-injection] JSON Schema `pattern` is intentionally regex syntax and constrained by MAX_SCHEMA_REGEX_LENGTH.
|
|
43
54
|
const re = new RegExp(pattern);
|
|
44
55
|
return { ok: true, value: re };
|
|
45
56
|
} catch (e: any) {
|
package/src/z-schema-base.ts
CHANGED
|
@@ -6,8 +6,8 @@ import type { ZSchemaOptions } from './z-schema-options.js';
|
|
|
6
6
|
|
|
7
7
|
import { type Errors, getValidateError } from './errors.js';
|
|
8
8
|
import { getSupportedFormats } from './format-validators.js';
|
|
9
|
-
import { isInternalKey } from './json-schema.js';
|
|
10
9
|
import { VERSION_SCHEMA_URL_MAPPING } from './json-schema-versions.js';
|
|
10
|
+
import { isInternalKey } from './json-schema.js';
|
|
11
11
|
import { validate as validateJson } from './json-validation.js';
|
|
12
12
|
import { Report } from './report.js';
|
|
13
13
|
import { prepareRemoteSchema, SchemaCache } from './schema-cache.js';
|
package/src/z-schema-versions.ts
CHANGED
|
@@ -11,8 +11,6 @@ import type {
|
|
|
11
11
|
import type { ZSchemaOptions } from './z-schema-options.js';
|
|
12
12
|
|
|
13
13
|
import { SchemaCache } from './schema-cache.js';
|
|
14
|
-
import { normalizeOptions } from './z-schema-options.js';
|
|
15
|
-
|
|
16
14
|
// draft-04
|
|
17
15
|
import _Draft4Schema from './schemas/draft-04-schema.json' with { type: 'json' };
|
|
18
16
|
// draft-06
|
|
@@ -37,6 +35,7 @@ import _Draft202012MetaMetaData from './schemas/draft-2020-12-meta-meta-data.jso
|
|
|
37
35
|
import _Draft202012MetaUnevaluated from './schemas/draft-2020-12-meta-unevaluated.json' with { type: 'json' };
|
|
38
36
|
import _Draft202012MetaValidation from './schemas/draft-2020-12-meta-validation.json' with { type: 'json' };
|
|
39
37
|
import _Draft202012Schema from './schemas/draft-2020-12-schema.json' with { type: 'json' };
|
|
38
|
+
import { normalizeOptions } from './z-schema-options.js';
|
|
40
39
|
|
|
41
40
|
// draft-04
|
|
42
41
|
const Draft4Schema: JsonSchemaDraft4 = _Draft4Schema;
|
package/src/z-schema.ts
CHANGED
|
@@ -6,7 +6,6 @@ import type { ZSchemaOptions } from './z-schema-options.js';
|
|
|
6
6
|
import type { SchemaReader } from './z-schema-reader.js';
|
|
7
7
|
|
|
8
8
|
import './z-schema-versions.js';
|
|
9
|
-
|
|
10
9
|
import { getRegisteredFormats, registerFormat, unregisterFormat } from './format-validators.js';
|
|
11
10
|
import { prepareRemoteSchema, SchemaCache } from './schema-cache.js';
|
|
12
11
|
import { deepClone } from './utils/clone.js';
|