@sinclair/typebox 0.25.23 → 0.26.0-dev
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/compiler/compiler.d.ts +9 -4
- package/compiler/compiler.js +160 -119
- package/errors/errors.d.ts +56 -46
- package/errors/errors.js +234 -149
- package/package.json +1 -6
- package/readme.md +395 -396
- package/system/system.d.ts +9 -6
- package/system/system.js +17 -17
- package/typebox.d.ts +386 -162
- package/typebox.js +1710 -229
- package/value/cast.d.ts +2 -2
- package/value/cast.js +120 -192
- package/value/check.d.ts +1 -1
- package/value/check.js +162 -107
- package/value/convert.d.ts +13 -0
- package/value/convert.js +345 -0
- package/value/create.d.ts +6 -2
- package/value/create.js +149 -107
- package/{hash → value}/hash.js +39 -14
- package/value/index.d.ts +1 -0
- package/value/index.js +3 -1
- package/value/value.d.ts +2 -8
- package/value/value.js +20 -14
- package/conditional/conditional.d.ts +0 -17
- package/conditional/conditional.js +0 -91
- package/conditional/index.d.ts +0 -2
- package/conditional/index.js +0 -45
- package/conditional/structural.d.ts +0 -11
- package/conditional/structural.js +0 -685
- package/custom/custom.d.ts +0 -12
- package/custom/custom.js +0 -55
- package/custom/index.d.ts +0 -1
- package/custom/index.js +0 -44
- package/format/format.d.ts +0 -12
- package/format/format.js +0 -55
- package/format/index.d.ts +0 -1
- package/format/index.js +0 -44
- package/guard/guard.d.ts +0 -60
- package/guard/guard.js +0 -440
- package/guard/index.d.ts +0 -1
- package/guard/index.js +0 -44
- package/hash/index.d.ts +0 -1
- package/hash/index.js +0 -44
- /package/{hash → value}/hash.d.ts +0 -0
package/compiler/compiler.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { ValueError } from '../errors/index';
|
|
2
1
|
import * as Types from '../typebox';
|
|
2
|
+
import { ValueError } from '../errors/index';
|
|
3
3
|
export type CheckFunction = (value: unknown) => boolean;
|
|
4
4
|
export declare class TypeCheck<T extends Types.TSchema> {
|
|
5
5
|
private readonly schema;
|
|
6
|
-
private readonly references;
|
|
7
6
|
private readonly checkFunc;
|
|
8
7
|
private readonly code;
|
|
9
|
-
constructor(schema: T,
|
|
8
|
+
constructor(schema: T, checkFunc: CheckFunction, code: string);
|
|
10
9
|
/** Returns the generated validation code used to validate this type. */
|
|
11
10
|
Code(): string;
|
|
12
11
|
/** Returns an iterator for each error in this value. */
|
|
@@ -21,8 +20,14 @@ export declare class TypeCompilerUnknownTypeError extends Error {
|
|
|
21
20
|
readonly schema: Types.TSchema;
|
|
22
21
|
constructor(schema: Types.TSchema);
|
|
23
22
|
}
|
|
23
|
+
export declare class TypeCompilerPreflightCheckError extends Error {
|
|
24
|
+
readonly schema: Types.TSchema;
|
|
25
|
+
constructor(schema: Types.TSchema);
|
|
26
|
+
}
|
|
24
27
|
/** Compiles Types for Runtime Type Checking */
|
|
25
28
|
export declare namespace TypeCompiler {
|
|
29
|
+
/** Returns the generated validation code used to validate this type. */
|
|
30
|
+
function Code<T extends Types.TSchema>(schema: T): string;
|
|
26
31
|
/** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
|
|
27
|
-
function Compile<T extends Types.TSchema>(schema: T
|
|
32
|
+
function Compile<T extends Types.TSchema>(schema: T): TypeCheck<T>;
|
|
28
33
|
}
|
package/compiler/compiler.js
CHANGED
|
@@ -27,21 +27,17 @@ THE SOFTWARE.
|
|
|
27
27
|
|
|
28
28
|
---------------------------------------------------------------------------*/
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.TypeCompiler = exports.TypeCompilerUnknownTypeError = exports.MemberExpression = exports.TypeCheck = void 0;
|
|
30
|
+
exports.TypeCompiler = exports.TypeCompilerPreflightCheckError = exports.TypeCompilerUnknownTypeError = exports.MemberExpression = exports.TypeCheck = void 0;
|
|
31
|
+
const Types = require("../typebox");
|
|
31
32
|
const index_1 = require("../errors/index");
|
|
32
33
|
const index_2 = require("../system/index");
|
|
33
|
-
const
|
|
34
|
-
const index_4 = require("../format/index");
|
|
35
|
-
const index_5 = require("../custom/index");
|
|
36
|
-
const index_6 = require("../hash/index");
|
|
37
|
-
const Types = require("../typebox");
|
|
34
|
+
const hash_1 = require("../value/hash");
|
|
38
35
|
// -------------------------------------------------------------------
|
|
39
36
|
// TypeCheck
|
|
40
37
|
// -------------------------------------------------------------------
|
|
41
38
|
class TypeCheck {
|
|
42
|
-
constructor(schema,
|
|
39
|
+
constructor(schema, checkFunc, code) {
|
|
43
40
|
this.schema = schema;
|
|
44
|
-
this.references = references;
|
|
45
41
|
this.checkFunc = checkFunc;
|
|
46
42
|
this.code = code;
|
|
47
43
|
}
|
|
@@ -51,7 +47,7 @@ class TypeCheck {
|
|
|
51
47
|
}
|
|
52
48
|
/** Returns an iterator for each error in this value. */
|
|
53
49
|
Errors(value) {
|
|
54
|
-
return index_1.ValueErrors.Errors(this.schema,
|
|
50
|
+
return index_1.ValueErrors.Errors(this.schema, value);
|
|
55
51
|
}
|
|
56
52
|
/** Returns true if the value matches the compiled type. */
|
|
57
53
|
Check(value) {
|
|
@@ -138,217 +134,260 @@ class TypeCompilerUnknownTypeError extends Error {
|
|
|
138
134
|
}
|
|
139
135
|
}
|
|
140
136
|
exports.TypeCompilerUnknownTypeError = TypeCompilerUnknownTypeError;
|
|
137
|
+
class TypeCompilerPreflightCheckError extends Error {
|
|
138
|
+
constructor(schema) {
|
|
139
|
+
super('TypeCompiler: Preflight validation check failed for given schema');
|
|
140
|
+
this.schema = schema;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.TypeCompilerPreflightCheckError = TypeCompilerPreflightCheckError;
|
|
141
144
|
/** Compiles Types for Runtime Type Checking */
|
|
142
145
|
var TypeCompiler;
|
|
143
146
|
(function (TypeCompiler) {
|
|
144
147
|
// -------------------------------------------------------------------
|
|
145
148
|
// Guards
|
|
146
149
|
// -------------------------------------------------------------------
|
|
150
|
+
function IsBigInt(value) {
|
|
151
|
+
return typeof value === 'bigint';
|
|
152
|
+
}
|
|
147
153
|
function IsNumber(value) {
|
|
148
|
-
return typeof value === 'number' &&
|
|
154
|
+
return typeof value === 'number' && globalThis.Number.isFinite(value);
|
|
149
155
|
}
|
|
150
156
|
// -------------------------------------------------------------------
|
|
151
157
|
// Types
|
|
152
158
|
// -------------------------------------------------------------------
|
|
153
159
|
function* Any(schema, value) {
|
|
154
|
-
yield '
|
|
160
|
+
yield 'true';
|
|
155
161
|
}
|
|
156
162
|
function* Array(schema, value) {
|
|
157
163
|
const expression = CreateExpression(schema.items, 'value');
|
|
158
|
-
yield `
|
|
164
|
+
yield `Array.isArray(${value}) && ${value}.every(value => ${expression})`;
|
|
159
165
|
if (IsNumber(schema.minItems))
|
|
160
|
-
yield
|
|
166
|
+
yield `${value}.length >= ${schema.minItems}`;
|
|
161
167
|
if (IsNumber(schema.maxItems))
|
|
162
|
-
yield
|
|
168
|
+
yield `${value}.length <= ${schema.maxItems}`;
|
|
163
169
|
if (schema.uniqueItems === true)
|
|
164
170
|
yield `((function() { const set = new Set(); for(const element of ${value}) { const hashed = hash(element); if(set.has(hashed)) { return false } else { set.add(hashed) } } return true })())`;
|
|
165
171
|
}
|
|
172
|
+
function* BigInt(schema, value) {
|
|
173
|
+
yield `(typeof ${value} === 'bigint')`;
|
|
174
|
+
if (IsBigInt(schema.multipleOf))
|
|
175
|
+
yield `(${value} % BigInt(${schema.multipleOf})) === 0`;
|
|
176
|
+
if (IsBigInt(schema.exclusiveMinimum))
|
|
177
|
+
yield `${value} > BigInt(${schema.exclusiveMinimum})`;
|
|
178
|
+
if (IsBigInt(schema.exclusiveMaximum))
|
|
179
|
+
yield `${value} < BigInt(${schema.exclusiveMaximum})`;
|
|
180
|
+
if (IsBigInt(schema.minimum))
|
|
181
|
+
yield `${value} >= BigInt(${schema.minimum})`;
|
|
182
|
+
if (IsBigInt(schema.maximum))
|
|
183
|
+
yield `${value} <= BigInt(${schema.maximum})`;
|
|
184
|
+
}
|
|
166
185
|
function* Boolean(schema, value) {
|
|
167
|
-
yield `
|
|
186
|
+
yield `typeof ${value} === 'boolean'`;
|
|
168
187
|
}
|
|
169
188
|
function* Constructor(schema, value) {
|
|
170
189
|
yield* Visit(schema.returns, `${value}.prototype`);
|
|
171
190
|
}
|
|
172
191
|
function* Date(schema, value) {
|
|
173
|
-
yield `(${value} instanceof Date) &&
|
|
192
|
+
yield `(${value} instanceof Date) && Number.isFinite(${value}.getTime())`;
|
|
174
193
|
if (IsNumber(schema.exclusiveMinimumTimestamp))
|
|
175
|
-
yield
|
|
194
|
+
yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`;
|
|
176
195
|
if (IsNumber(schema.exclusiveMaximumTimestamp))
|
|
177
|
-
yield
|
|
196
|
+
yield `${value}.getTime() < ${schema.exclusiveMaximumTimestamp}`;
|
|
178
197
|
if (IsNumber(schema.minimumTimestamp))
|
|
179
|
-
yield
|
|
198
|
+
yield `${value}.getTime() >= ${schema.minimumTimestamp}`;
|
|
180
199
|
if (IsNumber(schema.maximumTimestamp))
|
|
181
|
-
yield
|
|
200
|
+
yield `${value}.getTime() <= ${schema.maximumTimestamp}`;
|
|
182
201
|
}
|
|
183
202
|
function* Function(schema, value) {
|
|
184
|
-
yield `
|
|
203
|
+
yield `typeof ${value} === 'function'`;
|
|
185
204
|
}
|
|
186
205
|
function* Integer(schema, value) {
|
|
187
206
|
yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`;
|
|
188
207
|
if (IsNumber(schema.multipleOf))
|
|
189
|
-
yield `(${value} % ${schema.multipleOf} === 0
|
|
208
|
+
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
190
209
|
if (IsNumber(schema.exclusiveMinimum))
|
|
191
|
-
yield
|
|
210
|
+
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
192
211
|
if (IsNumber(schema.exclusiveMaximum))
|
|
193
|
-
yield
|
|
212
|
+
yield `${value} < ${schema.exclusiveMaximum}`;
|
|
194
213
|
if (IsNumber(schema.minimum))
|
|
195
|
-
yield
|
|
214
|
+
yield `${value} >= ${schema.minimum}`;
|
|
196
215
|
if (IsNumber(schema.maximum))
|
|
197
|
-
yield
|
|
216
|
+
yield `${value} <= ${schema.maximum}`;
|
|
217
|
+
}
|
|
218
|
+
function* Intersect(schema, value) {
|
|
219
|
+
if (schema.unevaluatedProperties === undefined) {
|
|
220
|
+
const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
|
|
221
|
+
yield `${expressions.join(' && ')}`;
|
|
222
|
+
}
|
|
223
|
+
else if (schema.unevaluatedProperties === false) {
|
|
224
|
+
// prettier-ignore
|
|
225
|
+
const schemaKeys = Types.KeyResolver.Resolve(schema).map((key) => `'${key}'`).join(', ');
|
|
226
|
+
const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
|
|
227
|
+
const expression1 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key))`;
|
|
228
|
+
yield `${expressions.join(' && ')} && ${expression1}`;
|
|
229
|
+
}
|
|
230
|
+
else if (typeof schema.unevaluatedProperties === 'object') {
|
|
231
|
+
// prettier-ignore
|
|
232
|
+
const schemaKeys = Types.KeyResolver.Resolve(schema).map((key) => `'${key}'`).join(', ');
|
|
233
|
+
const expressions = schema.allOf.map((schema) => CreateExpression(schema, value));
|
|
234
|
+
const expression1 = CreateExpression(schema.unevaluatedProperties, 'value[key]');
|
|
235
|
+
const expression2 = `Object.getOwnPropertyNames(${value}).every(key => [${schemaKeys}].includes(key) || ${expression1})`;
|
|
236
|
+
yield `${expressions.join(' && ')} && ${expression2}`;
|
|
237
|
+
}
|
|
198
238
|
}
|
|
199
239
|
function* Literal(schema, value) {
|
|
200
240
|
if (typeof schema.const === 'number' || typeof schema.const === 'boolean') {
|
|
201
|
-
yield
|
|
241
|
+
yield `${value} === ${schema.const}`;
|
|
202
242
|
}
|
|
203
243
|
else {
|
|
204
|
-
yield
|
|
244
|
+
yield `${value} === '${schema.const}'`;
|
|
205
245
|
}
|
|
206
246
|
}
|
|
207
247
|
function* Never(schema, value) {
|
|
208
|
-
yield `
|
|
248
|
+
yield `false`;
|
|
249
|
+
}
|
|
250
|
+
function* Not(schema, value) {
|
|
251
|
+
const left = CreateExpression(schema.allOf[0].not, value);
|
|
252
|
+
const right = CreateExpression(schema.allOf[1], value);
|
|
253
|
+
yield `!${left} && ${right}`;
|
|
209
254
|
}
|
|
210
255
|
function* Null(schema, value) {
|
|
211
|
-
yield
|
|
256
|
+
yield `${value} === null`;
|
|
212
257
|
}
|
|
213
258
|
function* Number(schema, value) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
else {
|
|
218
|
-
yield `(typeof ${value} === 'number' && !isNaN(${value}))`;
|
|
219
|
-
}
|
|
259
|
+
yield `typeof ${value} === 'number'`;
|
|
260
|
+
if (!index_2.TypeSystem.AllowNaN)
|
|
261
|
+
yield `Number.isFinite(${value})`;
|
|
220
262
|
if (IsNumber(schema.multipleOf))
|
|
221
|
-
yield `(${value} % ${schema.multipleOf} === 0
|
|
263
|
+
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
222
264
|
if (IsNumber(schema.exclusiveMinimum))
|
|
223
|
-
yield
|
|
265
|
+
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
224
266
|
if (IsNumber(schema.exclusiveMaximum))
|
|
225
|
-
yield
|
|
267
|
+
yield `${value} < ${schema.exclusiveMaximum}`;
|
|
226
268
|
if (IsNumber(schema.minimum))
|
|
227
|
-
yield
|
|
269
|
+
yield `${value} >= ${schema.minimum}`;
|
|
228
270
|
if (IsNumber(schema.maximum))
|
|
229
|
-
yield
|
|
271
|
+
yield `${value} <= ${schema.maximum}`;
|
|
230
272
|
}
|
|
231
273
|
function* Object(schema, value) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
else {
|
|
236
|
-
yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
|
|
237
|
-
}
|
|
274
|
+
yield `(typeof ${value} === 'object' && ${value} !== null)`;
|
|
275
|
+
if (!index_2.TypeSystem.AllowArrayObjects)
|
|
276
|
+
yield `!Array.isArray(${value})`;
|
|
238
277
|
if (IsNumber(schema.minProperties))
|
|
239
|
-
yield `
|
|
278
|
+
yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}`;
|
|
240
279
|
if (IsNumber(schema.maxProperties))
|
|
241
|
-
yield `
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
280
|
+
yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}`;
|
|
281
|
+
const schemaKeys = globalThis.Object.getOwnPropertyNames(schema.properties);
|
|
282
|
+
for (const schemaKey of schemaKeys) {
|
|
283
|
+
const memberExpression = MemberExpression.Encode(value, schemaKey);
|
|
284
|
+
const property = schema.properties[schemaKey];
|
|
285
|
+
if (schema.required && schema.required.includes(schemaKey)) {
|
|
286
|
+
yield* Visit(property, memberExpression);
|
|
287
|
+
if (Types.ExtendsUndefined.Check(property))
|
|
288
|
+
yield `('${schemaKey}' in ${value})`;
|
|
250
289
|
}
|
|
251
290
|
else {
|
|
252
|
-
const
|
|
253
|
-
yield `(
|
|
291
|
+
const expression = CreateExpression(property, memberExpression);
|
|
292
|
+
yield `('${schemaKey}' in ${value} ? ${expression} : true)`;
|
|
254
293
|
}
|
|
255
294
|
}
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))`;
|
|
260
|
-
}
|
|
261
|
-
for (const propertyKey of propertyKeys) {
|
|
262
|
-
const memberExpression = MemberExpression.Encode(value, propertyKey);
|
|
263
|
-
const propertySchema = schema.properties[propertyKey];
|
|
264
|
-
if (schema.required && schema.required.includes(propertyKey)) {
|
|
265
|
-
yield* Visit(propertySchema, memberExpression);
|
|
295
|
+
if (schema.additionalProperties === false) {
|
|
296
|
+
if (schema.required && schema.required.length === schemaKeys.length) {
|
|
297
|
+
yield `Object.getOwnPropertyNames(${value}).length === ${schemaKeys.length}`;
|
|
266
298
|
}
|
|
267
299
|
else {
|
|
268
|
-
const
|
|
269
|
-
yield `(${
|
|
300
|
+
const keys = `[${schemaKeys.map((key) => `'${key}'`).join(', ')}]`;
|
|
301
|
+
yield `Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key))`;
|
|
270
302
|
}
|
|
271
303
|
}
|
|
304
|
+
if (typeof schema.additionalProperties === 'object') {
|
|
305
|
+
const expression = CreateExpression(schema.additionalProperties, 'value[key]');
|
|
306
|
+
const keys = `[${schemaKeys.map((key) => `'${key}'`).join(', ')}]`;
|
|
307
|
+
yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))`;
|
|
308
|
+
}
|
|
272
309
|
}
|
|
273
310
|
function* Promise(schema, value) {
|
|
274
311
|
yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
|
|
275
312
|
}
|
|
276
313
|
function* Record(schema, value) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
else {
|
|
281
|
-
yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !Array.isArray(${value}))`;
|
|
282
|
-
}
|
|
314
|
+
yield `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date))`;
|
|
315
|
+
if (!index_2.TypeSystem.AllowArrayObjects)
|
|
316
|
+
yield `!Array.isArray(${value})`;
|
|
283
317
|
const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
|
|
284
318
|
const local = PushLocal(`new RegExp(/${keyPattern}/)`);
|
|
285
319
|
yield `(Object.getOwnPropertyNames(${value}).every(key => ${local}.test(key)))`;
|
|
286
320
|
const expression = CreateExpression(valueSchema, 'value');
|
|
287
|
-
yield `
|
|
321
|
+
yield `Object.values(${value}).every(value => ${expression})`;
|
|
288
322
|
}
|
|
289
323
|
function* Ref(schema, value) {
|
|
290
324
|
// Reference: If we have seen this reference before we can just yield and return
|
|
291
325
|
// the function call. If this isn't the case we defer to visit to generate and
|
|
292
326
|
// set the function for subsequent passes. Consider for refactor.
|
|
293
327
|
if (state_local_function_names.has(schema.$ref))
|
|
294
|
-
return yield
|
|
295
|
-
|
|
296
|
-
throw Error(`TypeCompiler.Ref: Cannot de-reference schema with $id '${schema.$ref}'`);
|
|
297
|
-
const reference = state_reference_map.get(schema.$ref);
|
|
298
|
-
yield* Visit(reference, value);
|
|
328
|
+
return yield `${CreateFunctionName(schema.$ref)}(${value})`;
|
|
329
|
+
yield* Visit(Types.ReferenceRegistry.DerefOne(schema), value);
|
|
299
330
|
}
|
|
300
331
|
function* Self(schema, value) {
|
|
301
332
|
const func = CreateFunctionName(schema.$ref);
|
|
302
|
-
yield
|
|
333
|
+
yield `${func}(${value})`;
|
|
303
334
|
}
|
|
304
335
|
function* String(schema, value) {
|
|
305
336
|
yield `(typeof ${value} === 'string')`;
|
|
306
337
|
if (IsNumber(schema.minLength))
|
|
307
|
-
yield
|
|
338
|
+
yield `${value}.length >= ${schema.minLength}`;
|
|
308
339
|
if (IsNumber(schema.maxLength))
|
|
309
|
-
yield
|
|
340
|
+
yield `${value}.length <= ${schema.maxLength}`;
|
|
310
341
|
if (schema.pattern !== undefined) {
|
|
311
342
|
const local = PushLocal(`${new RegExp(schema.pattern)};`);
|
|
312
|
-
yield
|
|
343
|
+
yield `${local}.test(${value})`;
|
|
313
344
|
}
|
|
314
345
|
if (schema.format !== undefined) {
|
|
315
|
-
yield `
|
|
346
|
+
yield `format('${schema.format}', ${value})`;
|
|
316
347
|
}
|
|
317
348
|
}
|
|
349
|
+
function* Symbol(schema, value) {
|
|
350
|
+
yield `(typeof ${value} === 'symbol')`;
|
|
351
|
+
}
|
|
318
352
|
function* Tuple(schema, value) {
|
|
319
353
|
yield `(Array.isArray(${value}))`;
|
|
320
354
|
if (schema.items === undefined)
|
|
321
|
-
return yield
|
|
355
|
+
return yield `${value}.length === 0`;
|
|
322
356
|
yield `(${value}.length === ${schema.maxItems})`;
|
|
323
357
|
for (let i = 0; i < schema.items.length; i++) {
|
|
324
358
|
const expression = CreateExpression(schema.items[i], `${value}[${i}]`);
|
|
325
|
-
yield
|
|
359
|
+
yield `${expression}`;
|
|
326
360
|
}
|
|
327
361
|
}
|
|
328
362
|
function* Undefined(schema, value) {
|
|
329
|
-
yield
|
|
363
|
+
yield `${value} === undefined`;
|
|
330
364
|
}
|
|
331
365
|
function* Union(schema, value) {
|
|
332
366
|
const expressions = schema.anyOf.map((schema) => CreateExpression(schema, value));
|
|
333
367
|
yield `(${expressions.join(' || ')})`;
|
|
334
368
|
}
|
|
335
369
|
function* Uint8Array(schema, value) {
|
|
336
|
-
yield
|
|
370
|
+
yield `${value} instanceof Uint8Array`;
|
|
337
371
|
if (IsNumber(schema.maxByteLength))
|
|
338
372
|
yield `(${value}.length <= ${schema.maxByteLength})`;
|
|
339
373
|
if (IsNumber(schema.minByteLength))
|
|
340
374
|
yield `(${value}.length >= ${schema.minByteLength})`;
|
|
341
375
|
}
|
|
342
376
|
function* Unknown(schema, value) {
|
|
343
|
-
yield '
|
|
377
|
+
yield 'true';
|
|
344
378
|
}
|
|
345
379
|
function* Void(schema, value) {
|
|
346
|
-
|
|
380
|
+
if (index_2.TypeSystem.AllowVoidNull) {
|
|
381
|
+
yield `(${value} === undefined || ${value} === null)`;
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
yield `${value} === undefined`;
|
|
385
|
+
}
|
|
347
386
|
}
|
|
348
387
|
function* UserDefined(schema, value) {
|
|
349
388
|
const schema_key = `schema_key_${state_remote_custom_types.size}`;
|
|
350
389
|
state_remote_custom_types.set(schema_key, schema);
|
|
351
|
-
yield `
|
|
390
|
+
yield `custom('${schema[Types.Kind]}', '${schema_key}', ${value})`;
|
|
352
391
|
}
|
|
353
392
|
function* Visit(schema, value) {
|
|
354
393
|
// Reference: Referenced schemas can originate from either additional schemas
|
|
@@ -359,7 +398,7 @@ var TypeCompiler;
|
|
|
359
398
|
const name = CreateFunctionName(schema.$id);
|
|
360
399
|
const body = CreateFunction(name, schema, 'value');
|
|
361
400
|
PushFunction(body);
|
|
362
|
-
yield
|
|
401
|
+
yield `${name}(${value})`;
|
|
363
402
|
return;
|
|
364
403
|
}
|
|
365
404
|
const anySchema = schema;
|
|
@@ -368,6 +407,8 @@ var TypeCompiler;
|
|
|
368
407
|
return yield* Any(anySchema, value);
|
|
369
408
|
case 'Array':
|
|
370
409
|
return yield* Array(anySchema, value);
|
|
410
|
+
case 'BigInt':
|
|
411
|
+
return yield* BigInt(anySchema, value);
|
|
371
412
|
case 'Boolean':
|
|
372
413
|
return yield* Boolean(anySchema, value);
|
|
373
414
|
case 'Constructor':
|
|
@@ -378,10 +419,14 @@ var TypeCompiler;
|
|
|
378
419
|
return yield* Function(anySchema, value);
|
|
379
420
|
case 'Integer':
|
|
380
421
|
return yield* Integer(anySchema, value);
|
|
422
|
+
case 'Intersect':
|
|
423
|
+
return yield* Intersect(anySchema, value);
|
|
381
424
|
case 'Literal':
|
|
382
425
|
return yield* Literal(anySchema, value);
|
|
383
426
|
case 'Never':
|
|
384
427
|
return yield* Never(anySchema, value);
|
|
428
|
+
case 'Not':
|
|
429
|
+
return yield* Not(anySchema, value);
|
|
385
430
|
case 'Null':
|
|
386
431
|
return yield* Null(anySchema, value);
|
|
387
432
|
case 'Number':
|
|
@@ -398,6 +443,8 @@ var TypeCompiler;
|
|
|
398
443
|
return yield* Self(anySchema, value);
|
|
399
444
|
case 'String':
|
|
400
445
|
return yield* String(anySchema, value);
|
|
446
|
+
case 'Symbol':
|
|
447
|
+
return yield* Symbol(anySchema, value);
|
|
401
448
|
case 'Tuple':
|
|
402
449
|
return yield* Tuple(anySchema, value);
|
|
403
450
|
case 'Undefined':
|
|
@@ -411,7 +458,7 @@ var TypeCompiler;
|
|
|
411
458
|
case 'Void':
|
|
412
459
|
return yield* Void(anySchema, value);
|
|
413
460
|
default:
|
|
414
|
-
if (!
|
|
461
|
+
if (!Types.TypeRegistry.Has(anySchema[Types.Kind]))
|
|
415
462
|
throw new TypeCompilerUnknownTypeError(schema);
|
|
416
463
|
return yield* UserDefined(anySchema, value);
|
|
417
464
|
}
|
|
@@ -419,25 +466,14 @@ var TypeCompiler;
|
|
|
419
466
|
// -------------------------------------------------------------------
|
|
420
467
|
// Compiler State
|
|
421
468
|
// -------------------------------------------------------------------
|
|
422
|
-
const state_reference_map = new Map(); // tracks schemas with identifiers
|
|
423
469
|
const state_local_variables = new Set(); // local variables and functions
|
|
424
470
|
const state_local_function_names = new Set(); // local function names used call ref validators
|
|
425
471
|
const state_remote_custom_types = new Map(); // remote custom types used during compilation
|
|
426
472
|
function ResetCompiler() {
|
|
427
|
-
state_reference_map.clear();
|
|
428
473
|
state_local_variables.clear();
|
|
429
474
|
state_local_function_names.clear();
|
|
430
475
|
state_remote_custom_types.clear();
|
|
431
476
|
}
|
|
432
|
-
function AddReferences(schemas = []) {
|
|
433
|
-
for (const schema of schemas) {
|
|
434
|
-
if (!schema.$id)
|
|
435
|
-
throw new Error(`TypeCompiler: Referenced schemas must specify an $id.`);
|
|
436
|
-
if (state_reference_map.has(schema.$id))
|
|
437
|
-
throw new Error(`TypeCompiler: Duplicate schema $id found for '${schema.$id}'`);
|
|
438
|
-
state_reference_map.set(schema.$id, schema);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
477
|
function CreateExpression(schema, value) {
|
|
442
478
|
return `(${[...Visit(schema, value)].join(' && ')})`;
|
|
443
479
|
}
|
|
@@ -462,34 +498,39 @@ var TypeCompiler;
|
|
|
462
498
|
// -------------------------------------------------------------------
|
|
463
499
|
// Compile
|
|
464
500
|
// -------------------------------------------------------------------
|
|
465
|
-
function Build(schema
|
|
501
|
+
function Build(schema) {
|
|
466
502
|
ResetCompiler();
|
|
467
|
-
AddReferences(references);
|
|
468
503
|
const check = CreateFunction('check', schema, 'value');
|
|
469
504
|
const locals = GetLocals();
|
|
470
505
|
return `${locals.join('\n')}\nreturn ${check}`;
|
|
471
506
|
}
|
|
507
|
+
/** Returns the generated validation code used to validate this type. */
|
|
508
|
+
function Code(schema) {
|
|
509
|
+
if (!Types.TypeGuard.TSchema(schema))
|
|
510
|
+
throw new TypeCompilerPreflightCheckError(schema);
|
|
511
|
+
return Build(schema);
|
|
512
|
+
}
|
|
513
|
+
TypeCompiler.Code = Code;
|
|
472
514
|
/** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
|
|
473
|
-
function Compile(schema
|
|
474
|
-
|
|
475
|
-
const code = Build(schema, references);
|
|
515
|
+
function Compile(schema) {
|
|
516
|
+
const code = Code(schema);
|
|
476
517
|
const custom_schemas = new Map(state_remote_custom_types);
|
|
477
518
|
const compiledFunction = globalThis.Function('custom', 'format', 'hash', code);
|
|
478
519
|
const checkFunction = compiledFunction((kind, schema_key, value) => {
|
|
479
|
-
if (!
|
|
520
|
+
if (!Types.TypeRegistry.Has(kind) || !custom_schemas.has(schema_key))
|
|
480
521
|
return false;
|
|
481
522
|
const schema = custom_schemas.get(schema_key);
|
|
482
|
-
const func =
|
|
523
|
+
const func = Types.TypeRegistry.Get(kind);
|
|
483
524
|
return func(schema, value);
|
|
484
525
|
}, (format, value) => {
|
|
485
|
-
if (!
|
|
526
|
+
if (!Types.FormatRegistry.Has(format))
|
|
486
527
|
return false;
|
|
487
|
-
const func =
|
|
528
|
+
const func = Types.FormatRegistry.Get(format);
|
|
488
529
|
return func(value);
|
|
489
530
|
}, (value) => {
|
|
490
|
-
return
|
|
531
|
+
return hash_1.ValueHash.Create(value);
|
|
491
532
|
});
|
|
492
|
-
return new TypeCheck(schema,
|
|
533
|
+
return new TypeCheck(schema, checkFunction, code);
|
|
493
534
|
}
|
|
494
535
|
TypeCompiler.Compile = Compile;
|
|
495
536
|
})(TypeCompiler = exports.TypeCompiler || (exports.TypeCompiler = {}));
|
package/errors/errors.d.ts
CHANGED
|
@@ -4,51 +4,61 @@ export declare enum ValueErrorType {
|
|
|
4
4
|
ArrayMinItems = 1,
|
|
5
5
|
ArrayMaxItems = 2,
|
|
6
6
|
ArrayUniqueItems = 3,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
7
|
+
BigInt = 4,
|
|
8
|
+
BigIntMultipleOf = 5,
|
|
9
|
+
BigIntExclusiveMinimum = 6,
|
|
10
|
+
BigIntExclusiveMaximum = 7,
|
|
11
|
+
BigIntMinimum = 8,
|
|
12
|
+
BigIntMaximum = 9,
|
|
13
|
+
Boolean = 10,
|
|
14
|
+
Date = 11,
|
|
15
|
+
DateExclusiveMinimumTimestamp = 12,
|
|
16
|
+
DateExclusiveMaximumTimestamp = 13,
|
|
17
|
+
DateMinimumTimestamp = 14,
|
|
18
|
+
DateMaximumTimestamp = 15,
|
|
19
|
+
Function = 16,
|
|
20
|
+
Integer = 17,
|
|
21
|
+
IntegerMultipleOf = 18,
|
|
22
|
+
IntegerExclusiveMinimum = 19,
|
|
23
|
+
IntegerExclusiveMaximum = 20,
|
|
24
|
+
IntegerMinimum = 21,
|
|
25
|
+
IntegerMaximum = 22,
|
|
26
|
+
Intersect = 23,
|
|
27
|
+
IntersectUnevaluatedProperties = 24,
|
|
28
|
+
Literal = 25,
|
|
29
|
+
Never = 26,
|
|
30
|
+
Not = 27,
|
|
31
|
+
Null = 28,
|
|
32
|
+
Number = 29,
|
|
33
|
+
NumberMultipleOf = 30,
|
|
34
|
+
NumberExclusiveMinimum = 31,
|
|
35
|
+
NumberExclusiveMaximum = 32,
|
|
36
|
+
NumberMinumum = 33,
|
|
37
|
+
NumberMaximum = 34,
|
|
38
|
+
Object = 35,
|
|
39
|
+
ObjectMinProperties = 36,
|
|
40
|
+
ObjectMaxProperties = 37,
|
|
41
|
+
ObjectAdditionalProperties = 38,
|
|
42
|
+
ObjectRequiredProperties = 39,
|
|
43
|
+
Promise = 40,
|
|
44
|
+
RecordKeyNumeric = 41,
|
|
45
|
+
RecordKeyString = 42,
|
|
46
|
+
String = 43,
|
|
47
|
+
StringMinLength = 44,
|
|
48
|
+
StringMaxLength = 45,
|
|
49
|
+
StringPattern = 46,
|
|
50
|
+
StringFormatUnknown = 47,
|
|
51
|
+
StringFormat = 48,
|
|
52
|
+
Symbol = 49,
|
|
53
|
+
TupleZeroLength = 50,
|
|
54
|
+
TupleLength = 51,
|
|
55
|
+
Undefined = 52,
|
|
56
|
+
Union = 53,
|
|
57
|
+
Uint8Array = 54,
|
|
58
|
+
Uint8ArrayMinByteLength = 55,
|
|
59
|
+
Uint8ArrayMaxByteLength = 56,
|
|
60
|
+
Void = 57,
|
|
61
|
+
Custom = 58
|
|
52
62
|
}
|
|
53
63
|
export interface ValueError {
|
|
54
64
|
type: ValueErrorType;
|
|
@@ -63,5 +73,5 @@ export declare class ValueErrorsUnknownTypeError extends Error {
|
|
|
63
73
|
}
|
|
64
74
|
/** Provides functionality to generate a sequence of errors against a TypeBox type. */
|
|
65
75
|
export declare namespace ValueErrors {
|
|
66
|
-
function Errors<T extends Types.TSchema>(schema: T,
|
|
76
|
+
function Errors<T extends Types.TSchema>(schema: T, value: any): IterableIterator<ValueError>;
|
|
67
77
|
}
|