@sinclair/typebox 0.30.3 → 0.31.0-dev-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiler/compiler.d.ts +22 -14
- package/compiler/compiler.js +135 -107
- 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 +592 -511
- 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,7 +1,8 @@
|
|
|
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
|
+
#private;
|
|
5
6
|
private readonly schema;
|
|
6
7
|
private readonly references;
|
|
7
8
|
private readonly checkFunc;
|
|
@@ -10,32 +11,39 @@ export declare class TypeCheck<T extends Types.TSchema> {
|
|
|
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
|
@@ -26,13 +26,27 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
26
26
|
THE SOFTWARE.
|
|
27
27
|
|
|
28
28
|
---------------------------------------------------------------------------*/
|
|
29
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
30
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
31
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
32
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
33
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
34
|
+
};
|
|
35
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
36
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
37
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
38
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
39
|
+
};
|
|
40
|
+
var _TypeCheck_hasTransform;
|
|
29
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.TypeCompiler = exports.
|
|
42
|
+
exports.TypeCompiler = exports.Policy = exports.TypeCompilerTypeGuardError = exports.TypeCompilerUnknownTypeError = exports.TypeCheck = void 0;
|
|
43
|
+
const transform_1 = require("../value/transform");
|
|
44
|
+
const guard_1 = require("../value/guard");
|
|
45
|
+
const errors_1 = require("../errors/errors");
|
|
31
46
|
const index_1 = require("../system/index");
|
|
47
|
+
const deref_1 = require("../value/deref");
|
|
48
|
+
const hash_1 = require("../value/hash");
|
|
32
49
|
const Types = require("../typebox");
|
|
33
|
-
const ValueErrors = require("../errors/index");
|
|
34
|
-
const ValueHash = require("../value/hash");
|
|
35
|
-
const ValueGuard = require("../value/guard");
|
|
36
50
|
// -------------------------------------------------------------------
|
|
37
51
|
// TypeCheck
|
|
38
52
|
// -------------------------------------------------------------------
|
|
@@ -42,6 +56,8 @@ class TypeCheck {
|
|
|
42
56
|
this.references = references;
|
|
43
57
|
this.checkFunc = checkFunc;
|
|
44
58
|
this.code = code;
|
|
59
|
+
_TypeCheck_hasTransform.set(this, void 0);
|
|
60
|
+
__classPrivateFieldSet(this, _TypeCheck_hasTransform, transform_1.HasTransform.Has(schema, references), "f");
|
|
45
61
|
}
|
|
46
62
|
/** Returns the generated assertion code used to validate this type. */
|
|
47
63
|
Code() {
|
|
@@ -49,14 +65,28 @@ class TypeCheck {
|
|
|
49
65
|
}
|
|
50
66
|
/** Returns an iterator for each error in this value. */
|
|
51
67
|
Errors(value) {
|
|
52
|
-
return
|
|
68
|
+
return (0, errors_1.Errors)(this.schema, this.references, value);
|
|
53
69
|
}
|
|
54
70
|
/** Returns true if the value matches the compiled type. */
|
|
55
71
|
Check(value) {
|
|
56
72
|
return this.checkFunc(value);
|
|
57
73
|
}
|
|
74
|
+
/** Decodes a value or throws if error */
|
|
75
|
+
Decode(value) {
|
|
76
|
+
if (!this.checkFunc(value))
|
|
77
|
+
throw new transform_1.TransformDecodeCheckError(this.schema, value, this.Errors(value).First());
|
|
78
|
+
return __classPrivateFieldGet(this, _TypeCheck_hasTransform, "f") ? transform_1.DecodeTransform.Decode(this.schema, this.references, value, (_, __, value) => this.Check(value)) : value;
|
|
79
|
+
}
|
|
80
|
+
/** Encodes a value or throws if error */
|
|
81
|
+
Encode(value) {
|
|
82
|
+
const encoded = __classPrivateFieldGet(this, _TypeCheck_hasTransform, "f") ? transform_1.EncodeTransform.Encode(this.schema, this.references, value, (_, __, value) => this.Check(value)) : value;
|
|
83
|
+
if (!this.checkFunc(encoded))
|
|
84
|
+
throw new transform_1.TransformEncodeCheckError(this.schema, value, this.Errors(value).First());
|
|
85
|
+
return encoded;
|
|
86
|
+
}
|
|
58
87
|
}
|
|
59
88
|
exports.TypeCheck = TypeCheck;
|
|
89
|
+
_TypeCheck_hasTransform = new WeakMap();
|
|
60
90
|
// -------------------------------------------------------------------
|
|
61
91
|
// Character
|
|
62
92
|
// -------------------------------------------------------------------
|
|
@@ -131,27 +161,48 @@ var Identifier;
|
|
|
131
161
|
// -------------------------------------------------------------------
|
|
132
162
|
// Errors
|
|
133
163
|
// -------------------------------------------------------------------
|
|
134
|
-
class TypeCompilerUnknownTypeError extends
|
|
164
|
+
class TypeCompilerUnknownTypeError extends Types.TypeBoxError {
|
|
135
165
|
constructor(schema) {
|
|
136
|
-
super('
|
|
166
|
+
super('Unknown type');
|
|
137
167
|
this.schema = schema;
|
|
138
168
|
}
|
|
139
169
|
}
|
|
140
170
|
exports.TypeCompilerUnknownTypeError = TypeCompilerUnknownTypeError;
|
|
141
|
-
class
|
|
171
|
+
class TypeCompilerTypeGuardError extends Types.TypeBoxError {
|
|
142
172
|
constructor(schema) {
|
|
143
|
-
super(
|
|
144
|
-
this.schema = schema;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
exports.TypeCompilerDereferenceError = TypeCompilerDereferenceError;
|
|
148
|
-
class TypeCompilerTypeGuardError extends Error {
|
|
149
|
-
constructor(schema) {
|
|
150
|
-
super('TypeCompiler: Preflight validation check failed to guard for the given schema');
|
|
173
|
+
super('Preflight validation check failed to guard for the given schema');
|
|
151
174
|
this.schema = schema;
|
|
152
175
|
}
|
|
153
176
|
}
|
|
154
177
|
exports.TypeCompilerTypeGuardError = TypeCompilerTypeGuardError;
|
|
178
|
+
// -------------------------------------------------------------------
|
|
179
|
+
// Policy
|
|
180
|
+
// -------------------------------------------------------------------
|
|
181
|
+
var Policy;
|
|
182
|
+
(function (Policy) {
|
|
183
|
+
function IsExactOptionalProperty(value, key, expression) {
|
|
184
|
+
return index_1.TypeSystemPolicy.ExactOptionalPropertyTypes ? `('${key}' in ${value} ? ${expression} : true)` : `(${MemberExpression.Encode(value, key)} !== undefined ? ${expression} : true)`;
|
|
185
|
+
}
|
|
186
|
+
Policy.IsExactOptionalProperty = IsExactOptionalProperty;
|
|
187
|
+
function IsObjectLike(value) {
|
|
188
|
+
return !index_1.TypeSystemPolicy.AllowArrayObject ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))` : `(typeof ${value} === 'object' && ${value} !== null)`;
|
|
189
|
+
}
|
|
190
|
+
Policy.IsObjectLike = IsObjectLike;
|
|
191
|
+
function IsRecordLike(value) {
|
|
192
|
+
return !index_1.TypeSystemPolicy.AllowArrayObject
|
|
193
|
+
? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}) && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`
|
|
194
|
+
: `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))`;
|
|
195
|
+
}
|
|
196
|
+
Policy.IsRecordLike = IsRecordLike;
|
|
197
|
+
function IsNumberLike(value) {
|
|
198
|
+
return !index_1.TypeSystemPolicy.AllowNaN ? `(typeof ${value} === 'number' && Number.isFinite(${value}))` : `typeof ${value} === 'number'`;
|
|
199
|
+
}
|
|
200
|
+
Policy.IsNumberLike = IsNumberLike;
|
|
201
|
+
function IsVoidLike(value) {
|
|
202
|
+
return index_1.TypeSystemPolicy.AllowNullVoid ? `(${value} === undefined || ${value} === null)` : `${value} === undefined`;
|
|
203
|
+
}
|
|
204
|
+
Policy.IsVoidLike = IsVoidLike;
|
|
205
|
+
})(Policy || (exports.Policy = Policy = {}));
|
|
155
206
|
/** Compiles Types for Runtime Type Checking */
|
|
156
207
|
var TypeCompiler;
|
|
157
208
|
(function (TypeCompiler) {
|
|
@@ -162,26 +213,6 @@ var TypeCompiler;
|
|
|
162
213
|
return schema[Types.Kind] === 'Any' || schema[Types.Kind] === 'Unknown';
|
|
163
214
|
}
|
|
164
215
|
// -------------------------------------------------------------------
|
|
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
216
|
// Types
|
|
186
217
|
// -------------------------------------------------------------------
|
|
187
218
|
function* TAny(schema, references, value) {
|
|
@@ -190,17 +221,17 @@ var TypeCompiler;
|
|
|
190
221
|
function* TArray(schema, references, value) {
|
|
191
222
|
yield `Array.isArray(${value})`;
|
|
192
223
|
const [parameter, accumulator] = [CreateParameter('value', 'any'), CreateParameter('acc', 'number')];
|
|
193
|
-
if (
|
|
194
|
-
yield `${value}.length >= ${schema.minItems}`;
|
|
195
|
-
if (ValueGuard.IsNumber(schema.maxItems))
|
|
224
|
+
if ((0, guard_1.IsNumber)(schema.maxItems))
|
|
196
225
|
yield `${value}.length <= ${schema.maxItems}`;
|
|
226
|
+
if ((0, guard_1.IsNumber)(schema.minItems))
|
|
227
|
+
yield `${value}.length >= ${schema.minItems}`;
|
|
197
228
|
const elementExpression = CreateExpression(schema.items, references, 'value');
|
|
198
229
|
yield `${value}.every((${parameter}) => ${elementExpression})`;
|
|
199
|
-
if (Types.TypeGuard.TSchema(schema.contains) ||
|
|
230
|
+
if (Types.TypeGuard.TSchema(schema.contains) || (0, guard_1.IsNumber)(schema.minContains) || (0, guard_1.IsNumber)(schema.maxContains)) {
|
|
200
231
|
const containsSchema = Types.TypeGuard.TSchema(schema.contains) ? schema.contains : Types.Type.Never();
|
|
201
232
|
const checkExpression = CreateExpression(containsSchema, references, 'value');
|
|
202
|
-
const checkMinContains =
|
|
203
|
-
const checkMaxContains =
|
|
233
|
+
const checkMinContains = (0, guard_1.IsNumber)(schema.minContains) ? [`(count >= ${schema.minContains})`] : [];
|
|
234
|
+
const checkMaxContains = (0, guard_1.IsNumber)(schema.maxContains) ? [`(count <= ${schema.maxContains})`] : [];
|
|
204
235
|
const checkCount = `const count = ${value}.reduce((${accumulator}, ${parameter}) => ${checkExpression} ? acc + 1 : acc, 0)`;
|
|
205
236
|
const check = [`(count > 0)`, ...checkMinContains, ...checkMaxContains].join(' && ');
|
|
206
237
|
yield `((${parameter}) => { ${checkCount}; return ${check}})(${value})`;
|
|
@@ -216,16 +247,16 @@ var TypeCompiler;
|
|
|
216
247
|
}
|
|
217
248
|
function* TBigInt(schema, references, value) {
|
|
218
249
|
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))
|
|
250
|
+
if ((0, guard_1.IsBigInt)(schema.exclusiveMaximum))
|
|
224
251
|
yield `${value} < BigInt(${schema.exclusiveMaximum})`;
|
|
225
|
-
if (
|
|
226
|
-
yield `${value}
|
|
227
|
-
if (
|
|
252
|
+
if ((0, guard_1.IsBigInt)(schema.exclusiveMinimum))
|
|
253
|
+
yield `${value} > BigInt(${schema.exclusiveMinimum})`;
|
|
254
|
+
if ((0, guard_1.IsBigInt)(schema.maximum))
|
|
228
255
|
yield `${value} <= BigInt(${schema.maximum})`;
|
|
256
|
+
if ((0, guard_1.IsBigInt)(schema.minimum))
|
|
257
|
+
yield `${value} >= BigInt(${schema.minimum})`;
|
|
258
|
+
if ((0, guard_1.IsBigInt)(schema.multipleOf))
|
|
259
|
+
yield `(${value} % BigInt(${schema.multipleOf})) === 0`;
|
|
229
260
|
}
|
|
230
261
|
function* TBoolean(schema, references, value) {
|
|
231
262
|
yield `(typeof ${value} === 'boolean')`;
|
|
@@ -235,30 +266,32 @@ var TypeCompiler;
|
|
|
235
266
|
}
|
|
236
267
|
function* TDate(schema, references, value) {
|
|
237
268
|
yield `(${value} instanceof Date) && Number.isFinite(${value}.getTime())`;
|
|
238
|
-
if (
|
|
239
|
-
yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`;
|
|
240
|
-
if (ValueGuard.IsNumber(schema.exclusiveMaximumTimestamp))
|
|
269
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMaximumTimestamp))
|
|
241
270
|
yield `${value}.getTime() < ${schema.exclusiveMaximumTimestamp}`;
|
|
242
|
-
if (
|
|
243
|
-
yield `${value}.getTime()
|
|
244
|
-
if (
|
|
271
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMinimumTimestamp))
|
|
272
|
+
yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}`;
|
|
273
|
+
if ((0, guard_1.IsNumber)(schema.maximumTimestamp))
|
|
245
274
|
yield `${value}.getTime() <= ${schema.maximumTimestamp}`;
|
|
275
|
+
if ((0, guard_1.IsNumber)(schema.minimumTimestamp))
|
|
276
|
+
yield `${value}.getTime() >= ${schema.minimumTimestamp}`;
|
|
277
|
+
if ((0, guard_1.IsNumber)(schema.multipleOfTimestamp))
|
|
278
|
+
yield `(${value}.getTime() % ${schema.multipleOfTimestamp}) === 0`;
|
|
246
279
|
}
|
|
247
280
|
function* TFunction(schema, references, value) {
|
|
248
281
|
yield `(typeof ${value} === 'function')`;
|
|
249
282
|
}
|
|
250
283
|
function* TInteger(schema, references, value) {
|
|
251
284
|
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))
|
|
285
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMaximum))
|
|
257
286
|
yield `${value} < ${schema.exclusiveMaximum}`;
|
|
258
|
-
if (
|
|
259
|
-
yield `${value}
|
|
260
|
-
if (
|
|
287
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMinimum))
|
|
288
|
+
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
289
|
+
if ((0, guard_1.IsNumber)(schema.maximum))
|
|
261
290
|
yield `${value} <= ${schema.maximum}`;
|
|
291
|
+
if ((0, guard_1.IsNumber)(schema.minimum))
|
|
292
|
+
yield `${value} >= ${schema.minimum}`;
|
|
293
|
+
if ((0, guard_1.IsNumber)(schema.multipleOf))
|
|
294
|
+
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
262
295
|
}
|
|
263
296
|
function* TIntersect(schema, references, value) {
|
|
264
297
|
const check1 = schema.allOf.map((schema) => CreateExpression(schema, references, value)).join(' && ');
|
|
@@ -298,23 +331,23 @@ var TypeCompiler;
|
|
|
298
331
|
yield `(${value} === null)`;
|
|
299
332
|
}
|
|
300
333
|
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))
|
|
334
|
+
yield Policy.IsNumberLike(value);
|
|
335
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMaximum))
|
|
307
336
|
yield `${value} < ${schema.exclusiveMaximum}`;
|
|
308
|
-
if (
|
|
309
|
-
yield `${value}
|
|
310
|
-
if (
|
|
337
|
+
if ((0, guard_1.IsNumber)(schema.exclusiveMinimum))
|
|
338
|
+
yield `${value} > ${schema.exclusiveMinimum}`;
|
|
339
|
+
if ((0, guard_1.IsNumber)(schema.maximum))
|
|
311
340
|
yield `${value} <= ${schema.maximum}`;
|
|
341
|
+
if ((0, guard_1.IsNumber)(schema.minimum))
|
|
342
|
+
yield `${value} >= ${schema.minimum}`;
|
|
343
|
+
if ((0, guard_1.IsNumber)(schema.multipleOf))
|
|
344
|
+
yield `(${value} % ${schema.multipleOf}) === 0`;
|
|
312
345
|
}
|
|
313
346
|
function* TObject(schema, references, value) {
|
|
314
|
-
yield
|
|
315
|
-
if (
|
|
347
|
+
yield Policy.IsObjectLike(value);
|
|
348
|
+
if ((0, guard_1.IsNumber)(schema.minProperties))
|
|
316
349
|
yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}`;
|
|
317
|
-
if (
|
|
350
|
+
if ((0, guard_1.IsNumber)(schema.maxProperties))
|
|
318
351
|
yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}`;
|
|
319
352
|
const knownKeys = Object.getOwnPropertyNames(schema.properties);
|
|
320
353
|
for (const knownKey of knownKeys) {
|
|
@@ -327,7 +360,7 @@ var TypeCompiler;
|
|
|
327
360
|
}
|
|
328
361
|
else {
|
|
329
362
|
const expression = CreateExpression(property, references, memberExpression);
|
|
330
|
-
yield IsExactOptionalProperty(value, knownKey, expression);
|
|
363
|
+
yield Policy.IsExactOptionalProperty(value, knownKey, expression);
|
|
331
364
|
}
|
|
332
365
|
}
|
|
333
366
|
if (schema.additionalProperties === false) {
|
|
@@ -349,10 +382,10 @@ var TypeCompiler;
|
|
|
349
382
|
yield `(typeof value === 'object' && typeof ${value}.then === 'function')`;
|
|
350
383
|
}
|
|
351
384
|
function* TRecord(schema, references, value) {
|
|
352
|
-
yield
|
|
353
|
-
if (
|
|
385
|
+
yield Policy.IsRecordLike(value);
|
|
386
|
+
if ((0, guard_1.IsNumber)(schema.minProperties))
|
|
354
387
|
yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}`;
|
|
355
|
-
if (
|
|
388
|
+
if ((0, guard_1.IsNumber)(schema.maxProperties))
|
|
356
389
|
yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}`;
|
|
357
390
|
const [patternKey, patternSchema] = Object.entries(schema.patternProperties)[0];
|
|
358
391
|
const variable = CreateVariable(`new RegExp(/${patternKey}/)`);
|
|
@@ -362,10 +395,7 @@ var TypeCompiler;
|
|
|
362
395
|
yield `(Object.entries(${value}).every(([key, value]) => ${expression}))`;
|
|
363
396
|
}
|
|
364
397
|
function* TRef(schema, references, value) {
|
|
365
|
-
const
|
|
366
|
-
if (index === -1)
|
|
367
|
-
throw new TypeCompilerDereferenceError(schema);
|
|
368
|
-
const target = references[index];
|
|
398
|
+
const target = (0, deref_1.Deref)(schema, references);
|
|
369
399
|
// Reference: If we have seen this reference before we can just yield and return the function call.
|
|
370
400
|
// If this isn't the case we defer to visit to generate and set the function for subsequent passes.
|
|
371
401
|
if (state.functions.has(schema.$ref))
|
|
@@ -374,10 +404,10 @@ var TypeCompiler;
|
|
|
374
404
|
}
|
|
375
405
|
function* TString(schema, references, value) {
|
|
376
406
|
yield `(typeof ${value} === 'string')`;
|
|
377
|
-
if (
|
|
378
|
-
yield `${value}.length >= ${schema.minLength}`;
|
|
379
|
-
if (ValueGuard.IsNumber(schema.maxLength))
|
|
407
|
+
if ((0, guard_1.IsNumber)(schema.maxLength))
|
|
380
408
|
yield `${value}.length <= ${schema.maxLength}`;
|
|
409
|
+
if ((0, guard_1.IsNumber)(schema.minLength))
|
|
410
|
+
yield `${value}.length >= ${schema.minLength}`;
|
|
381
411
|
if (schema.pattern !== undefined) {
|
|
382
412
|
const variable = CreateVariable(`${new RegExp(schema.pattern)};`);
|
|
383
413
|
yield `${variable}.test(${value})`;
|
|
@@ -395,8 +425,8 @@ var TypeCompiler;
|
|
|
395
425
|
yield `${variable}.test(${value})`;
|
|
396
426
|
}
|
|
397
427
|
function* TThis(schema, references, value) {
|
|
398
|
-
|
|
399
|
-
yield `${
|
|
428
|
+
// Note: This types are assured to be hoisted prior to this call. Just yield the function.
|
|
429
|
+
yield `${CreateFunctionName(schema.$ref)}(${value})`;
|
|
400
430
|
}
|
|
401
431
|
function* TTuple(schema, references, value) {
|
|
402
432
|
yield `Array.isArray(${value})`;
|
|
@@ -417,16 +447,16 @@ var TypeCompiler;
|
|
|
417
447
|
}
|
|
418
448
|
function* TUint8Array(schema, references, value) {
|
|
419
449
|
yield `${value} instanceof Uint8Array`;
|
|
420
|
-
if (
|
|
450
|
+
if ((0, guard_1.IsNumber)(schema.maxByteLength))
|
|
421
451
|
yield `(${value}.length <= ${schema.maxByteLength})`;
|
|
422
|
-
if (
|
|
452
|
+
if ((0, guard_1.IsNumber)(schema.minByteLength))
|
|
423
453
|
yield `(${value}.length >= ${schema.minByteLength})`;
|
|
424
454
|
}
|
|
425
455
|
function* TUnknown(schema, references, value) {
|
|
426
456
|
yield 'true';
|
|
427
457
|
}
|
|
428
458
|
function* TVoid(schema, references, value) {
|
|
429
|
-
yield
|
|
459
|
+
yield Policy.IsVoidLike(value);
|
|
430
460
|
}
|
|
431
461
|
function* TKind(schema, references, value) {
|
|
432
462
|
const instance = state.instances.size;
|
|
@@ -434,12 +464,12 @@ var TypeCompiler;
|
|
|
434
464
|
yield `kind('${schema[Types.Kind]}', ${instance}, ${value})`;
|
|
435
465
|
}
|
|
436
466
|
function* Visit(schema, references, value, useHoisting = true) {
|
|
437
|
-
const references_ =
|
|
467
|
+
const references_ = (0, guard_1.IsString)(schema.$id) ? [...references, schema] : references;
|
|
438
468
|
const schema_ = schema;
|
|
439
469
|
// ----------------------------------------------------------------------------------
|
|
440
470
|
// Hoisting
|
|
441
471
|
// ----------------------------------------------------------------------------------
|
|
442
|
-
if (useHoisting &&
|
|
472
|
+
if (useHoisting && (0, guard_1.IsString)(schema.$id)) {
|
|
443
473
|
const functionName = CreateFunctionName(schema.$id);
|
|
444
474
|
if (state.functions.has(functionName)) {
|
|
445
475
|
return yield `${functionName}(${value})`;
|
|
@@ -450,9 +480,6 @@ var TypeCompiler;
|
|
|
450
480
|
return yield `${functionName}(${value})`;
|
|
451
481
|
}
|
|
452
482
|
}
|
|
453
|
-
// ----------------------------------------------------------------------------------
|
|
454
|
-
// Types
|
|
455
|
-
// ----------------------------------------------------------------------------------
|
|
456
483
|
switch (schema_[Types.Kind]) {
|
|
457
484
|
case 'Any':
|
|
458
485
|
return yield* TAny(schema_, references_, value);
|
|
@@ -568,17 +595,17 @@ var TypeCompiler;
|
|
|
568
595
|
const functions = [...state.functions.values()];
|
|
569
596
|
const variables = [...state.variables.values()];
|
|
570
597
|
// prettier-ignore
|
|
571
|
-
const checkFunction =
|
|
598
|
+
const checkFunction = (0, guard_1.IsString)(schema.$id) // ensure top level schemas with $id's are hoisted
|
|
572
599
|
? `return function check(${parameter})${returns} {\n return ${CreateFunctionName(schema.$id)}(value)\n}`
|
|
573
600
|
: `return ${functionCode}`;
|
|
574
601
|
return [...variables, ...functions, checkFunction].join('\n');
|
|
575
602
|
}
|
|
576
|
-
/**
|
|
603
|
+
/** Generates the code used to assert this type and returns it as a string */
|
|
577
604
|
function Code(...args) {
|
|
578
605
|
const defaults = { language: 'javascript' };
|
|
579
606
|
// prettier-ignore
|
|
580
|
-
const [schema, references, options] = (args.length === 2 &&
|
|
581
|
-
args.length === 2 && !
|
|
607
|
+
const [schema, references, options] = (args.length === 2 && (0, guard_1.IsArray)(args[1]) ? [args[0], args[1], defaults] :
|
|
608
|
+
args.length === 2 && !(0, guard_1.IsArray)(args[1]) ? [args[0], [], args[1]] :
|
|
582
609
|
args.length === 3 ? [args[0], args[1], args[2]] :
|
|
583
610
|
args.length === 1 ? [args[0], [], defaults] :
|
|
584
611
|
[null, [], defaults]);
|
|
@@ -595,15 +622,16 @@ var TypeCompiler;
|
|
|
595
622
|
return Build(schema, references, options);
|
|
596
623
|
}
|
|
597
624
|
TypeCompiler.Code = Code;
|
|
598
|
-
/** Compiles
|
|
625
|
+
/** Compiles a TypeBox type for optimal runtime type checking. Types must be valid TypeBox types of TSchema */
|
|
599
626
|
function Compile(schema, references = []) {
|
|
600
627
|
const generatedCode = Code(schema, references, { language: 'javascript' });
|
|
601
628
|
const compiledFunction = globalThis.Function('kind', 'format', 'hash', generatedCode);
|
|
629
|
+
const instances = new Map(state.instances);
|
|
602
630
|
function typeRegistryFunction(kind, instance, value) {
|
|
603
|
-
if (!Types.TypeRegistry.Has(kind) || !
|
|
631
|
+
if (!Types.TypeRegistry.Has(kind) || !instances.has(instance))
|
|
604
632
|
return false;
|
|
605
|
-
const schema = state.instances.get(instance);
|
|
606
633
|
const checkFunc = Types.TypeRegistry.Get(kind);
|
|
634
|
+
const schema = instances.get(instance);
|
|
607
635
|
return checkFunc(schema, value);
|
|
608
636
|
}
|
|
609
637
|
function formatRegistryFunction(format, value) {
|
|
@@ -612,10 +640,10 @@ var TypeCompiler;
|
|
|
612
640
|
const checkFunc = Types.FormatRegistry.Get(format);
|
|
613
641
|
return checkFunc(value);
|
|
614
642
|
}
|
|
615
|
-
function
|
|
616
|
-
return
|
|
643
|
+
function hashFunction(value) {
|
|
644
|
+
return (0, hash_1.Hash)(value);
|
|
617
645
|
}
|
|
618
|
-
const checkFunction = compiledFunction(typeRegistryFunction, formatRegistryFunction,
|
|
646
|
+
const checkFunction = compiledFunction(typeRegistryFunction, formatRegistryFunction, hashFunction);
|
|
619
647
|
return new TypeCheck(schema, references, checkFunction, generatedCode);
|
|
620
648
|
}
|
|
621
649
|
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);
|