@sinclair/typebox 0.30.4 → 0.31.0-dev-2
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 +22 -14
- package/compiler/compiler.js +119 -106
- package/compiler/index.d.ts +1 -1
- package/compiler/index.js +2 -1
- package/errors/errors.d.ts +56 -61
- package/errors/errors.js +222 -279
- package/package.json +5 -3
- package/readme.md +588 -507
- package/system/system.d.ts +34 -8
- package/system/system.js +214 -11
- package/typebox.d.ts +180 -106
- package/typebox.js +794 -907
- package/value/cast.d.ts +6 -12
- package/value/cast.js +81 -163
- package/value/check.d.ts +1 -5
- package/value/check.js +59 -103
- package/value/clone.js +6 -29
- package/value/convert.d.ts +2 -5
- package/value/convert.js +55 -106
- package/value/create.d.ts +6 -10
- package/value/create.js +54 -68
- package/value/delta.js +22 -22
- package/value/deref.d.ts +7 -0
- package/value/deref.js +46 -0
- package/value/equal.js +10 -10
- package/value/guard.js +1 -1
- package/value/hash.js +14 -14
- package/value/mutate.js +17 -17
- package/value/pointer.js +2 -2
- package/value/transform.d.ts +42 -0
- package/value/transform.js +512 -0
- package/value/value.d.ts +8 -0
- package/value/value.js +18 -0
package/compiler/compiler.d.ts
CHANGED
|
@@ -1,41 +1,49 @@
|
|
|
1
|
+
import { ValueErrorIterator } from '../errors/errors';
|
|
1
2
|
import * as Types from '../typebox';
|
|
2
|
-
import * as ValueErrors 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
6
|
private readonly references;
|
|
7
7
|
private readonly checkFunc;
|
|
8
8
|
private readonly code;
|
|
9
|
+
private readonly hasTransform;
|
|
9
10
|
constructor(schema: T, references: Types.TSchema[], checkFunc: CheckFunction, code: string);
|
|
10
11
|
/** Returns the generated assertion code used to validate this type. */
|
|
11
12
|
Code(): string;
|
|
12
13
|
/** Returns an iterator for each error in this value. */
|
|
13
|
-
Errors(value: unknown):
|
|
14
|
+
Errors(value: unknown): ValueErrorIterator;
|
|
14
15
|
/** Returns true if the value matches the compiled type. */
|
|
15
16
|
Check(value: unknown): value is Types.Static<T>;
|
|
17
|
+
/** Decodes a value or throws if error */
|
|
18
|
+
Decode(value: unknown): Types.StaticDecode<T>;
|
|
19
|
+
/** Encodes a value or throws if error */
|
|
20
|
+
Encode(value: unknown): Types.StaticEncode<T>;
|
|
16
21
|
}
|
|
17
|
-
export declare class TypeCompilerUnknownTypeError extends
|
|
22
|
+
export declare class TypeCompilerUnknownTypeError extends Types.TypeBoxError {
|
|
18
23
|
readonly schema: Types.TSchema;
|
|
19
24
|
constructor(schema: Types.TSchema);
|
|
20
25
|
}
|
|
21
|
-
export declare class
|
|
22
|
-
readonly schema: Types.TRef;
|
|
23
|
-
constructor(schema: Types.TRef);
|
|
24
|
-
}
|
|
25
|
-
export declare class TypeCompilerTypeGuardError extends Error {
|
|
26
|
+
export declare class TypeCompilerTypeGuardError extends Types.TypeBoxError {
|
|
26
27
|
readonly schema: Types.TSchema;
|
|
27
28
|
constructor(schema: Types.TSchema);
|
|
28
29
|
}
|
|
30
|
+
export declare namespace Policy {
|
|
31
|
+
function IsExactOptionalProperty(value: string, key: string, expression: string): string;
|
|
32
|
+
function IsObjectLike(value: string): string;
|
|
33
|
+
function IsRecordLike(value: string): string;
|
|
34
|
+
function IsNumberLike(value: string): string;
|
|
35
|
+
function IsVoidLike(value: string): string;
|
|
36
|
+
}
|
|
29
37
|
export type TypeCompilerLanguageOption = 'typescript' | 'javascript';
|
|
30
|
-
export interface
|
|
38
|
+
export interface TypeCompilerCodegenOptions {
|
|
31
39
|
language?: TypeCompilerLanguageOption;
|
|
32
40
|
}
|
|
33
41
|
/** Compiles Types for Runtime Type Checking */
|
|
34
42
|
export declare namespace TypeCompiler {
|
|
35
|
-
/**
|
|
36
|
-
function Code<T extends Types.TSchema>(schema: T, references: Types.TSchema[], options?:
|
|
37
|
-
/**
|
|
38
|
-
function Code<T extends Types.TSchema>(schema: T, options?:
|
|
39
|
-
/** Compiles
|
|
43
|
+
/** Generates the code used to assert this type and returns it as a string */
|
|
44
|
+
function Code<T extends Types.TSchema>(schema: T, references: Types.TSchema[], options?: TypeCompilerCodegenOptions): string;
|
|
45
|
+
/** Generates the code used to assert this type and returns it as a string */
|
|
46
|
+
function Code<T extends Types.TSchema>(schema: T, options?: TypeCompilerCodegenOptions): string;
|
|
47
|
+
/** Compiles a TypeBox type for optimal runtime type checking. Types must be valid TypeBox types of TSchema */
|
|
40
48
|
function Compile<T extends Types.TSchema>(schema: T, references?: Types.TSchema[]): TypeCheck<T>;
|
|
41
49
|
}
|
package/compiler/compiler.js
CHANGED
|
@@ -27,12 +27,14 @@ THE SOFTWARE.
|
|
|
27
27
|
|
|
28
28
|
---------------------------------------------------------------------------*/
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.TypeCompiler = exports.
|
|
30
|
+
exports.TypeCompiler = exports.Policy = exports.TypeCompilerTypeGuardError = exports.TypeCompilerUnknownTypeError = exports.TypeCheck = void 0;
|
|
31
|
+
const transform_1 = require("../value/transform");
|
|
32
|
+
const guard_1 = require("../value/guard");
|
|
33
|
+
const errors_1 = require("../errors/errors");
|
|
31
34
|
const index_1 = require("../system/index");
|
|
35
|
+
const deref_1 = require("../value/deref");
|
|
36
|
+
const hash_1 = require("../value/hash");
|
|
32
37
|
const Types = require("../typebox");
|
|
33
|
-
const ValueErrors = require("../errors/index");
|
|
34
|
-
const ValueHash = require("../value/hash");
|
|
35
|
-
const ValueGuard = require("../value/guard");
|
|
36
38
|
// -------------------------------------------------------------------
|
|
37
39
|
// TypeCheck
|
|
38
40
|
// -------------------------------------------------------------------
|
|
@@ -42,6 +44,7 @@ class TypeCheck {
|
|
|
42
44
|
this.references = references;
|
|
43
45
|
this.checkFunc = checkFunc;
|
|
44
46
|
this.code = code;
|
|
47
|
+
this.hasTransform = transform_1.HasTransform.Has(schema, references);
|
|
45
48
|
}
|
|
46
49
|
/** Returns the generated assertion code used to validate this type. */
|
|
47
50
|
Code() {
|
|
@@ -49,12 +52,25 @@ class TypeCheck {
|
|
|
49
52
|
}
|
|
50
53
|
/** Returns an iterator for each error in this value. */
|
|
51
54
|
Errors(value) {
|
|
52
|
-
return
|
|
55
|
+
return (0, errors_1.Errors)(this.schema, this.references, value);
|
|
53
56
|
}
|
|
54
57
|
/** Returns true if the value matches the compiled type. */
|
|
55
58
|
Check(value) {
|
|
56
59
|
return this.checkFunc(value);
|
|
57
60
|
}
|
|
61
|
+
/** Decodes a value or throws if error */
|
|
62
|
+
Decode(value) {
|
|
63
|
+
if (!this.checkFunc(value))
|
|
64
|
+
throw new transform_1.TransformDecodeCheckError(this.schema, value, this.Errors(value).First());
|
|
65
|
+
return this.hasTransform ? transform_1.DecodeTransform.Decode(this.schema, this.references, value, (_, __, value) => this.Check(value)) : value;
|
|
66
|
+
}
|
|
67
|
+
/** Encodes a value or throws if error */
|
|
68
|
+
Encode(value) {
|
|
69
|
+
const encoded = this.hasTransform ? transform_1.EncodeTransform.Encode(this.schema, this.references, value, (_, __, value) => this.Check(value)) : value;
|
|
70
|
+
if (!this.checkFunc(encoded))
|
|
71
|
+
throw new transform_1.TransformEncodeCheckError(this.schema, value, this.Errors(value).First());
|
|
72
|
+
return encoded;
|
|
73
|
+
}
|
|
58
74
|
}
|
|
59
75
|
exports.TypeCheck = TypeCheck;
|
|
60
76
|
// -------------------------------------------------------------------
|
|
@@ -131,27 +147,48 @@ var Identifier;
|
|
|
131
147
|
// -------------------------------------------------------------------
|
|
132
148
|
// Errors
|
|
133
149
|
// -------------------------------------------------------------------
|
|
134
|
-
class TypeCompilerUnknownTypeError extends
|
|
150
|
+
class TypeCompilerUnknownTypeError extends Types.TypeBoxError {
|
|
135
151
|
constructor(schema) {
|
|
136
|
-
super('
|
|
152
|
+
super('Unknown type');
|
|
137
153
|
this.schema = schema;
|
|
138
154
|
}
|
|
139
155
|
}
|
|
140
156
|
exports.TypeCompilerUnknownTypeError = TypeCompilerUnknownTypeError;
|
|
141
|
-
class
|
|
142
|
-
constructor(schema) {
|
|
143
|
-
super(`TypeCompiler: Unable to dereference type with $id '${schema.$ref}'`);
|
|
144
|
-
this.schema = schema;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
exports.TypeCompilerDereferenceError = TypeCompilerDereferenceError;
|
|
148
|
-
class TypeCompilerTypeGuardError extends Error {
|
|
157
|
+
class TypeCompilerTypeGuardError extends Types.TypeBoxError {
|
|
149
158
|
constructor(schema) {
|
|
150
|
-
super('
|
|
159
|
+
super('Preflight validation check failed to guard for the given schema');
|
|
151
160
|
this.schema = schema;
|
|
152
161
|
}
|
|
153
162
|
}
|
|
154
163
|
exports.TypeCompilerTypeGuardError = TypeCompilerTypeGuardError;
|
|
164
|
+
// -------------------------------------------------------------------
|
|
165
|
+
// Policy
|
|
166
|
+
// -------------------------------------------------------------------
|
|
167
|
+
var Policy;
|
|
168
|
+
(function (Policy) {
|
|
169
|
+
function IsExactOptionalProperty(value, key, expression) {
|
|
170
|
+
return index_1.TypeSystemPolicy.ExactOptionalPropertyTypes ? `('${key}' in ${value} ? ${expression} : true)` : `(${MemberExpression.Encode(value, key)} !== undefined ? ${expression} : true)`;
|
|
171
|
+
}
|
|
172
|
+
Policy.IsExactOptionalProperty = IsExactOptionalProperty;
|
|
173
|
+
function IsObjectLike(value) {
|
|
174
|
+
return !index_1.TypeSystemPolicy.AllowArrayObject ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))` : `(typeof ${value} === 'object' && ${value} !== null)`;
|
|
175
|
+
}
|
|
176
|
+
Policy.IsObjectLike = IsObjectLike;
|
|
177
|
+
function IsRecordLike(value) {
|
|
178
|
+
return !index_1.TypeSystemPolicy.AllowArrayObject
|
|
179
|
+
? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}) && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`
|
|
180
|
+
: `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`;
|
|
181
|
+
}
|
|
182
|
+
Policy.IsRecordLike = IsRecordLike;
|
|
183
|
+
function IsNumberLike(value) {
|
|
184
|
+
return !index_1.TypeSystemPolicy.AllowNaN ? `(typeof ${value} === 'number' && Number.isFinite(${value}))` : `typeof ${value} === 'number'`;
|
|
185
|
+
}
|
|
186
|
+
Policy.IsNumberLike = IsNumberLike;
|
|
187
|
+
function IsVoidLike(value) {
|
|
188
|
+
return index_1.TypeSystemPolicy.AllowNullVoid ? `(${value} === undefined || ${value} === null)` : `${value} === undefined`;
|
|
189
|
+
}
|
|
190
|
+
Policy.IsVoidLike = IsVoidLike;
|
|
191
|
+
})(Policy || (exports.Policy = Policy = {}));
|
|
155
192
|
/** Compiles Types for Runtime Type Checking */
|
|
156
193
|
var TypeCompiler;
|
|
157
194
|
(function (TypeCompiler) {
|
|
@@ -162,26 +199,6 @@ var TypeCompiler;
|
|
|
162
199
|
return schema[Types.Kind] === 'Any' || schema[Types.Kind] === 'Unknown';
|
|
163
200
|
}
|
|
164
201
|
// -------------------------------------------------------------------
|
|
165
|
-
// Polices
|
|
166
|
-
// -------------------------------------------------------------------
|
|
167
|
-
function IsExactOptionalProperty(value, key, expression) {
|
|
168
|
-
return index_1.TypeSystem.ExactOptionalPropertyTypes ? `('${key}' in ${value} ? ${expression} : true)` : `(${MemberExpression.Encode(value, key)} !== undefined ? ${expression} : true)`;
|
|
169
|
-
}
|
|
170
|
-
function IsObjectCheck(value) {
|
|
171
|
-
return !index_1.TypeSystem.AllowArrayObjects ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))` : `(typeof ${value} === 'object' && ${value} !== null)`;
|
|
172
|
-
}
|
|
173
|
-
function IsRecordCheck(value) {
|
|
174
|
-
return !index_1.TypeSystem.AllowArrayObjects
|
|
175
|
-
? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}) && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`
|
|
176
|
-
: `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`;
|
|
177
|
-
}
|
|
178
|
-
function IsNumberCheck(value) {
|
|
179
|
-
return !index_1.TypeSystem.AllowNaN ? `(typeof ${value} === 'number' && Number.isFinite(${value}))` : `typeof ${value} === 'number'`;
|
|
180
|
-
}
|
|
181
|
-
function IsVoidCheck(value) {
|
|
182
|
-
return index_1.TypeSystem.AllowVoidNull ? `(${value} === undefined || ${value} === null)` : `${value} === undefined`;
|
|
183
|
-
}
|
|
184
|
-
// -------------------------------------------------------------------
|
|
185
202
|
// Types
|
|
186
203
|
// -------------------------------------------------------------------
|
|
187
204
|
function* TAny(schema, references, value) {
|
|
@@ -190,17 +207,17 @@ var TypeCompiler;
|
|
|
190
207
|
function* TArray(schema, references, value) {
|
|
191
208
|
yield `Array.isArray(${value})`;
|
|
192
209
|
const [parameter, accumulator] = [CreateParameter('value', 'any'), CreateParameter('acc', 'number')];
|
|
193
|
-
if (
|
|
194
|
-
yield `${value}.length >= ${schema.minItems}`;
|
|
195
|
-
if (ValueGuard.IsNumber(schema.maxItems))
|
|
210
|
+
if ((0, guard_1.IsNumber)(schema.maxItems))
|
|
196
211
|
yield `${value}.length <= ${schema.maxItems}`;
|
|
212
|
+
if ((0, guard_1.IsNumber)(schema.minItems))
|
|
213
|
+
yield `${value}.length >= ${schema.minItems}`;
|
|
197
214
|
const elementExpression = CreateExpression(schema.items, references, 'value');
|
|
198
215
|
yield `${value}.every((${parameter}) => ${elementExpression})`;
|
|
199
|
-
if (Types.TypeGuard.TSchema(schema.contains) ||
|
|
216
|
+
if (Types.TypeGuard.TSchema(schema.contains) || (0, guard_1.IsNumber)(schema.minContains) || (0, guard_1.IsNumber)(schema.maxContains)) {
|
|
200
217
|
const containsSchema = Types.TypeGuard.TSchema(schema.contains) ? schema.contains : Types.Type.Never();
|
|
201
218
|
const checkExpression = CreateExpression(containsSchema, references, 'value');
|
|
202
|
-
const checkMinContains =
|
|
203
|
-
const checkMaxContains =
|
|
219
|
+
const checkMinContains = (0, guard_1.IsNumber)(schema.minContains) ? [`(count >= ${schema.minContains})`] : [];
|
|
220
|
+
const checkMaxContains = (0, guard_1.IsNumber)(schema.maxContains) ? [`(count <= ${schema.maxContains})`] : [];
|
|
204
221
|
const checkCount = `const count = ${value}.reduce((${accumulator}, ${parameter}) => ${checkExpression} ? acc + 1 : acc, 0)`;
|
|
205
222
|
const check = [`(count > 0)`, ...checkMinContains, ...checkMaxContains].join(' && ');
|
|
206
223
|
yield `((${parameter}) => { ${checkCount}; return ${check}})(${value})`;
|
|
@@ -216,16 +233,16 @@ var TypeCompiler;
|
|
|
216
233
|
}
|
|
217
234
|
function* TBigInt(schema, references, value) {
|
|
218
235
|
yield `(typeof ${value} === 'bigint')`;
|
|
219
|
-
if (
|
|
220
|
-
yield `(${value} % BigInt(${schema.multipleOf})) === 0`;
|
|
221
|
-
if (ValueGuard.IsBigInt(schema.exclusiveMinimum))
|
|
222
|
-
yield `${value} > BigInt(${schema.exclusiveMinimum})`;
|
|
223
|
-
if (ValueGuard.IsBigInt(schema.exclusiveMaximum))
|
|
236
|
+
if ((0, guard_1.IsBigInt)(schema.exclusiveMaximum))
|
|
224
237
|
yield `${value} < BigInt(${schema.exclusiveMaximum})`;
|
|
225
|
-
if (
|
|
226
|
-
yield `${value}
|
|
227
|
-
if (
|
|
238
|
+
if ((0, guard_1.IsBigInt)(schema.exclusiveMinimum))
|
|
239
|
+
yield `${value} > BigInt(${schema.exclusiveMinimum})`;
|
|
240
|
+
if ((0, guard_1.IsBigInt)(schema.maximum))
|
|
228
241
|
yield `${value} <= BigInt(${schema.maximum})`;
|
|
242
|
+
if ((0, guard_1.IsBigInt)(schema.minimum))
|
|
243
|
+
yield `${value} >= BigInt(${schema.minimum})`;
|
|
244
|
+
if ((0, guard_1.IsBigInt)(schema.multipleOf))
|
|
245
|
+
yield `(${value} % BigInt(${schema.multipleOf})) === 0`;
|
|
229
246
|
}
|
|
230
247
|
function* TBoolean(schema, references, value) {
|
|
231
248
|
yield `(typeof ${value} === 'boolean')`;
|
|
@@ -235,30 +252,32 @@ var TypeCompiler;
|
|
|
235
252
|
}
|
|
236
253
|
function* TDate(schema, references, value) {
|
|
237
254
|
yield `(${value} instanceof Date) && Number.isFinite(${value}.getTime())`;
|
|
238
|
-
if (
|
|
239
|
-
yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`;
|
|
240
|
-
if (ValueGuard.IsNumber(schema.exclusiveMaximumTimestamp))
|
|
255
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMaximumTimestamp))
|
|
241
256
|
yield `${value}.getTime() < ${schema.exclusiveMaximumTimestamp}`;
|
|
242
|
-
if (
|
|
243
|
-
yield `${value}.getTime()
|
|
244
|
-
if (
|
|
257
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMinimumTimestamp))
|
|
258
|
+
yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`;
|
|
259
|
+
if ((0, guard_1.IsNumber)(schema.maximumTimestamp))
|
|
245
260
|
yield `${value}.getTime() <= ${schema.maximumTimestamp}`;
|
|
261
|
+
if ((0, guard_1.IsNumber)(schema.minimumTimestamp))
|
|
262
|
+
yield `${value}.getTime() >= ${schema.minimumTimestamp}`;
|
|
263
|
+
if ((0, guard_1.IsNumber)(schema.multipleOfTimestamp))
|
|
264
|
+
yield `(${value}.getTime() % ${schema.multipleOfTimestamp}) === 0`;
|
|
246
265
|
}
|
|
247
266
|
function* TFunction(schema, references, value) {
|
|
248
267
|
yield `(typeof ${value} === 'function')`;
|
|
249
268
|
}
|
|
250
269
|
function* TInteger(schema, references, value) {
|
|
251
270
|
yield `(typeof ${value} === 'number' && Number.isInteger(${value}))`;
|
|
252
|
-
if (
|
|
253
|
-
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
254
|
-
if (ValueGuard.IsNumber(schema.exclusiveMinimum))
|
|
255
|
-
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
256
|
-
if (ValueGuard.IsNumber(schema.exclusiveMaximum))
|
|
271
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMaximum))
|
|
257
272
|
yield `${value} < ${schema.exclusiveMaximum}`;
|
|
258
|
-
if (
|
|
259
|
-
yield `${value}
|
|
260
|
-
if (
|
|
273
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMinimum))
|
|
274
|
+
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
275
|
+
if ((0, guard_1.IsNumber)(schema.maximum))
|
|
261
276
|
yield `${value} <= ${schema.maximum}`;
|
|
277
|
+
if ((0, guard_1.IsNumber)(schema.minimum))
|
|
278
|
+
yield `${value} >= ${schema.minimum}`;
|
|
279
|
+
if ((0, guard_1.IsNumber)(schema.multipleOf))
|
|
280
|
+
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
262
281
|
}
|
|
263
282
|
function* TIntersect(schema, references, value) {
|
|
264
283
|
const check1 = schema.allOf.map((schema) => CreateExpression(schema, references, value)).join(' && ');
|
|
@@ -298,23 +317,23 @@ var TypeCompiler;
|
|
|
298
317
|
yield `(${value} === null)`;
|
|
299
318
|
}
|
|
300
319
|
function* TNumber(schema, references, value) {
|
|
301
|
-
yield
|
|
302
|
-
if (
|
|
303
|
-
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
304
|
-
if (ValueGuard.IsNumber(schema.exclusiveMinimum))
|
|
305
|
-
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
306
|
-
if (ValueGuard.IsNumber(schema.exclusiveMaximum))
|
|
320
|
+
yield Policy.IsNumberLike(value);
|
|
321
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMaximum))
|
|
307
322
|
yield `${value} < ${schema.exclusiveMaximum}`;
|
|
308
|
-
if (
|
|
309
|
-
yield `${value}
|
|
310
|
-
if (
|
|
323
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMinimum))
|
|
324
|
+
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
325
|
+
if ((0, guard_1.IsNumber)(schema.maximum))
|
|
311
326
|
yield `${value} <= ${schema.maximum}`;
|
|
327
|
+
if ((0, guard_1.IsNumber)(schema.minimum))
|
|
328
|
+
yield `${value} >= ${schema.minimum}`;
|
|
329
|
+
if ((0, guard_1.IsNumber)(schema.multipleOf))
|
|
330
|
+
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
312
331
|
}
|
|
313
332
|
function* TObject(schema, references, value) {
|
|
314
|
-
yield
|
|
315
|
-
if (
|
|
333
|
+
yield Policy.IsObjectLike(value);
|
|
334
|
+
if ((0, guard_1.IsNumber)(schema.minProperties))
|
|
316
335
|
yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}`;
|
|
317
|
-
if (
|
|
336
|
+
if ((0, guard_1.IsNumber)(schema.maxProperties))
|
|
318
337
|
yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}`;
|
|
319
338
|
const knownKeys = Object.getOwnPropertyNames(schema.properties);
|
|
320
339
|
for (const knownKey of knownKeys) {
|
|
@@ -327,7 +346,7 @@ var TypeCompiler;
|
|
|
327
346
|
}
|
|
328
347
|
else {
|
|
329
348
|
const expression = CreateExpression(property, references, memberExpression);
|
|
330
|
-
yield IsExactOptionalProperty(value, knownKey, expression);
|
|
349
|
+
yield Policy.IsExactOptionalProperty(value, knownKey, expression);
|
|
331
350
|
}
|
|
332
351
|
}
|
|
333
352
|
if (schema.additionalProperties === false) {
|
|
@@ -349,10 +368,10 @@ var TypeCompiler;
|
|
|
349
368
|
yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
|
|
350
369
|
}
|
|
351
370
|
function* TRecord(schema, references, value) {
|
|
352
|
-
yield
|
|
353
|
-
if (
|
|
371
|
+
yield Policy.IsRecordLike(value);
|
|
372
|
+
if ((0, guard_1.IsNumber)(schema.minProperties))
|
|
354
373
|
yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}`;
|
|
355
|
-
if (
|
|
374
|
+
if ((0, guard_1.IsNumber)(schema.maxProperties))
|
|
356
375
|
yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}`;
|
|
357
376
|
const [patternKey, patternSchema] = Object.entries(schema.patternProperties)[0];
|
|
358
377
|
const variable = CreateVariable(`new RegExp(/${patternKey}/)`);
|
|
@@ -362,10 +381,7 @@ var TypeCompiler;
|
|
|
362
381
|
yield `(Object.entries(${value}).every(([key, value]) => ${expression}))`;
|
|
363
382
|
}
|
|
364
383
|
function* TRef(schema, references, value) {
|
|
365
|
-
const
|
|
366
|
-
if (index === -1)
|
|
367
|
-
throw new TypeCompilerDereferenceError(schema);
|
|
368
|
-
const target = references[index];
|
|
384
|
+
const target = (0, deref_1.Deref)(schema, references);
|
|
369
385
|
// Reference: If we have seen this reference before we can just yield and return the function call.
|
|
370
386
|
// If this isn't the case we defer to visit to generate and set the function for subsequent passes.
|
|
371
387
|
if (state.functions.has(schema.$ref))
|
|
@@ -374,10 +390,10 @@ var TypeCompiler;
|
|
|
374
390
|
}
|
|
375
391
|
function* TString(schema, references, value) {
|
|
376
392
|
yield `(typeof ${value} === 'string')`;
|
|
377
|
-
if (
|
|
378
|
-
yield `${value}.length >= ${schema.minLength}`;
|
|
379
|
-
if (ValueGuard.IsNumber(schema.maxLength))
|
|
393
|
+
if ((0, guard_1.IsNumber)(schema.maxLength))
|
|
380
394
|
yield `${value}.length <= ${schema.maxLength}`;
|
|
395
|
+
if ((0, guard_1.IsNumber)(schema.minLength))
|
|
396
|
+
yield `${value}.length >= ${schema.minLength}`;
|
|
381
397
|
if (schema.pattern !== undefined) {
|
|
382
398
|
const variable = CreateVariable(`${new RegExp(schema.pattern)};`);
|
|
383
399
|
yield `${variable}.test(${value})`;
|
|
@@ -395,8 +411,8 @@ var TypeCompiler;
|
|
|
395
411
|
yield `${variable}.test(${value})`;
|
|
396
412
|
}
|
|
397
413
|
function* TThis(schema, references, value) {
|
|
398
|
-
|
|
399
|
-
yield `${
|
|
414
|
+
// Note: This types are assured to be hoisted prior to this call. Just yield the function.
|
|
415
|
+
yield `${CreateFunctionName(schema.$ref)}(${value})`;
|
|
400
416
|
}
|
|
401
417
|
function* TTuple(schema, references, value) {
|
|
402
418
|
yield `Array.isArray(${value})`;
|
|
@@ -417,16 +433,16 @@ var TypeCompiler;
|
|
|
417
433
|
}
|
|
418
434
|
function* TUint8Array(schema, references, value) {
|
|
419
435
|
yield `${value} instanceof Uint8Array`;
|
|
420
|
-
if (
|
|
436
|
+
if ((0, guard_1.IsNumber)(schema.maxByteLength))
|
|
421
437
|
yield `(${value}.length <= ${schema.maxByteLength})`;
|
|
422
|
-
if (
|
|
438
|
+
if ((0, guard_1.IsNumber)(schema.minByteLength))
|
|
423
439
|
yield `(${value}.length >= ${schema.minByteLength})`;
|
|
424
440
|
}
|
|
425
441
|
function* TUnknown(schema, references, value) {
|
|
426
442
|
yield 'true';
|
|
427
443
|
}
|
|
428
444
|
function* TVoid(schema, references, value) {
|
|
429
|
-
yield
|
|
445
|
+
yield Policy.IsVoidLike(value);
|
|
430
446
|
}
|
|
431
447
|
function* TKind(schema, references, value) {
|
|
432
448
|
const instance = state.instances.size;
|
|
@@ -434,12 +450,12 @@ var TypeCompiler;
|
|
|
434
450
|
yield `kind('${schema[Types.Kind]}', ${instance}, ${value})`;
|
|
435
451
|
}
|
|
436
452
|
function* Visit(schema, references, value, useHoisting = true) {
|
|
437
|
-
const references_ =
|
|
453
|
+
const references_ = (0, guard_1.IsString)(schema.$id) ? [...references, schema] : references;
|
|
438
454
|
const schema_ = schema;
|
|
439
455
|
// ----------------------------------------------------------------------------------
|
|
440
456
|
// Hoisting
|
|
441
457
|
// ----------------------------------------------------------------------------------
|
|
442
|
-
if (useHoisting &&
|
|
458
|
+
if (useHoisting && (0, guard_1.IsString)(schema.$id)) {
|
|
443
459
|
const functionName = CreateFunctionName(schema.$id);
|
|
444
460
|
if (state.functions.has(functionName)) {
|
|
445
461
|
return yield `${functionName}(${value})`;
|
|
@@ -450,9 +466,6 @@ var TypeCompiler;
|
|
|
450
466
|
return yield `${functionName}(${value})`;
|
|
451
467
|
}
|
|
452
468
|
}
|
|
453
|
-
// ----------------------------------------------------------------------------------
|
|
454
|
-
// Types
|
|
455
|
-
// ----------------------------------------------------------------------------------
|
|
456
469
|
switch (schema_[Types.Kind]) {
|
|
457
470
|
case 'Any':
|
|
458
471
|
return yield* TAny(schema_, references_, value);
|
|
@@ -568,17 +581,17 @@ var TypeCompiler;
|
|
|
568
581
|
const functions = [...state.functions.values()];
|
|
569
582
|
const variables = [...state.variables.values()];
|
|
570
583
|
// prettier-ignore
|
|
571
|
-
const checkFunction =
|
|
584
|
+
const checkFunction = (0, guard_1.IsString)(schema.$id) // ensure top level schemas with $id's are hoisted
|
|
572
585
|
? `return function check(${parameter})${returns} {\n return ${CreateFunctionName(schema.$id)}(value)\n}`
|
|
573
586
|
: `return ${functionCode}`;
|
|
574
587
|
return [...variables, ...functions, checkFunction].join('\n');
|
|
575
588
|
}
|
|
576
|
-
/**
|
|
589
|
+
/** Generates the code used to assert this type and returns it as a string */
|
|
577
590
|
function Code(...args) {
|
|
578
591
|
const defaults = { language: 'javascript' };
|
|
579
592
|
// prettier-ignore
|
|
580
|
-
const [schema, references, options] = (args.length === 2 &&
|
|
581
|
-
args.length === 2 && !
|
|
593
|
+
const [schema, references, options] = (args.length === 2 && (0, guard_1.IsArray)(args[1]) ? [args[0], args[1], defaults] :
|
|
594
|
+
args.length === 2 && !(0, guard_1.IsArray)(args[1]) ? [args[0], [], args[1]] :
|
|
582
595
|
args.length === 3 ? [args[0], args[1], args[2]] :
|
|
583
596
|
args.length === 1 ? [args[0], [], defaults] :
|
|
584
597
|
[null, [], defaults]);
|
|
@@ -595,7 +608,7 @@ var TypeCompiler;
|
|
|
595
608
|
return Build(schema, references, options);
|
|
596
609
|
}
|
|
597
610
|
TypeCompiler.Code = Code;
|
|
598
|
-
/** Compiles
|
|
611
|
+
/** Compiles a TypeBox type for optimal runtime type checking. Types must be valid TypeBox types of TSchema */
|
|
599
612
|
function Compile(schema, references = []) {
|
|
600
613
|
const generatedCode = Code(schema, references, { language: 'javascript' });
|
|
601
614
|
const compiledFunction = globalThis.Function('kind', 'format', 'hash', generatedCode);
|
|
@@ -603,8 +616,8 @@ var TypeCompiler;
|
|
|
603
616
|
function typeRegistryFunction(kind, instance, value) {
|
|
604
617
|
if (!Types.TypeRegistry.Has(kind) || !instances.has(instance))
|
|
605
618
|
return false;
|
|
606
|
-
const schema = instances.get(instance);
|
|
607
619
|
const checkFunc = Types.TypeRegistry.Get(kind);
|
|
620
|
+
const schema = instances.get(instance);
|
|
608
621
|
return checkFunc(schema, value);
|
|
609
622
|
}
|
|
610
623
|
function formatRegistryFunction(format, value) {
|
|
@@ -613,10 +626,10 @@ var TypeCompiler;
|
|
|
613
626
|
const checkFunc = Types.FormatRegistry.Get(format);
|
|
614
627
|
return checkFunc(value);
|
|
615
628
|
}
|
|
616
|
-
function
|
|
617
|
-
return
|
|
629
|
+
function hashFunction(value) {
|
|
630
|
+
return (0, hash_1.Hash)(value);
|
|
618
631
|
}
|
|
619
|
-
const checkFunction = compiledFunction(typeRegistryFunction, formatRegistryFunction,
|
|
632
|
+
const checkFunction = compiledFunction(typeRegistryFunction, formatRegistryFunction, hashFunction);
|
|
620
633
|
return new TypeCheck(schema, references, checkFunction, generatedCode);
|
|
621
634
|
}
|
|
622
635
|
TypeCompiler.Compile = Compile;
|
package/compiler/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { ValueError, ValueErrorType } from '../errors/index';
|
|
1
|
+
export { ValueError, ValueErrorType, ValueErrorIterator } from '../errors/index';
|
|
2
2
|
export * from './compiler';
|
package/compiler/index.js
CHANGED
|
@@ -41,7 +41,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
41
41
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
42
42
|
};
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.ValueErrorType = void 0;
|
|
44
|
+
exports.ValueErrorIterator = exports.ValueErrorType = void 0;
|
|
45
45
|
var index_1 = require("../errors/index");
|
|
46
46
|
Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return index_1.ValueErrorType; } });
|
|
47
|
+
Object.defineProperty(exports, "ValueErrorIterator", { enumerable: true, get: function () { return index_1.ValueErrorIterator; } });
|
|
47
48
|
__exportStar(require("./compiler"), exports);
|
package/errors/errors.d.ts
CHANGED
|
@@ -1,69 +1,68 @@
|
|
|
1
1
|
import * as Types from '../typebox';
|
|
2
2
|
export declare enum ValueErrorType {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
ArrayContains = 0,
|
|
4
|
+
ArrayMaxContains = 1,
|
|
5
5
|
ArrayMaxItems = 2,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
ArrayMinContains = 3,
|
|
7
|
+
ArrayMinItems = 4,
|
|
8
|
+
ArrayUniqueItems = 5,
|
|
9
|
+
Array = 6,
|
|
10
10
|
AsyncIterator = 7,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
BigIntExclusiveMaximum = 8,
|
|
12
|
+
BigIntExclusiveMinimum = 9,
|
|
13
|
+
BigIntMaximum = 10,
|
|
14
|
+
BigIntMinimum = 11,
|
|
15
|
+
BigIntMultipleOf = 12,
|
|
16
|
+
BigInt = 13,
|
|
17
17
|
Boolean = 14,
|
|
18
|
-
|
|
18
|
+
DateExclusiveMaximumTimestamp = 15,
|
|
19
19
|
DateExclusiveMinimumTimestamp = 16,
|
|
20
|
-
|
|
20
|
+
DateMaximumTimestamp = 17,
|
|
21
21
|
DateMinimumTimestamp = 18,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
DateMultipleOfTimestamp = 19,
|
|
23
|
+
Date = 20,
|
|
24
|
+
Function = 21,
|
|
25
|
+
IntegerExclusiveMaximum = 22,
|
|
26
26
|
IntegerExclusiveMinimum = 23,
|
|
27
|
-
|
|
27
|
+
IntegerMaximum = 24,
|
|
28
28
|
IntegerMinimum = 25,
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
IntegerMultipleOf = 26,
|
|
30
|
+
Integer = 27,
|
|
31
31
|
IntersectUnevaluatedProperties = 28,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
Intersect = 29,
|
|
33
|
+
Iterator = 30,
|
|
34
|
+
Kind = 31,
|
|
35
|
+
Literal = 32,
|
|
36
|
+
Never = 33,
|
|
37
|
+
Not = 34,
|
|
38
|
+
Null = 35,
|
|
39
|
+
NumberExclusiveMaximum = 36,
|
|
40
|
+
NumberExclusiveMinimum = 37,
|
|
41
|
+
NumberMaximum = 38,
|
|
42
|
+
NumberMinimum = 39,
|
|
43
|
+
NumberMultipleOf = 40,
|
|
44
|
+
Number = 41,
|
|
45
|
+
ObjectAdditionalProperties = 42,
|
|
46
|
+
ObjectMaxProperties = 43,
|
|
47
|
+
ObjectMinProperties = 44,
|
|
48
|
+
ObjectRequiredProperty = 45,
|
|
49
|
+
Object = 46,
|
|
50
|
+
Promise = 47,
|
|
51
|
+
StringFormatUnknown = 48,
|
|
52
|
+
StringFormat = 49,
|
|
53
53
|
StringMaxLength = 50,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
StringMinLength = 51,
|
|
55
|
+
StringPattern = 52,
|
|
56
|
+
String = 53,
|
|
57
57
|
Symbol = 54,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
TupleLength = 55,
|
|
59
|
+
Tuple = 56,
|
|
60
|
+
Uint8ArrayMaxByteLength = 57,
|
|
61
|
+
Uint8ArrayMinByteLength = 58,
|
|
62
62
|
Uint8Array = 59,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Void = 62
|
|
66
|
-
Kind = 63
|
|
63
|
+
Undefined = 60,
|
|
64
|
+
Union = 61,
|
|
65
|
+
Void = 62
|
|
67
66
|
}
|
|
68
67
|
export interface ValueError {
|
|
69
68
|
type: ValueErrorType;
|
|
@@ -72,6 +71,10 @@ export interface ValueError {
|
|
|
72
71
|
value: unknown;
|
|
73
72
|
message: string;
|
|
74
73
|
}
|
|
74
|
+
export declare class ValueErrorsUnknownTypeError extends Types.TypeBoxError {
|
|
75
|
+
readonly schema: Types.TSchema;
|
|
76
|
+
constructor(schema: Types.TSchema);
|
|
77
|
+
}
|
|
75
78
|
export declare class ValueErrorIterator {
|
|
76
79
|
private readonly iterator;
|
|
77
80
|
constructor(iterator: IterableIterator<ValueError>);
|
|
@@ -79,14 +82,6 @@ export declare class ValueErrorIterator {
|
|
|
79
82
|
/** Returns the first value error or undefined if no errors */
|
|
80
83
|
First(): ValueError | undefined;
|
|
81
84
|
}
|
|
82
|
-
export declare class ValueErrorsUnknownTypeError extends Error {
|
|
83
|
-
readonly schema: Types.TSchema;
|
|
84
|
-
constructor(schema: Types.TSchema);
|
|
85
|
-
}
|
|
86
|
-
export declare class ValueErrorsDereferenceError extends Error {
|
|
87
|
-
readonly schema: Types.TRef | Types.TThis;
|
|
88
|
-
constructor(schema: Types.TRef | Types.TThis);
|
|
89
|
-
}
|
|
90
85
|
/** Returns an iterator for each error in this value. */
|
|
91
86
|
export declare function Errors<T extends Types.TSchema>(schema: T, references: Types.TSchema[], value: unknown): ValueErrorIterator;
|
|
92
87
|
/** Returns an iterator for each error in this value. */
|