@sinclair/typebox 0.24.20 → 0.24.23

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.
@@ -1,4 +1,4 @@
1
- import { ValueError } from '../value/errors';
1
+ import { ValueError } from '../error/errors';
2
2
  import * as Types from '../typebox';
3
3
  export declare type CheckFunction = (value: unknown) => boolean;
4
4
  export declare class TypeCheck<T extends Types.TSchema> {
@@ -28,7 +28,8 @@ THE SOFTWARE.
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.TypeCompiler = exports.TypeCheck = void 0;
31
- const errors_1 = require("../value/errors");
31
+ const errors_1 = require("../error/errors");
32
+ const property_1 = require("./property");
32
33
  const Types = require("../typebox");
33
34
  // -------------------------------------------------------------------
34
35
  // TypeCheck
@@ -61,13 +62,13 @@ exports.TypeCheck = TypeCheck;
61
62
  var TypeCompiler;
62
63
  (function (TypeCompiler) {
63
64
  // -------------------------------------------------------------------
64
- // Schemas
65
+ // Types
65
66
  // -------------------------------------------------------------------
66
67
  function* Any(schema, value) {
67
68
  yield '(true)';
68
69
  }
69
70
  function* Array(schema, value) {
70
- const expression = [...Visit(schema.items, `value`)].map((condition) => condition).join(' && ');
71
+ const expression = CreateExpression(schema.items, 'value');
71
72
  if (schema.minItems !== undefined)
72
73
  yield `(${value}.length >= ${schema.minItems})`;
73
74
  if (schema.maxItems !== undefined)
@@ -143,13 +144,14 @@ var TypeCompiler;
143
144
  }
144
145
  }
145
146
  for (const propertyKey of propertyKeys) {
147
+ const memberExpression = property_1.Property.Check(propertyKey) ? `${value}.${propertyKey}` : `${value}['${propertyKey}']`;
146
148
  const propertySchema = schema.properties[propertyKey];
147
149
  if (schema.required && schema.required.includes(propertyKey)) {
148
- yield* Visit(propertySchema, `${value}.${propertyKey}`);
150
+ yield* Visit(propertySchema, memberExpression);
149
151
  }
150
152
  else {
151
- const expr = [...Visit(propertySchema, `${value}.${propertyKey}`)].map((condition) => condition).join(' && ');
152
- yield `(${value}.${propertyKey} === undefined ? true : (${expr}))`;
153
+ const expression = CreateExpression(propertySchema, memberExpression);
154
+ yield `(${memberExpression} === undefined ? true : (${expression}))`;
153
155
  }
154
156
  }
155
157
  }
@@ -159,25 +161,16 @@ var TypeCompiler;
159
161
  function* Record(schema, value) {
160
162
  yield `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))`;
161
163
  const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
162
- const local = PushLocal(`const local = new RegExp(/${keyPattern}/)`);
164
+ const local = PushLocal(`new RegExp(/${keyPattern}/)`);
163
165
  yield `(Object.keys(${value}).every(key => ${local}.test(key)))`;
164
- const expr = [...Visit(valueSchema, 'value')].map((condition) => condition).join(' && ');
165
- yield `(Object.values(${value}).every(value => ${expr}))`;
166
+ const expression = CreateExpression(valueSchema, 'value');
167
+ yield `(Object.values(${value}).every(value => ${expression}))`;
166
168
  }
167
169
  function* Ref(schema, value) {
168
- // reference: referenced schemas can originate from either additional
169
- // schemas or inline in the schema itself. Ideally the recursive
170
- // path should align to reference path. Consider for review.
171
- if (!functionNames.has(schema.$ref)) {
172
- const reference = referenceMap.get(schema.$ref);
173
- functionNames.add(schema.$ref);
174
- const conditions = [...Visit(reference, 'value')];
175
- const name = CreateFunctionName(schema.$ref);
176
- const body = CreateFunction(name, conditions);
177
- PushLocal(body);
178
- }
179
- const func = CreateFunctionName(schema.$ref);
180
- yield `(${func}(${value}))`;
170
+ if (!referenceMap.has(schema.$ref))
171
+ throw Error(`TypeCompiler.Ref: Cannot de-reference schema with $id '${schema.$ref}'`);
172
+ const reference = referenceMap.get(schema.$ref);
173
+ yield* Visit(reference, value);
181
174
  }
182
175
  function* Self(schema, value) {
183
176
  const func = CreateFunctionName(schema.$ref);
@@ -192,7 +185,7 @@ var TypeCompiler;
192
185
  yield `(${value}.length <= ${schema.maxLength})`;
193
186
  }
194
187
  if (schema.pattern !== undefined) {
195
- const local = PushLocal(`const local = new RegExp(/${schema.pattern}/);`);
188
+ const local = PushLocal(`new RegExp(/${schema.pattern}/);`);
196
189
  yield `(${local}.test(${value}))`;
197
190
  }
198
191
  }
@@ -202,16 +195,16 @@ var TypeCompiler;
202
195
  return yield `(${value}.length === 0)`;
203
196
  yield `(${value}.length === ${schema.maxItems})`;
204
197
  for (let i = 0; i < schema.items.length; i++) {
205
- const expr = [...Visit(schema.items[i], `${value}[${i}]`)].map((condition) => condition).join(' && ');
206
- yield `(${expr})`;
198
+ const expression = CreateExpression(schema.items[i], `${value}[${i}]`);
199
+ yield `(${expression})`;
207
200
  }
208
201
  }
209
202
  function* Undefined(schema, value) {
210
203
  yield `(${value} === undefined)`;
211
204
  }
212
205
  function* Union(schema, value) {
213
- const exprs = schema.anyOf.map((schema) => [...Visit(schema, value)].map((condition) => condition).join(' && '));
214
- yield `(${exprs.join(' || ')})`;
206
+ const expressions = schema.anyOf.map((schema) => CreateExpression(schema, value));
207
+ yield `(${expressions.join(' || ')})`;
215
208
  }
216
209
  function* Uint8Array(schema, value) {
217
210
  yield `(${value} instanceof Uint8Array)`;
@@ -230,12 +223,11 @@ var TypeCompiler;
230
223
  // reference: referenced schemas can originate from either additional
231
224
  // schemas or inline in the schema itself. Ideally the recursive
232
225
  // path should align to reference path. Consider for review.
233
- if (schema.$id && !functionNames.has(schema.$id)) {
234
- functionNames.add(schema.$id);
235
- const conditions = [...Visit(schema, 'value')];
226
+ if (schema.$id && !names.has(schema.$id)) {
227
+ names.add(schema.$id);
236
228
  const name = CreateFunctionName(schema.$id);
237
- const body = CreateFunction(name, conditions);
238
- PushLocal(body);
229
+ const body = CreateFunction(name, schema, 'value');
230
+ PushFunction(body);
239
231
  yield `(${name}(${value}))`;
240
232
  return;
241
233
  }
@@ -288,17 +280,17 @@ var TypeCompiler;
288
280
  }
289
281
  }
290
282
  // -------------------------------------------------------------------
291
- // Locals
283
+ // Compile State
292
284
  // -------------------------------------------------------------------
293
285
  const referenceMap = new Map();
294
- const functionLocals = new Set();
295
- const functionNames = new Set();
296
- function ClearLocals() {
297
- functionLocals.clear();
298
- functionNames.clear();
286
+ const locals = new Set(); // local variables and functions
287
+ const names = new Set(); // cache of local functions
288
+ function ResetCompiler() {
299
289
  referenceMap.clear();
290
+ locals.clear();
291
+ names.clear();
300
292
  }
301
- function PushReferences(schemas = []) {
293
+ function AddReferences(schemas = []) {
302
294
  for (const schema of schemas) {
303
295
  if (!schema.$id)
304
296
  throw new Error(`TypeCompiler: Referenced schemas must specify an $id.`);
@@ -307,33 +299,36 @@ var TypeCompiler;
307
299
  referenceMap.set(schema.$id, schema);
308
300
  }
309
301
  }
310
- function PushLocal(code) {
311
- const name = `local${functionLocals.size}`;
312
- functionLocals.add(code.replace('local', name));
313
- return name;
314
- }
315
- function GetLocals() {
316
- return [...functionLocals.values()];
302
+ function CreateExpression(schema, value) {
303
+ return [...Visit(schema, value)].join(' && ');
317
304
  }
318
- // -------------------------------------------------------------------
319
- // Functions
320
- // -------------------------------------------------------------------
321
305
  function CreateFunctionName($id) {
322
306
  return `check_${$id.replace(/-/g, '_')}`;
323
307
  }
324
- function CreateFunction(name, conditions) {
325
- const expression = conditions.map((condition) => ` ${condition}`).join(' &&\n');
308
+ function CreateFunction(name, schema, value) {
309
+ const expression = [...Visit(schema, value)].map((condition) => ` ${condition}`).join(' &&\n');
326
310
  return `function ${name}(value) {\n return (\n${expression}\n )\n}`;
327
311
  }
312
+ function PushFunction(functionBody) {
313
+ locals.add(functionBody);
314
+ }
315
+ function PushLocal(expression) {
316
+ const local = `local_${locals.size}`;
317
+ locals.add(`const ${local} = ${expression}`);
318
+ return local;
319
+ }
320
+ function GetLocals() {
321
+ return [...locals.values()];
322
+ }
328
323
  // -------------------------------------------------------------------
329
324
  // Compile
330
325
  // -------------------------------------------------------------------
331
326
  function Build(schema, references = []) {
332
- ClearLocals();
333
- PushReferences(references);
334
- const conditions = [...Visit(schema, 'value')]; // locals populated during yield
327
+ ResetCompiler();
328
+ AddReferences(references);
329
+ const check = CreateFunction('check', schema, 'value');
335
330
  const locals = GetLocals();
336
- return `${locals.join('\n')}\nreturn ${CreateFunction('check', conditions)}`;
331
+ return `${locals.join('\n')}\nreturn ${check}`;
337
332
  }
338
333
  /** Compiles the given type for runtime type checking. This compiler only accepts known TypeBox types non-inclusive of unsafe types. */
339
334
  function Compile(schema, references = []) {
@@ -1,2 +1,2 @@
1
- export type { ValueError } from '../value/errors';
1
+ export { ValueError, ValueErrorType } from '../error/errors';
2
2
  export * from './compiler';
package/compiler/index.js CHANGED
@@ -41,4 +41,7 @@ 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;
45
+ var errors_1 = require("../error/errors");
46
+ Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return errors_1.ValueErrorType; } });
44
47
  __exportStar(require("./compiler"), exports);
@@ -0,0 +1,4 @@
1
+ export declare namespace Property {
2
+ /** Tests if this property name can be used in a member expression */
3
+ function Check(propertyName: string): boolean;
4
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /*--------------------------------------------------------------------------
3
+
4
+ @sinclair/typebox/compiler
5
+
6
+ The MIT License (MIT)
7
+
8
+ Copyright (c) 2022 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in
18
+ all copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
+ THE SOFTWARE.
27
+
28
+ ---------------------------------------------------------------------------*/
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.Property = void 0;
31
+ var Property;
32
+ (function (Property) {
33
+ function DollarSign(char) {
34
+ return char === 36;
35
+ }
36
+ function Underscore(char) {
37
+ return char === 95;
38
+ }
39
+ function Numeric(char) {
40
+ return char >= 48 && char <= 57;
41
+ }
42
+ function Alpha(char) {
43
+ return (char >= 65 && char <= 90) || (char >= 97 && char <= 122);
44
+ }
45
+ /** Tests if this property name can be used in a member expression */
46
+ function Check(propertyName) {
47
+ if (propertyName.length === 0)
48
+ return false;
49
+ {
50
+ const code = propertyName.charCodeAt(0);
51
+ if (!(DollarSign(code) || Underscore(code) || Alpha(code))) {
52
+ return false;
53
+ }
54
+ }
55
+ for (let i = 1; i < propertyName.length; i++) {
56
+ const code = propertyName.charCodeAt(i);
57
+ if (!(DollarSign(code) || Underscore(code) || Alpha(code) || Numeric(code))) {
58
+ return false;
59
+ }
60
+ }
61
+ return true;
62
+ }
63
+ Property.Check = Check;
64
+ })(Property = exports.Property || (exports.Property = {}));
@@ -0,0 +1,52 @@
1
+ import * as Types from '../typebox';
2
+ export declare enum ValueErrorType {
3
+ Array = 0,
4
+ ArrayMinItems = 1,
5
+ ArrayMaxItems = 2,
6
+ ArrayUniqueItems = 3,
7
+ Boolean = 4,
8
+ Function = 5,
9
+ Integer = 6,
10
+ IntegerMultipleOf = 7,
11
+ IntegerExclusiveMinimum = 8,
12
+ IntegerExclusiveMaximum = 9,
13
+ IntegerMinimum = 10,
14
+ IntegerMaximum = 11,
15
+ Literal = 12,
16
+ Null = 13,
17
+ Number = 14,
18
+ NumberMultipleOf = 15,
19
+ NumberExclusiveMinimum = 16,
20
+ NumberExclusiveMaximum = 17,
21
+ NumberMinumum = 18,
22
+ NumberMaximum = 19,
23
+ Object = 20,
24
+ ObjectMinProperties = 21,
25
+ ObjectMaxProperties = 22,
26
+ ObjectAdditionalProperties = 23,
27
+ Promise = 24,
28
+ RecordKeyNumeric = 25,
29
+ RecordKeyString = 26,
30
+ String = 27,
31
+ StringMinLength = 28,
32
+ StringMaxLength = 29,
33
+ StringPattern = 30,
34
+ TupleZeroLength = 31,
35
+ TupleLength = 32,
36
+ Undefined = 33,
37
+ Union = 34,
38
+ Uint8Array = 35,
39
+ Uint8ArrayMinByteLength = 36,
40
+ Uint8ArrayMaxByteLength = 37,
41
+ Void = 38
42
+ }
43
+ export interface ValueError {
44
+ type: ValueErrorType;
45
+ schema: Types.TSchema;
46
+ path: string;
47
+ value: unknown;
48
+ message: string;
49
+ }
50
+ export declare namespace ValueErrors {
51
+ function Errors<T extends Types.TSchema>(schema: T, references: Types.TSchema[], value: any): IterableIterator<ValueError>;
52
+ }
@@ -27,23 +27,71 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.ValueErrors = void 0;
30
+ exports.ValueErrors = exports.ValueErrorType = void 0;
31
31
  const Types = require("../typebox");
32
+ // -------------------------------------------------------------------
33
+ // ValueErrorType
34
+ // -------------------------------------------------------------------
35
+ var ValueErrorType;
36
+ (function (ValueErrorType) {
37
+ ValueErrorType[ValueErrorType["Array"] = 0] = "Array";
38
+ ValueErrorType[ValueErrorType["ArrayMinItems"] = 1] = "ArrayMinItems";
39
+ ValueErrorType[ValueErrorType["ArrayMaxItems"] = 2] = "ArrayMaxItems";
40
+ ValueErrorType[ValueErrorType["ArrayUniqueItems"] = 3] = "ArrayUniqueItems";
41
+ ValueErrorType[ValueErrorType["Boolean"] = 4] = "Boolean";
42
+ ValueErrorType[ValueErrorType["Function"] = 5] = "Function";
43
+ ValueErrorType[ValueErrorType["Integer"] = 6] = "Integer";
44
+ ValueErrorType[ValueErrorType["IntegerMultipleOf"] = 7] = "IntegerMultipleOf";
45
+ ValueErrorType[ValueErrorType["IntegerExclusiveMinimum"] = 8] = "IntegerExclusiveMinimum";
46
+ ValueErrorType[ValueErrorType["IntegerExclusiveMaximum"] = 9] = "IntegerExclusiveMaximum";
47
+ ValueErrorType[ValueErrorType["IntegerMinimum"] = 10] = "IntegerMinimum";
48
+ ValueErrorType[ValueErrorType["IntegerMaximum"] = 11] = "IntegerMaximum";
49
+ ValueErrorType[ValueErrorType["Literal"] = 12] = "Literal";
50
+ ValueErrorType[ValueErrorType["Null"] = 13] = "Null";
51
+ ValueErrorType[ValueErrorType["Number"] = 14] = "Number";
52
+ ValueErrorType[ValueErrorType["NumberMultipleOf"] = 15] = "NumberMultipleOf";
53
+ ValueErrorType[ValueErrorType["NumberExclusiveMinimum"] = 16] = "NumberExclusiveMinimum";
54
+ ValueErrorType[ValueErrorType["NumberExclusiveMaximum"] = 17] = "NumberExclusiveMaximum";
55
+ ValueErrorType[ValueErrorType["NumberMinumum"] = 18] = "NumberMinumum";
56
+ ValueErrorType[ValueErrorType["NumberMaximum"] = 19] = "NumberMaximum";
57
+ ValueErrorType[ValueErrorType["Object"] = 20] = "Object";
58
+ ValueErrorType[ValueErrorType["ObjectMinProperties"] = 21] = "ObjectMinProperties";
59
+ ValueErrorType[ValueErrorType["ObjectMaxProperties"] = 22] = "ObjectMaxProperties";
60
+ ValueErrorType[ValueErrorType["ObjectAdditionalProperties"] = 23] = "ObjectAdditionalProperties";
61
+ ValueErrorType[ValueErrorType["Promise"] = 24] = "Promise";
62
+ ValueErrorType[ValueErrorType["RecordKeyNumeric"] = 25] = "RecordKeyNumeric";
63
+ ValueErrorType[ValueErrorType["RecordKeyString"] = 26] = "RecordKeyString";
64
+ ValueErrorType[ValueErrorType["String"] = 27] = "String";
65
+ ValueErrorType[ValueErrorType["StringMinLength"] = 28] = "StringMinLength";
66
+ ValueErrorType[ValueErrorType["StringMaxLength"] = 29] = "StringMaxLength";
67
+ ValueErrorType[ValueErrorType["StringPattern"] = 30] = "StringPattern";
68
+ ValueErrorType[ValueErrorType["TupleZeroLength"] = 31] = "TupleZeroLength";
69
+ ValueErrorType[ValueErrorType["TupleLength"] = 32] = "TupleLength";
70
+ ValueErrorType[ValueErrorType["Undefined"] = 33] = "Undefined";
71
+ ValueErrorType[ValueErrorType["Union"] = 34] = "Union";
72
+ ValueErrorType[ValueErrorType["Uint8Array"] = 35] = "Uint8Array";
73
+ ValueErrorType[ValueErrorType["Uint8ArrayMinByteLength"] = 36] = "Uint8ArrayMinByteLength";
74
+ ValueErrorType[ValueErrorType["Uint8ArrayMaxByteLength"] = 37] = "Uint8ArrayMaxByteLength";
75
+ ValueErrorType[ValueErrorType["Void"] = 38] = "Void";
76
+ })(ValueErrorType = exports.ValueErrorType || (exports.ValueErrorType = {}));
77
+ // -------------------------------------------------------------------
78
+ // ValueErrors
79
+ // -------------------------------------------------------------------
32
80
  var ValueErrors;
33
81
  (function (ValueErrors) {
34
82
  function* Any(schema, references, path, value) { }
35
83
  function* Array(schema, references, path, value) {
36
84
  if (!globalThis.Array.isArray(value)) {
37
- return yield { schema, path, value, message: `Expected array` };
85
+ return yield { type: ValueErrorType.Array, schema, path, value, message: `Expected array` };
38
86
  }
39
87
  if (schema.minItems !== undefined && !(value.length >= schema.minItems)) {
40
- yield { schema, path, value, message: `Expected array length to be greater or equal to ${schema.minItems}` };
88
+ yield { type: ValueErrorType.ArrayMinItems, schema, path, value, message: `Expected array length to be greater or equal to ${schema.minItems}` };
41
89
  }
42
90
  if (schema.maxItems !== undefined && !(value.length <= schema.maxItems)) {
43
- yield { schema, path, value, message: `Expected array length to be less or equal to ${schema.maxItems}` };
91
+ yield { type: ValueErrorType.ArrayMinItems, schema, path, value, message: `Expected array length to be less or equal to ${schema.maxItems}` };
44
92
  }
45
93
  if (schema.uniqueItems === true && !(new Set(value).size === value.length)) {
46
- yield { schema, path, value, message: `Expected array elements to be unique` };
94
+ yield { type: ValueErrorType.ArrayUniqueItems, schema, path, value, message: `Expected array elements to be unique` };
47
95
  }
48
96
  for (let i = 0; i < value.length; i++) {
49
97
  yield* Visit(schema.items, references, `${path}/${i}`, value[i]);
@@ -51,7 +99,7 @@ var ValueErrors;
51
99
  }
52
100
  function* Boolean(schema, references, path, value) {
53
101
  if (!(typeof value === 'boolean')) {
54
- return yield { schema, path, value, message: `Expected boolean` };
102
+ return yield { type: ValueErrorType.Boolean, schema, path, value, message: `Expected boolean` };
55
103
  }
56
104
  }
57
105
  function* Constructor(schema, references, path, value) {
@@ -59,78 +107,78 @@ var ValueErrors;
59
107
  }
60
108
  function* Function(schema, references, path, value) {
61
109
  if (!(typeof value === 'function')) {
62
- return yield { schema, path, value, message: `Expected function` };
110
+ return yield { type: ValueErrorType.Function, schema, path, value, message: `Expected function` };
63
111
  }
64
112
  }
65
113
  function* Integer(schema, references, path, value) {
66
114
  if (!(typeof value === 'number')) {
67
- return yield { schema, path, value, message: `Expected number` };
115
+ return yield { type: ValueErrorType.Number, schema, path, value, message: `Expected number` };
68
116
  }
69
117
  if (!globalThis.Number.isInteger(value)) {
70
- yield { schema, path, value, message: `Expected integer` };
118
+ yield { type: ValueErrorType.Integer, schema, path, value, message: `Expected integer` };
71
119
  }
72
120
  if (schema.multipleOf && !(value % schema.multipleOf === 0)) {
73
- yield { schema, path, value, message: `Expected integer to be a multiple of ${schema.multipleOf}` };
121
+ yield { type: ValueErrorType.IntegerMultipleOf, schema, path, value, message: `Expected integer to be a multiple of ${schema.multipleOf}` };
74
122
  }
75
123
  if (schema.exclusiveMinimum && !(value > schema.exclusiveMinimum)) {
76
- yield { schema, path, value, message: `Expected integer to be greater than ${schema.exclusiveMinimum}` };
124
+ yield { type: ValueErrorType.IntegerExclusiveMinimum, schema, path, value, message: `Expected integer to be greater than ${schema.exclusiveMinimum}` };
77
125
  }
78
126
  if (schema.exclusiveMaximum && !(value < schema.exclusiveMaximum)) {
79
- yield { schema, path, value, message: `Expected integer to be less than ${schema.exclusiveMaximum}` };
127
+ yield { type: ValueErrorType.IntegerExclusiveMaximum, schema, path, value, message: `Expected integer to be less than ${schema.exclusiveMaximum}` };
80
128
  }
81
129
  if (schema.minimum && !(value >= schema.minimum)) {
82
- yield { schema, path, value, message: `Expected integer to be greater or equal to ${schema.minimum}` };
130
+ yield { type: ValueErrorType.IntegerMinimum, schema, path, value, message: `Expected integer to be greater or equal to ${schema.minimum}` };
83
131
  }
84
132
  if (schema.maximum && !(value <= schema.maximum)) {
85
- yield { schema, path, value, message: `Expected integer to be less or equal to ${schema.maximum}` };
133
+ yield { type: ValueErrorType.IntegerMaximum, schema, path, value, message: `Expected integer to be less or equal to ${schema.maximum}` };
86
134
  }
87
135
  }
88
136
  function* Literal(schema, references, path, value) {
89
137
  if (!(value === schema.const)) {
90
138
  const error = typeof schema.const === 'string' ? `'${schema.const}'` : schema.const;
91
- return yield { schema, path, value, message: `Expected ${error}` };
139
+ return yield { type: ValueErrorType.Literal, schema, path, value, message: `Expected ${error}` };
92
140
  }
93
141
  }
94
142
  function* Null(schema, references, path, value) {
95
143
  if (!(value === null)) {
96
- return yield { schema, path, value, message: `Expected null` };
144
+ return yield { type: ValueErrorType.Null, schema, path, value, message: `Expected null` };
97
145
  }
98
146
  }
99
147
  function* Number(schema, references, path, value) {
100
148
  if (!(typeof value === 'number')) {
101
- return yield { schema, path, value, message: `Expected number` };
149
+ return yield { type: ValueErrorType.Number, schema, path, value, message: `Expected number` };
102
150
  }
103
151
  if (schema.multipleOf && !(value % schema.multipleOf === 0)) {
104
- yield { schema, path, value, message: `Expected number to be a multiple of ${schema.multipleOf}` };
152
+ yield { type: ValueErrorType.NumberMultipleOf, schema, path, value, message: `Expected number to be a multiple of ${schema.multipleOf}` };
105
153
  }
106
154
  if (schema.exclusiveMinimum && !(value > schema.exclusiveMinimum)) {
107
- yield { schema, path, value, message: `Expected number to be greater than ${schema.exclusiveMinimum}` };
155
+ yield { type: ValueErrorType.NumberExclusiveMinimum, schema, path, value, message: `Expected number to be greater than ${schema.exclusiveMinimum}` };
108
156
  }
109
157
  if (schema.exclusiveMaximum && !(value < schema.exclusiveMaximum)) {
110
- yield { schema, path, value, message: `Expected number to be less than ${schema.exclusiveMaximum}` };
158
+ yield { type: ValueErrorType.NumberExclusiveMaximum, schema, path, value, message: `Expected number to be less than ${schema.exclusiveMaximum}` };
111
159
  }
112
160
  if (schema.minimum && !(value >= schema.minimum)) {
113
- yield { schema, path, value, message: `Expected number to be greater or equal to ${schema.minimum}` };
161
+ yield { type: ValueErrorType.NumberMaximum, schema, path, value, message: `Expected number to be greater or equal to ${schema.minimum}` };
114
162
  }
115
163
  if (schema.maximum && !(value <= schema.maximum)) {
116
- yield { schema, path, value, message: `Expected number to be less or equal to ${schema.maximum}` };
164
+ yield { type: ValueErrorType.NumberMinumum, schema, path, value, message: `Expected number to be less or equal to ${schema.maximum}` };
117
165
  }
118
166
  }
119
167
  function* Object(schema, references, path, value) {
120
168
  if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
121
- return yield { schema, path, value, message: `Expected object` };
169
+ return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
122
170
  }
123
171
  if (schema.minProperties !== undefined && !(globalThis.Object.keys(value).length >= schema.minProperties)) {
124
- yield { schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` };
172
+ yield { type: ValueErrorType.ObjectMinProperties, schema, path, value, message: `Expected object to have at least ${schema.minProperties} properties` };
125
173
  }
126
174
  if (schema.maxProperties !== undefined && !(globalThis.Object.keys(value).length <= schema.maxProperties)) {
127
- yield { schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` };
175
+ yield { type: ValueErrorType.ObjectMaxProperties, schema, path, value, message: `Expected object to have less than ${schema.minProperties} properties` };
128
176
  }
129
177
  const propertyKeys = globalThis.Object.keys(schema.properties);
130
178
  if (schema.additionalProperties === false) {
131
179
  for (const propKey of globalThis.Object.keys(value)) {
132
180
  if (!propertyKeys.includes(propKey)) {
133
- yield { schema, path: `${path}/${propKey}`, value: value[propKey], message: 'Unexpected property' };
181
+ yield { type: ValueErrorType.ObjectAdditionalProperties, schema, path: `${path}/${propKey}`, value: value[propKey], message: 'Unexpected property' };
134
182
  }
135
183
  }
136
184
  }
@@ -148,18 +196,20 @@ var ValueErrors;
148
196
  }
149
197
  function* Promise(schema, references, path, value) {
150
198
  if (!(typeof value === 'object' && typeof value.then === 'function')) {
151
- yield { schema, path, value, message: `Expected Promise` };
199
+ yield { type: ValueErrorType.Promise, schema, path, value, message: `Expected Promise` };
152
200
  }
153
201
  }
154
202
  function* Record(schema, references, path, value) {
155
203
  if (!(typeof value === 'object' && value !== null && !globalThis.Array.isArray(value))) {
156
- return yield { schema, path, value, message: `Expected object` };
204
+ return yield { type: ValueErrorType.Object, schema, path, value, message: `Expected object` };
157
205
  }
158
206
  const [keyPattern, valueSchema] = globalThis.Object.entries(schema.patternProperties)[0];
159
207
  const regex = new RegExp(keyPattern);
160
208
  if (!globalThis.Object.keys(value).every((key) => regex.test(key))) {
161
- const message = keyPattern === '^(0|[1-9][0-9]*)$' ? 'Expected all object property keys to be numeric' : 'Expected all object property keys to be strings';
162
- return yield { schema, path, value, message };
209
+ const numeric = keyPattern === '^(0|[1-9][0-9]*)$';
210
+ const type = numeric ? ValueErrorType.RecordKeyNumeric : ValueErrorType.RecordKeyString;
211
+ const message = numeric ? 'Expected all object property keys to be numeric' : 'Expected all object property keys to be strings';
212
+ return yield { type, schema, path, value, message };
163
213
  }
164
214
  for (const [propKey, propValue] of globalThis.Object.entries(value)) {
165
215
  yield* Visit(valueSchema, references, `${path}/${propKey}`, propValue);
@@ -179,30 +229,30 @@ var ValueErrors;
179
229
  }
180
230
  function* String(schema, references, path, value) {
181
231
  if (!(typeof value === 'string')) {
182
- return yield { schema, path, value, message: 'Expected string' };
232
+ return yield { type: ValueErrorType.String, schema, path, value, message: 'Expected string' };
183
233
  }
184
234
  if (schema.minLength !== undefined && !(value.length >= schema.minLength)) {
185
- yield { schema, path, value, message: `Expected string length greater or equal to ${schema.minLength}` };
235
+ yield { type: ValueErrorType.StringMinLength, schema, path, value, message: `Expected string length greater or equal to ${schema.minLength}` };
186
236
  }
187
237
  if (schema.maxLength !== undefined && !(value.length <= schema.maxLength)) {
188
- yield { schema, path, value, message: `Expected string length less or equal to ${schema.maxLength}` };
238
+ yield { type: ValueErrorType.StringMaxLength, schema, path, value, message: `Expected string length less or equal to ${schema.maxLength}` };
189
239
  }
190
240
  if (schema.pattern !== undefined) {
191
241
  const regex = new RegExp(schema.pattern);
192
242
  if (!regex.test(value)) {
193
- yield { schema, path, value, message: `Expected string to match pattern ${schema.pattern}` };
243
+ yield { type: ValueErrorType.StringPattern, schema, path, value, message: `Expected string to match pattern ${schema.pattern}` };
194
244
  }
195
245
  }
196
246
  }
197
247
  function* Tuple(schema, references, path, value) {
198
248
  if (!globalThis.Array.isArray(value)) {
199
- return yield { schema, path, value, message: 'Expected Array' };
249
+ return yield { type: ValueErrorType.Array, schema, path, value, message: 'Expected Array' };
200
250
  }
201
251
  if (schema.items === undefined && !(value.length === 0)) {
202
- return yield { schema, path, value, message: 'Expected tuple to have 0 elements' };
252
+ return yield { type: ValueErrorType.TupleZeroLength, schema, path, value, message: 'Expected tuple to have 0 elements' };
203
253
  }
204
254
  if (!(value.length === schema.maxItems)) {
205
- yield { schema, path, value, message: `Expected tuple to have ${schema.maxItems} elements` };
255
+ yield { type: ValueErrorType.TupleLength, schema, path, value, message: `Expected tuple to have ${schema.maxItems} elements` };
206
256
  }
207
257
  if (!schema.items) {
208
258
  return;
@@ -213,7 +263,7 @@ var ValueErrors;
213
263
  }
214
264
  function* Undefined(schema, references, path, value) {
215
265
  if (!(value === undefined)) {
216
- yield { schema, path, value, message: `Expected undefined` };
266
+ yield { type: ValueErrorType.Undefined, schema, path, value, message: `Expected undefined` };
217
267
  }
218
268
  }
219
269
  function* Union(schema, references, path, value) {
@@ -228,24 +278,24 @@ var ValueErrors;
228
278
  yield error;
229
279
  }
230
280
  if (errors.length > 0) {
231
- yield { schema, path, value, message: 'Expected value of union' };
281
+ yield { type: ValueErrorType.Union, schema, path, value, message: 'Expected value of union' };
232
282
  }
233
283
  }
234
284
  function* Uint8Array(schema, references, path, value) {
235
285
  if (!(value instanceof globalThis.Uint8Array)) {
236
- return yield { schema, path, value, message: `Expected Uint8Array` };
286
+ return yield { type: ValueErrorType.Uint8Array, schema, path, value, message: `Expected Uint8Array` };
237
287
  }
238
288
  if (schema.maxByteLength && !(value.length <= schema.maxByteLength)) {
239
- yield { schema, path, value, message: `Expected Uint8Array to have a byte length less or equal to ${schema.maxByteLength}` };
289
+ yield { type: ValueErrorType.Uint8ArrayMaxByteLength, schema, path, value, message: `Expected Uint8Array to have a byte length less or equal to ${schema.maxByteLength}` };
240
290
  }
241
291
  if (schema.minByteLength && !(value.length >= schema.minByteLength)) {
242
- yield { schema, path, value, message: `Expected Uint8Array to have a byte length greater or equal to ${schema.maxByteLength}` };
292
+ yield { type: ValueErrorType.Uint8ArrayMinByteLength, schema, path, value, message: `Expected Uint8Array to have a byte length greater or equal to ${schema.maxByteLength}` };
243
293
  }
244
294
  }
245
295
  function* Unknown(schema, references, path, value) { }
246
296
  function* Void(schema, references, path, value) {
247
297
  if (!(value === null)) {
248
- return yield { schema, path, value, message: `Expected null` };
298
+ return yield { type: ValueErrorType.Void, schema, path, value, message: `Expected null` };
249
299
  }
250
300
  }
251
301
  function* Visit(schema, references, path, value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.24.20",
3
+ "version": "0.24.23",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
package/readme.md CHANGED
@@ -47,30 +47,30 @@ type T = Static<typeof T> // type T = string
47
47
 
48
48
  TypeBox is a type builder library that creates in-memory JSON Schema objects that can be statically inferred as TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox enables one to create unified types that can be statically checked by TypeScript and runtime asserted using standard JSON Schema validation.
49
49
 
50
- TypeBox can be used as a simple tool to build up complex schemas or integrated into RPC or REST services to help validate data received over the wire. It offers a type system aligned to the capabilities of TypeScript and can be used equally well in JavaScript environments.
50
+ TypeBox can be used as a simple tool to build up complex schemas or integrated into RPC or REST services to help validate JSON data received over the wire.
51
51
 
52
52
  License MIT
53
53
 
54
54
  ## Contents
55
- - [Install](#Install)
56
- - [Overview](#Overview)
57
- - [Usage](#Usage)
58
- - [Types](#Types)
59
- - [Modifiers](#Modifiers)
60
- - [Options](#Options)
61
- - [Extended Types](#Extended-Types)
62
- - [Reference Types](#Reference-Types)
63
- - [Recursive Types](#Recursive-Types)
64
- - [Generic Types](#Generic-Types)
65
- - [Unsafe Types](#Unsafe-Types)
66
- - [Conditional Types](#Conditional-Types)
67
- - [Values](#Values)
68
- - [Guards](#Guards)
69
- - [Strict](#Strict)
70
- - [Validation](#Validation)
71
- - [Compiler](#Compiler)
72
- - [Benchmark](#Benchmark)
73
- - [Contribute](#Contribute)
55
+ - [Install](#install)
56
+ - [Overview](#overview)
57
+ - [Usage](#usage)
58
+ - [Types](#types)
59
+ - [Modifiers](#modifiers)
60
+ - [Options](#options)
61
+ - [Extended Types](#extended-types)
62
+ - [Reference Types](#reference-types)
63
+ - [Recursive Types](#recursive-types)
64
+ - [Generic Types](#generic-types)
65
+ - [Unsafe Types](#unsafe-types)
66
+ - [Conditional Types](#conditional-types)
67
+ - [Values](#values)
68
+ - [Guards](#guards)
69
+ - [Strict](#strict)
70
+ - [Validation](#validation)
71
+ - [Compiler](#compiler)
72
+ - [Benchmark](#benchmark)
73
+ - [Contribute](#contribute)
74
74
 
75
75
  <a name="Example"></a>
76
76
 
@@ -147,8 +147,6 @@ function receive(value: T) { // ... as a Type
147
147
  }
148
148
  ```
149
149
 
150
- <a name="Types"></a>
151
-
152
150
  ## Types
153
151
 
154
152
  The following table outlines the TypeBox mappings between TypeScript and JSON schema.
@@ -342,7 +340,6 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
342
340
  │ │ │ │
343
341
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
344
342
  ```
345
- <a name="Modifiers"></a>
346
343
 
347
344
  ## Modifiers
348
345
 
@@ -386,8 +383,6 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
386
383
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
387
384
  ```
388
385
 
389
- <a name="Options"></a>
390
-
391
386
  ## Options
392
387
 
393
388
  You can pass additional JSON schema options on the last argument of any given type. The following are some examples.
@@ -403,8 +398,6 @@ const T = Type.Number({ multipleOf: 2 })
403
398
  const T = Type.Array(Type.Integer(), { minItems: 5 })
404
399
  ```
405
400
 
406
- <a name="Extended-Types"></a>
407
-
408
401
  ## Extended Types
409
402
 
410
403
  In addition to JSON schema types, TypeBox provides several extended types that allow for `function` and `constructor` types to be composed. These additional types are not valid JSON Schema and will not validate using typical JSON Schema validation. However, these types can be used to frame JSON schema and describe callable interfaces that may receive JSON validated data. These types are as follows.
@@ -467,8 +460,6 @@ In addition to JSON schema types, TypeBox provides several extended types that a
467
460
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
468
461
  ```
469
462
 
470
- <a name="Reference-Types"></a>
471
-
472
463
  ## Reference Types
473
464
 
474
465
  Use `Type.Ref(...)` to create referenced types. The target type must specify an `$id`.
@@ -484,8 +475,6 @@ const R = Type.Ref(T) // const R = {
484
475
  // }
485
476
  ```
486
477
 
487
- <a name="Recursive-Types"></a>
488
-
489
478
  ## Recursive Types
490
479
 
491
480
  Use `Type.Recursive(...)` to create recursive types.
@@ -524,11 +513,9 @@ function test(node: Node) {
524
513
  }
525
514
  ```
526
515
 
527
- <a name="Generic-Types"></a>
528
-
529
516
  ## Generic Types
530
517
 
531
- Generic types can be created using functions. The following creates a generic `Nullable<T>` type.
518
+ Use functions to create generic types. The following creates a generic `Nullable<T>` type.
532
519
 
533
520
  ```typescript
534
521
  import { Type, Static, TSchema } from '@sinclair/typebox'
@@ -556,8 +543,6 @@ const U = Nullable(Type.Number()) // const U = {
556
543
  type U = Static<typeof U> // type U = number | null
557
544
  ```
558
545
 
559
- <a name="Unsafe-Types"></a>
560
-
561
546
  ## Unsafe Types
562
547
 
563
548
  Use `Type.Unsafe(...)` to create custom schemas with user defined inference rules.
@@ -594,12 +579,12 @@ type T = Static<typeof T> // type T = string | null
594
579
 
595
580
  //--------------------------------------------------------------------------------------------
596
581
  //
597
- // StringUnion<[...]>
582
+ // StringEnum<string[]>
598
583
  //
599
584
  //--------------------------------------------------------------------------------------------
600
585
 
601
586
  function StringEnum<T extends string[]>(values: [...T]) {
602
- return Type.Unsafe<T[number]>({ enum: values })
587
+ return Type.Unsafe<T[number]>({ type: 'string', enum: values })
603
588
  }
604
589
 
605
590
  const T = StringEnum(['A', 'B', 'C']) // const T = {
@@ -609,8 +594,6 @@ const T = StringEnum(['A', 'B', 'C']) // const T = {
609
594
  type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
610
595
  ```
611
596
 
612
- <a name="Conditional-Types"></a>
613
-
614
597
  ## Conditional Types
615
598
 
616
599
  Use `Conditional.Extends(...)` to create conditional mapped types.
@@ -660,8 +643,6 @@ The following table shows the TypeBox mappings between TypeScript and JSON schem
660
643
  └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘
661
644
  ```
662
645
 
663
- <a name="Values"></a>
664
-
665
646
  ## Values
666
647
 
667
648
  Use `Value.Create(...)` to generate values from types.
@@ -697,8 +678,6 @@ const B = Value.Cast(T, { x: 1 }) // const B = { x: 1, y: 0
697
678
  const C = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const C = { x: 1, y: 2 }
698
679
  ```
699
680
 
700
- <a name="Guards"></a>
701
-
702
681
  ## Guards
703
682
 
704
683
  Use a `TypeGuard` to test if a value meets a TypeBox type specification. Guards can be helpful when reflecting types.
@@ -716,8 +695,6 @@ if(TypeGuard.TString(T)) {
716
695
 
717
696
  ```
718
697
 
719
- <a name="Strict"></a>
720
-
721
698
  ## Strict
722
699
 
723
700
  TypeBox schemas contain the `Kind` and `Modifier` symbol properties. These properties are provided to enable runtime type reflection on schemas, as well as helping TypeBox internally compose types. These properties are not strictly valid JSON schema; so in some cases it may be desirable to omit them. TypeBox provides a `Type.Strict()` function that will omit these properties if necessary.
@@ -745,8 +722,6 @@ const U = Type.Strict(T) // const U = {
745
722
  // }
746
723
  ```
747
724
 
748
- <a name="Validation"></a>
749
-
750
725
  ## Validation
751
726
 
752
727
  TypeBox schemas target JSON Schema draft 6 so any validator capable of draft 6 should be fine. A good library to use for validation in JavaScript environments is [Ajv](https://www.npmjs.com/package/ajv). The following example shows setting up Ajv to work with TypeBox.
@@ -812,8 +787,6 @@ const R = ajv.validate(T, { x: 1, y: 2, z: 3 }) // const R = true
812
787
 
813
788
  Please refer to the official Ajv [documentation](https://ajv.js.org/guide/getting-started.html) for additional information on using Ajv.
814
789
 
815
- <a name="Compiler"></a>
816
-
817
790
  ## Compiler
818
791
 
819
792
  TypeBox provides an optional high performance runtime type checker that can be used in applications that require extremely fast validation. This type checker is optimized for TypeBox types only whose schematics are known in advance. If defining custom schemas with `Type.Unsafe<T>` please consider Ajv.
@@ -845,16 +818,19 @@ const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck<TObje
845
818
  const value = { }
846
819
 
847
820
  const errors = [...C.Errors(value)] // const errors = [{
821
+ // type: ValueErrorType.Number,
848
822
  // schema: { type: 'number' },
849
823
  // path: '/x',
850
824
  // value: undefined,
851
825
  // message: 'Expected number'
852
826
  // }, {
827
+ // type: ValueErrorType.Number,
853
828
  // schema: { type: 'number' },
854
829
  // path: '/y',
855
830
  // value: undefined,
856
831
  // message: 'Expected number'
857
832
  // }, {
833
+ // type: ValueErrorType.Number,
858
834
  // schema: { type: 'number' },
859
835
  // path: '/z',
860
836
  // value: undefined,
@@ -874,9 +850,13 @@ console.log(C.Code()) // return function check(va
874
850
  // }
875
851
  ```
876
852
 
853
+
854
+
877
855
  ## Benchmark
878
856
 
879
- This project maintains benchmarks that measure Ajv and TypeCompiler validate and compile performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. Results show against Ajv version 8.11.0.
857
+ This project maintains a set of benchmarks that measure Ajv and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. The results below show for Ajv version 8.11.0.
858
+
859
+ For additional comparative benchmarks, please refer to [typescript-runtime-type-benchmarks](https://moltar.github.io/typescript-runtime-type-benchmarks/).
880
860
 
881
861
  ### Validate
882
862
 
@@ -886,31 +866,31 @@ This benchmark measures validation performance for varying types. You can review
886
866
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
887
867
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
888
868
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
889
- │ Number │ 16000000 │ ' 73 ms' │ ' 65 ms' │ ' 1.12 x' │
890
- │ String │ 16000000 │ ' 281 ms' │ ' 161 ms' │ ' 1.75 x' │
891
- │ Boolean │ 16000000 │ ' 302 ms' │ ' 151 ms' │ ' 2.00 x' │
892
- │ Null │ 16000000 │ ' 281 ms' │ ' 149 ms' │ ' 1.89 x' │
893
- │ RegEx │ 16000000 │ ' 689 ms' │ ' 550 ms' │ ' 1.25 x' │
894
- │ ObjectA │ 16000000 │ ' 470 ms' │ ' 311 ms' │ ' 1.51 x' │
895
- │ ObjectB │ 16000000 │ ' 667 ms' │ ' 556 ms' │ ' 1.20 x' │
896
- │ Tuple │ 16000000 │ ' 362 ms' │ ' 190 ms' │ ' 1.91 x' │
897
- │ Union │ 16000000 │ ' 387 ms' │ ' 209 ms' │ ' 1.85 x' │
898
- │ Recursive │ 16000000 │ ' 6327 ms' │ ' 2773 ms' │ ' 2.28 x' │
899
- │ Vector4 │ 16000000 │ ' 362 ms' │ ' 172 ms' │ ' 2.10 x' │
900
- │ Matrix4 │ 16000000 │ ' 607 ms' │ ' 418 ms' │ ' 1.45 x' │
901
- │ Literal_String │ 16000000 │ ' 314 ms' │ ' 151 ms' │ ' 2.08 x' │
902
- │ Literal_Number │ 16000000 │ ' 281 ms' │ ' 147 ms' │ ' 1.91 x' │
903
- │ Literal_Boolean │ 16000000 │ ' 289 ms' │ ' 148 ms' │ ' 1.95 x' │
904
- │ Array_Number │ 16000000 │ ' 475 ms' │ ' 230 ms' │ ' 2.07 x' │
905
- │ Array_String │ 16000000 │ ' 463 ms' │ ' 297 ms' │ ' 1.56 x' │
906
- │ Array_Boolean │ 16000000 │ ' 521 ms' │ ' 348 ms' │ ' 1.50 x' │
907
- │ Array_ObjectA │ 16000000 │ ' 43842 ms' │ ' 28375 ms' │ ' 1.55 x' │
908
- │ Array_ObjectB │ 16000000 │ ' 45055 ms' │ ' 32882 ms' │ ' 1.37 x' │
909
- │ Array_Tuple │ 16000000 │ ' 1424 ms' │ ' 1105 ms' │ ' 1.29 x' │
910
- │ Array_Union │ 16000000 │ ' 3505 ms' │ ' 1350 ms' │ ' 2.60 x' │
911
- │ Array_Recursive │ 16000000 │ ' 117087 ms' │ ' 42982 ms' │ ' 2.72 x' │
912
- │ Array_Vector4 │ 16000000 │ ' 1500 ms' │ ' 817 ms' │ ' 1.84 x' │
913
- │ Array_Matrix4 │ 16000000 │ ' 6126 ms' │ ' 4965 ms' │ ' 1.23 x' │
869
+ │ Number │ 4000000 │ ' 17 ms' │ ' 16 ms' │ ' 1.06 x' │
870
+ │ String │ 4000000 │ ' 74 ms' │ ' 37 ms' │ ' 2.00 x' │
871
+ │ Boolean │ 4000000 │ ' 68 ms' │ ' 36 ms' │ ' 1.89 x' │
872
+ │ Null │ 4000000 │ ' 68 ms' │ ' 36 ms' │ ' 1.89 x' │
873
+ │ RegEx │ 4000000 │ ' 170 ms' │ ' 143 ms' │ ' 1.19 x' │
874
+ │ ObjectA │ 4000000 │ ' 122 ms' │ ' 84 ms' │ ' 1.45 x' │
875
+ │ ObjectB │ 4000000 │ ' 182 ms' │ ' 137 ms' │ ' 1.33 x' │
876
+ │ Tuple │ 4000000 │ ' 82 ms' │ ' 48 ms' │ ' 1.71 x' │
877
+ │ Union │ 4000000 │ ' 84 ms' │ ' 52 ms' │ ' 1.62 x' │
878
+ │ Recursive │ 4000000 │ ' 1526 ms' │ ' 631 ms' │ ' 2.42 x' │
879
+ │ Vector4 │ 4000000 │ ' 80 ms' │ ' 42 ms' │ ' 1.90 x' │
880
+ │ Matrix4 │ 4000000 │ ' 157 ms' │ ' 113 ms' │ ' 1.39 x' │
881
+ │ Literal_String │ 4000000 │ ' 69 ms' │ ' 36 ms' │ ' 1.92 x' │
882
+ │ Literal_Number │ 4000000 │ ' 69 ms' │ ' 35 ms' │ ' 1.97 x' │
883
+ │ Literal_Boolean │ 4000000 │ ' 68 ms' │ ' 35 ms' │ ' 1.94 x' │
884
+ │ Array_Number │ 4000000 │ ' 119 ms' │ ' 60 ms' │ ' 1.98 x' │
885
+ │ Array_String │ 4000000 │ ' 119 ms' │ ' 76 ms' │ ' 1.57 x' │
886
+ │ Array_Boolean │ 4000000 │ ' 131 ms' │ ' 88 ms' │ ' 1.49 x' │
887
+ │ Array_ObjectA │ 4000000 │ ' 10615 ms' │ ' 7053 ms' │ ' 1.51 x' │
888
+ │ Array_ObjectB │ 4000000 │ ' 11305 ms' │ ' 8128 ms' │ ' 1.39 x' │
889
+ │ Array_Tuple │ 4000000 │ ' 355 ms' │ ' 271 ms' │ ' 1.31 x' │
890
+ │ Array_Union │ 4000000 │ ' 910 ms' │ ' 340 ms' │ ' 2.68 x' │
891
+ │ Array_Recursive │ 4000000 │ ' 29101 ms' │ ' 10837 ms' │ ' 2.69 x' │
892
+ │ Array_Vector4 │ 4000000 │ ' 381 ms' │ ' 212 ms' │ ' 1.80 x' │
893
+ │ Array_Matrix4 │ 4000000 │ ' 1534 ms' │ ' 1344 ms' │ ' 1.14 x' │
914
894
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
915
895
  ```
916
896
 
@@ -922,34 +902,32 @@ This benchmark measures compilation performance for varying types. You can revie
922
902
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
923
903
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
924
904
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
925
- │ Number │ 2000 │ ' 387 ms' │ ' 7 ms' │ ' 55.29 x' │
926
- │ String │ 2000 │ ' 340 ms' │ ' 6 ms' │ ' 56.67 x' │
927
- │ Boolean │ 2000 │ ' 314 ms' │ ' 5 ms' │ ' 62.80 x' │
928
- │ Null │ 2000 │ ' 259 ms' │ ' 5 ms' │ ' 51.80 x' │
929
- │ RegEx │ 2000 │ ' 491 ms' │ ' 7 ms' │ ' 70.14 x' │
930
- │ ObjectA │ 2000 │ ' 2850 ms' │ ' 26 ms' │ ' 109.62 x' │
931
- │ ObjectB │ 2000 │ ' 2989 ms' │ ' 22 ms' │ ' 135.86 x' │
932
- │ Tuple │ 2000 │ ' 1283 ms' │ ' 17 ms' │ ' 75.47 x' │
933
- │ Union │ 2000 │ ' 1292 ms' │ ' 16 ms' │ ' 80.75 x' │
934
- │ Vector4 │ 2000 │ ' 1588 ms' │ ' 12 ms' │ ' 132.33 x' │
935
- │ Matrix4 │ 2000 │ ' 934 ms' │ ' 7 ms' │ ' 133.43 x' │
936
- │ Literal_String │ 2000 │ ' 340 ms' │ ' 5 ms' │ ' 68.00 x' │
937
- │ Literal_Number │ 2000 │ ' 402 ms' │ ' 4 ms' │ ' 100.50 x' │
938
- │ Literal_Boolean │ 2000 │ ' 381 ms' │ ' 6 ms' │ ' 63.50 x' │
939
- │ Array_Number │ 2000 │ ' 750 ms' │ ' 8 ms' │ ' 93.75 x' │
940
- │ Array_String │ 2000 │ ' 760 ms' │ ' 6 ms' │ ' 126.67 x' │
941
- │ Array_Boolean │ 2000 │ ' 796 ms' │ ' 7 ms' │ ' 113.71 x' │
942
- │ Array_ObjectA │ 2000 │ ' 3617 ms' │ ' 26 ms' │ ' 139.12 x' │
943
- │ Array_ObjectB │ 2000 │ ' 3823 ms' │ ' 26 ms' │ ' 147.04 x' │
944
- │ Array_Tuple │ 2000 │ ' 2263 ms' │ ' 13 ms' │ ' 174.08 x' │
945
- │ Array_Union │ 2000 │ ' 1725 ms' │ ' 16 ms' │ ' 107.81 x' │
946
- │ Array_Vector4 │ 2000 │ ' 2445 ms' │ ' 14 ms' │ ' 174.64 x' │
947
- │ Array_Matrix4 │ 2000 │ ' 1638 ms' │ ' 11 ms' │ ' 148.91 x' │
905
+ │ Number │ 2000 │ ' 384 ms' │ ' 7 ms' │ ' 54.86 x' │
906
+ │ String │ 2000 │ ' 311 ms' │ ' 6 ms' │ ' 51.83 x' │
907
+ │ Boolean │ 2000 │ ' 304 ms' │ ' 5 ms' │ ' 60.80 x' │
908
+ │ Null │ 2000 │ ' 252 ms' │ ' 5 ms' │ ' 50.40 x' │
909
+ │ RegEx │ 2000 │ ' 480 ms' │ ' 7 ms' │ ' 68.57 x' │
910
+ │ ObjectA │ 2000 │ ' 2786 ms' │ ' 27 ms' │ ' 103.19 x' │
911
+ │ ObjectB │ 2000 │ ' 2946 ms' │ ' 22 ms' │ ' 133.91 x' │
912
+ │ Tuple │ 2000 │ ' 1277 ms' │ ' 16 ms' │ ' 79.81 x' │
913
+ │ Union │ 2000 │ ' 1288 ms' │ ' 16 ms' │ ' 80.50 x' │
914
+ │ Vector4 │ 2000 │ ' 1628 ms' │ ' 12 ms' │ ' 135.67 x' │
915
+ │ Matrix4 │ 2000 │ ' 912 ms' │ ' 7 ms' │ ' 130.29 x' │
916
+ │ Literal_String │ 2000 │ ' 344 ms' │ ' 5 ms' │ ' 68.80 x' │
917
+ │ Literal_Number │ 2000 │ ' 432 ms' │ ' 5 ms' │ ' 86.40 x' │
918
+ │ Literal_Boolean │ 2000 │ ' 407 ms' │ ' 4 ms' │ ' 101.75 x' │
919
+ │ Array_Number │ 2000 │ ' 788 ms' │ ' 9 ms' │ ' 87.56 x' │
920
+ │ Array_String │ 2000 │ ' 823 ms' │ ' 7 ms' │ ' 117.57 x' │
921
+ │ Array_Boolean │ 2000 │ ' 816 ms' │ ' 5 ms' │ ' 163.20 x' │
922
+ │ Array_ObjectA │ 2000 │ ' 4270 ms' │ ' 24 ms' │ ' 177.92 x' │
923
+ │ Array_ObjectB │ 2000 │ ' 4008 ms' │ ' 28 ms' │ ' 143.14 x' │
924
+ │ Array_Tuple │ 2000 │ ' 2243 ms' │ ' 13 ms' │ ' 172.54 x' │
925
+ │ Array_Union │ 2000 │ ' 1734 ms' │ ' 16 ms' │ ' 108.38 x' │
926
+ │ Array_Vector4 │ 2000 │ ' 2348 ms' │ ' 14 ms' │ ' 167.71 x' │
927
+ │ Array_Matrix4 │ 2000 │ ' 1608 ms' │ ' 11 ms' │ ' 146.18 x' │
948
928
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
949
929
  ```
950
930
 
951
- <a name="Contribute"></a>
952
-
953
931
  ## Contribute
954
932
 
955
933
  TypeBox is open to community contribution. Please ensure you submit an open issue before submitting your pull request. The TypeBox project preferences open community discussion prior to accepting new features.
package/value/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export type { ValueError } from './errors';
1
+ export { ValueError, ValueErrorType } from '../error/errors';
2
2
  export * from './value';
package/value/index.js CHANGED
@@ -41,4 +41,7 @@ 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;
45
+ var errors_1 = require("../error/errors");
46
+ Object.defineProperty(exports, "ValueErrorType", { enumerable: true, get: function () { return errors_1.ValueErrorType; } });
44
47
  __exportStar(require("./value"), exports);
package/value/value.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as Types from '../typebox';
2
- import { ValueError } from './errors';
2
+ import { ValueError } from '../error/errors';
3
3
  /** Creates Values from TypeBox Types */
4
4
  export declare namespace Value {
5
5
  /** Creates a value from the given type */
package/value/value.js CHANGED
@@ -28,7 +28,7 @@ THE SOFTWARE.
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.Value = void 0;
31
- const errors_1 = require("./errors");
31
+ const errors_1 = require("../error/errors");
32
32
  const cast_1 = require("./cast");
33
33
  const create_1 = require("./create");
34
34
  const check_1 = require("./check");
package/value/errors.d.ts DELETED
@@ -1,10 +0,0 @@
1
- import * as Types from '../typebox';
2
- export interface ValueError {
3
- schema: Types.TSchema;
4
- path: string;
5
- value: unknown;
6
- message: string;
7
- }
8
- export declare namespace ValueErrors {
9
- function Errors<T extends Types.TSchema>(schema: T, references: Types.TSchema[], value: any): IterableIterator<ValueError>;
10
- }