@sinclair/typebox 0.25.7 → 0.25.9

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.
@@ -31,6 +31,7 @@ exports.TypeCompiler = exports.TypeCompilerUnknownTypeError = exports.Property =
31
31
  const index_1 = require("../errors/index");
32
32
  const index_2 = require("../guard/index");
33
33
  const index_3 = require("../format/index");
34
+ const index_4 = require("../custom/index");
34
35
  const Types = require("../typebox");
35
36
  // -------------------------------------------------------------------
36
37
  // TypeCheck
@@ -291,6 +292,9 @@ var TypeCompiler;
291
292
  function* Void(schema, value) {
292
293
  yield `(${value} === null)`;
293
294
  }
295
+ function* Kind(schema, value) {
296
+ yield `(custom('${schema[Types.Kind]}', ${value}))`;
297
+ }
294
298
  function* Visit(schema, value) {
295
299
  // Reference: Referenced schemas can originate from either additional schemas
296
300
  // or inline in the schema itself. Ideally the recursive path should align to
@@ -352,7 +356,9 @@ var TypeCompiler;
352
356
  case 'Void':
353
357
  return yield* Void(anySchema, value);
354
358
  default:
355
- throw new TypeCompilerUnknownTypeError(schema);
359
+ if (!index_4.Custom.Has(anySchema[Types.Kind]))
360
+ throw new TypeCompilerUnknownTypeError(schema);
361
+ return yield* Kind(anySchema, value);
356
362
  }
357
363
  }
358
364
  // -------------------------------------------------------------------
@@ -410,14 +416,19 @@ var TypeCompiler;
410
416
  function Compile(schema, references = []) {
411
417
  index_2.TypeGuard.Assert(schema, references);
412
418
  const code = Build(schema, references);
413
- const func1 = globalThis.Function('format', code);
414
- const func2 = func1((format, value) => {
419
+ const compiledFunction = globalThis.Function('custom', 'format', code);
420
+ const checkFunction = compiledFunction((kind, value) => {
421
+ if (!index_4.Custom.Has(kind))
422
+ return false;
423
+ const func = index_4.Custom.Get(kind);
424
+ return func(value);
425
+ }, (format, value) => {
415
426
  if (!index_3.Format.Has(format))
416
427
  return false;
417
428
  const func = index_3.Format.Get(format);
418
429
  return func(value);
419
430
  });
420
- return new TypeCheck(schema, references, func2, code);
431
+ return new TypeCheck(schema, references, checkFunction, code);
421
432
  }
422
433
  TypeCompiler.Compile = Compile;
423
434
  })(TypeCompiler = exports.TypeCompiler || (exports.TypeCompiler = {}));
@@ -49,14 +49,16 @@ var Structural;
49
49
  // ------------------------------------------------------------------------
50
50
  // Rules
51
51
  // ------------------------------------------------------------------------
52
- function AnyOrUnknownRule(right) {
52
+ function AnyUnknownOrCustomRule(right) {
53
53
  // https://github.com/microsoft/TypeScript/issues/40049
54
- if (right[Types.Kind] === 'Union' && right.anyOf.some((schema) => schema[Types.Kind] === 'Any' || schema[Types.Kind] === 'Unknown'))
54
+ if (guard_1.TypeGuard.TUnion(right) && right.anyOf.some((schema) => schema[Types.Kind] === 'Any' || schema[Types.Kind] === 'Unknown'))
55
55
  return true;
56
- if (right[Types.Kind] === 'Unknown')
56
+ if (guard_1.TypeGuard.TUnknown(right))
57
57
  return true;
58
- if (right[Types.Kind] === 'Any')
58
+ if (guard_1.TypeGuard.TAny(right))
59
59
  return true;
60
+ if (guard_1.TypeGuard.TCustom(right))
61
+ throw Error(`Structural: Cannot structurally compare custom type '${right[Types.Kind]}'`);
60
62
  return false;
61
63
  }
62
64
  function ObjectRightRule(left, right) {
@@ -132,10 +134,10 @@ var Structural;
132
134
  // Checks
133
135
  // ------------------------------------------------------------------------
134
136
  function Any(left, right) {
135
- return AnyOrUnknownRule(right) ? StructuralResult.True : StructuralResult.Union;
137
+ return AnyUnknownOrCustomRule(right) ? StructuralResult.True : StructuralResult.Union;
136
138
  }
137
139
  function Array(left, right) {
138
- if (AnyOrUnknownRule(right)) {
140
+ if (AnyUnknownOrCustomRule(right)) {
139
141
  return StructuralResult.True;
140
142
  }
141
143
  else if (guard_1.TypeGuard.TObject(right)) {
@@ -163,7 +165,7 @@ var Structural;
163
165
  }
164
166
  }
165
167
  function Boolean(left, right) {
166
- if (AnyOrUnknownRule(right)) {
168
+ if (AnyUnknownOrCustomRule(right)) {
167
169
  return StructuralResult.True;
168
170
  }
169
171
  else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
@@ -180,7 +182,7 @@ var Structural;
180
182
  }
181
183
  }
182
184
  function Constructor(left, right) {
183
- if (AnyOrUnknownRule(right)) {
185
+ if (AnyUnknownOrCustomRule(right)) {
184
186
  return StructuralResult.True;
185
187
  }
186
188
  else if (guard_1.TypeGuard.TObject(right) && globalThis.Object.keys(right.properties).length === 0) {
@@ -205,7 +207,7 @@ var Structural;
205
207
  }
206
208
  }
207
209
  function Date(left, right) {
208
- if (AnyOrUnknownRule(right)) {
210
+ if (AnyUnknownOrCustomRule(right)) {
209
211
  return StructuralResult.True;
210
212
  }
211
213
  else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
@@ -225,7 +227,7 @@ var Structural;
225
227
  }
226
228
  }
227
229
  function Function(left, right) {
228
- if (AnyOrUnknownRule(right)) {
230
+ if (AnyUnknownOrCustomRule(right)) {
229
231
  return StructuralResult.True;
230
232
  }
231
233
  else if (guard_1.TypeGuard.TObject(right)) {
@@ -254,7 +256,7 @@ var Structural;
254
256
  }
255
257
  }
256
258
  function Integer(left, right) {
257
- if (AnyOrUnknownRule(right)) {
259
+ if (AnyUnknownOrCustomRule(right)) {
258
260
  return StructuralResult.True;
259
261
  }
260
262
  else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
@@ -271,7 +273,7 @@ var Structural;
271
273
  }
272
274
  }
273
275
  function Literal(left, right) {
274
- if (AnyOrUnknownRule(right)) {
276
+ if (AnyUnknownOrCustomRule(right)) {
275
277
  return StructuralResult.True;
276
278
  }
277
279
  else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
@@ -308,7 +310,7 @@ var Structural;
308
310
  }
309
311
  }
310
312
  function Number(left, right) {
311
- if (AnyOrUnknownRule(right)) {
313
+ if (AnyUnknownOrCustomRule(right)) {
312
314
  return StructuralResult.True;
313
315
  }
314
316
  else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
@@ -328,7 +330,7 @@ var Structural;
328
330
  }
329
331
  }
330
332
  function Null(left, right) {
331
- if (AnyOrUnknownRule(right)) {
333
+ if (AnyUnknownOrCustomRule(right)) {
332
334
  return StructuralResult.True;
333
335
  }
334
336
  else if (guard_1.TypeGuard.TNull(right)) {
@@ -356,7 +358,7 @@ var Structural;
356
358
  return StructuralResult.True;
357
359
  }
358
360
  function Object(left, right) {
359
- if (AnyOrUnknownRule(right)) {
361
+ if (AnyUnknownOrCustomRule(right)) {
360
362
  return StructuralResult.True;
361
363
  }
362
364
  else if (guard_1.TypeGuard.TObject(right)) {
@@ -375,7 +377,7 @@ var Structural;
375
377
  }
376
378
  }
377
379
  function Promise(left, right) {
378
- if (AnyOrUnknownRule(right)) {
380
+ if (AnyUnknownOrCustomRule(right)) {
379
381
  return StructuralResult.True;
380
382
  }
381
383
  else if (guard_1.TypeGuard.TObject(right)) {
@@ -395,7 +397,7 @@ var Structural;
395
397
  }
396
398
  }
397
399
  function Record(left, right) {
398
- if (AnyOrUnknownRule(right)) {
400
+ if (AnyUnknownOrCustomRule(right)) {
399
401
  return StructuralResult.True;
400
402
  }
401
403
  else if (guard_1.TypeGuard.TObject(right)) {
@@ -444,7 +446,7 @@ var Structural;
444
446
  return Visit(resolved, right);
445
447
  }
446
448
  function String(left, right) {
447
- if (AnyOrUnknownRule(right)) {
449
+ if (AnyUnknownOrCustomRule(right)) {
448
450
  return StructuralResult.True;
449
451
  }
450
452
  else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
@@ -464,7 +466,7 @@ var Structural;
464
466
  }
465
467
  }
466
468
  function Tuple(left, right) {
467
- if (AnyOrUnknownRule(right)) {
469
+ if (AnyUnknownOrCustomRule(right)) {
468
470
  return StructuralResult.True;
469
471
  }
470
472
  else if (guard_1.TypeGuard.TObject(right)) {
@@ -508,7 +510,7 @@ var Structural;
508
510
  return StructuralResult.True;
509
511
  }
510
512
  function Uint8Array(left, right) {
511
- if (AnyOrUnknownRule(right)) {
513
+ if (AnyUnknownOrCustomRule(right)) {
512
514
  return StructuralResult.True;
513
515
  }
514
516
  else if (guard_1.TypeGuard.TObject(right) && ObjectRightRule(left, right)) {
@@ -528,7 +530,7 @@ var Structural;
528
530
  }
529
531
  }
530
532
  function Undefined(left, right) {
531
- if (AnyOrUnknownRule(right)) {
533
+ if (AnyUnknownOrCustomRule(right)) {
532
534
  return StructuralResult.True;
533
535
  }
534
536
  else if (guard_1.TypeGuard.TUndefined(right)) {
@@ -666,6 +668,9 @@ var Structural;
666
668
  else if (guard_1.TypeGuard.TVoid(left)) {
667
669
  return Void(left, resolvedRight);
668
670
  }
671
+ else if (guard_1.TypeGuard.TCustom(left)) {
672
+ throw Error(`Structural: Cannot structurally compare custom type '${left[Types.Kind]}'`);
673
+ }
669
674
  else {
670
675
  throw Error(`Structural: Unknown left operand '${left[Types.Kind]}'`);
671
676
  }
@@ -0,0 +1,12 @@
1
+ export declare type CustomValidationFunction = (value: unknown) => boolean;
2
+ /** Provides functions to create custom types */
3
+ export declare namespace Custom {
4
+ /** Clears all custom types */
5
+ function Clear(): void;
6
+ /** Returns true if this kind exists */
7
+ function Has(kind: string): boolean;
8
+ /** Sets a validation function for a custom kind */
9
+ function Set(kind: string, func: CustomValidationFunction): void;
10
+ /** Gets a custom validation function */
11
+ function Get(kind: string): CustomValidationFunction | undefined;
12
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /*--------------------------------------------------------------------------
3
+
4
+ @sinclair/typebox/custom
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.Custom = void 0;
31
+ /** Provides functions to create custom types */
32
+ var Custom;
33
+ (function (Custom) {
34
+ const customs = new Map();
35
+ /** Clears all custom types */
36
+ function Clear() {
37
+ return customs.clear();
38
+ }
39
+ Custom.Clear = Clear;
40
+ /** Returns true if this kind exists */
41
+ function Has(kind) {
42
+ return customs.has(kind);
43
+ }
44
+ Custom.Has = Has;
45
+ /** Sets a validation function for a custom kind */
46
+ function Set(kind, func) {
47
+ customs.set(kind, func);
48
+ }
49
+ Custom.Set = Set;
50
+ /** Gets a custom validation function */
51
+ function Get(kind) {
52
+ return customs.get(kind);
53
+ }
54
+ Custom.Get = Get;
55
+ })(Custom = exports.Custom || (exports.Custom = {}));
@@ -0,0 +1 @@
1
+ export * from './custom';
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /*--------------------------------------------------------------------------
3
+
4
+ @sinclair/typebox/custom
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
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ var desc = Object.getOwnPropertyDescriptor(m, k);
32
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
33
+ desc = { enumerable: true, get: function() { return m[k]; } };
34
+ }
35
+ Object.defineProperty(o, k2, desc);
36
+ }) : (function(o, m, k, k2) {
37
+ if (k2 === undefined) k2 = k;
38
+ o[k2] = m[k];
39
+ }));
40
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
41
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ __exportStar(require("./custom"), exports);
@@ -47,7 +47,8 @@ export declare enum ValueErrorType {
47
47
  Uint8Array = 44,
48
48
  Uint8ArrayMinByteLength = 45,
49
49
  Uint8ArrayMaxByteLength = 46,
50
- Void = 47
50
+ Void = 47,
51
+ Custom = 48
51
52
  }
52
53
  export interface ValueError {
53
54
  type: ValueErrorType;
package/errors/errors.js CHANGED
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ValueErrors = exports.ValueErrorsUnknownTypeError = exports.ValueErrorType = void 0;
31
31
  const Types = require("../typebox");
32
32
  const index_1 = require("../format/index");
33
+ const index_2 = require("../custom/index");
33
34
  // -------------------------------------------------------------------
34
35
  // ValueErrorType
35
36
  // -------------------------------------------------------------------
@@ -83,6 +84,7 @@ var ValueErrorType;
83
84
  ValueErrorType[ValueErrorType["Uint8ArrayMinByteLength"] = 45] = "Uint8ArrayMinByteLength";
84
85
  ValueErrorType[ValueErrorType["Uint8ArrayMaxByteLength"] = 46] = "Uint8ArrayMaxByteLength";
85
86
  ValueErrorType[ValueErrorType["Void"] = 47] = "Void";
87
+ ValueErrorType[ValueErrorType["Custom"] = 48] = "Custom";
86
88
  })(ValueErrorType = exports.ValueErrorType || (exports.ValueErrorType = {}));
87
89
  // -------------------------------------------------------------------
88
90
  // ValueErrors
@@ -365,6 +367,12 @@ var ValueErrors;
365
367
  return yield { type: ValueErrorType.Void, schema, path, value, message: `Expected null` };
366
368
  }
367
369
  }
370
+ function* CustomType(schema, references, path, value) {
371
+ const func = index_2.Custom.Get(schema[Types.Kind]);
372
+ if (!func(value)) {
373
+ return yield { type: ValueErrorType.Custom, schema, path, value, message: `Expected kind ${schema[Types.Kind]}` };
374
+ }
375
+ }
368
376
  function* Visit(schema, references, path, value) {
369
377
  const anyReferences = schema.$id === undefined ? references : [schema, ...references];
370
378
  const anySchema = schema;
@@ -416,7 +424,9 @@ var ValueErrors;
416
424
  case 'Void':
417
425
  return yield* Void(anySchema, anyReferences, path, value);
418
426
  default:
419
- throw new ValueErrorsUnknownTypeError(schema);
427
+ if (!index_2.Custom.Has(anySchema[Types.Kind]))
428
+ throw new ValueErrorsUnknownTypeError(schema);
429
+ return yield* CustomType(anySchema, anyReferences, path, value);
420
430
  }
421
431
  }
422
432
  function* Errors(schema, references, value) {
package/guard/guard.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as Types from '../typebox';
2
- export declare class TypeGuardInvalidTypeError extends Error {
2
+ export declare class TypeGuardUnknownTypeError extends Error {
3
3
  readonly schema: unknown;
4
4
  constructor(schema: unknown);
5
5
  }
@@ -51,6 +51,8 @@ export declare namespace TypeGuard {
51
51
  function TUnknown(schema: unknown): schema is Types.TUnknown;
52
52
  /** Returns true if the given schema is TVoid */
53
53
  function TVoid(schema: unknown): schema is Types.TVoid;
54
+ /** Returns true if the given schema is a registered custom type */
55
+ function TCustom(schema: unknown): schema is Types.TSchema;
54
56
  /** Returns true if the given schema is TSchema */
55
57
  function TSchema(schema: unknown): schema is Types.TSchema;
56
58
  /** Asserts if this schema and associated references are valid. */
package/guard/guard.js CHANGED
@@ -27,15 +27,16 @@ THE SOFTWARE.
27
27
 
28
28
  ---------------------------------------------------------------------------*/
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.TypeGuard = exports.TypeGuardInvalidTypeError = void 0;
30
+ exports.TypeGuard = exports.TypeGuardUnknownTypeError = void 0;
31
+ const index_1 = require("../custom/index");
31
32
  const Types = require("../typebox");
32
- class TypeGuardInvalidTypeError extends Error {
33
+ class TypeGuardUnknownTypeError extends Error {
33
34
  constructor(schema) {
34
- super('TypeGuard: Invalid type');
35
+ super('TypeGuard: Unknown type');
35
36
  this.schema = schema;
36
37
  }
37
38
  }
38
- exports.TypeGuardInvalidTypeError = TypeGuardInvalidTypeError;
39
+ exports.TypeGuardUnknownTypeError = TypeGuardUnknownTypeError;
39
40
  /** Provides functionality to test if values are TypeBox types */
40
41
  var TypeGuard;
41
42
  (function (TypeGuard) {
@@ -393,6 +394,11 @@ var TypeGuard;
393
394
  IsOptionalString(schema.$id));
394
395
  }
395
396
  TypeGuard.TVoid = TVoid;
397
+ /** Returns true if the given schema is a registered custom type */
398
+ function TCustom(schema) {
399
+ return IsObject(schema) && IsString(schema[Types.Kind]) && index_1.Custom.Has(schema[Types.Kind]);
400
+ }
401
+ TypeGuard.TCustom = TCustom;
396
402
  /** Returns true if the given schema is TSchema */
397
403
  function TSchema(schema) {
398
404
  return (TAny(schema) ||
@@ -417,16 +423,17 @@ var TypeGuard;
417
423
  TUnion(schema) ||
418
424
  TUint8Array(schema) ||
419
425
  TUnknown(schema) ||
420
- TVoid(schema));
426
+ TVoid(schema) ||
427
+ TCustom(schema));
421
428
  }
422
429
  TypeGuard.TSchema = TSchema;
423
430
  /** Asserts if this schema and associated references are valid. */
424
431
  function Assert(schema, references = []) {
425
432
  if (!TSchema(schema))
426
- throw new TypeGuardInvalidTypeError(schema);
433
+ throw new TypeGuardUnknownTypeError(schema);
427
434
  for (const schema of references) {
428
435
  if (!TSchema(schema))
429
- throw new TypeGuardInvalidTypeError(schema);
436
+ throw new TypeGuardUnknownTypeError(schema);
430
437
  }
431
438
  }
432
439
  TypeGuard.Assert = Assert;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.25.7",
3
+ "version": "0.25.9",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
@@ -12,6 +12,16 @@
12
12
  "license": "MIT",
13
13
  "main": "./typebox.js",
14
14
  "types": "./typebox.d.ts",
15
+ "exports": {
16
+ "./compiler": "./compiler/index.js",
17
+ "./conditional": "./conditional/index.js",
18
+ "./custom": "./custom/index.js",
19
+ "./errors": "./errors/index.js",
20
+ "./format": "./format/index.js",
21
+ "./guard": "./guard/index.js",
22
+ "./value": "./value/index.js",
23
+ ".": "./typebox.js"
24
+ },
15
25
  "repository": {
16
26
  "type": "git",
17
27
  "url": "https://github.com/sinclairzx81/typebox"
package/readme.md CHANGED
@@ -19,28 +19,45 @@
19
19
 
20
20
  ## Install
21
21
 
22
- Node
23
-
22
+ ### npm
24
23
  ```bash
25
24
  $ npm install @sinclair/typebox --save
26
25
  ```
27
26
 
28
- Deno and ESM
27
+ ### deno
28
+ ```typescript
29
+ import { Static, Type } from 'npm:@sinclair/typebox'
30
+ ```
31
+
32
+ ### esm
29
33
 
30
34
  ```typescript
31
35
  import { Static, Type } from 'https://esm.sh/@sinclair/typebox'
32
36
  ```
33
37
 
34
- ## Example
38
+ ## Usage
35
39
 
36
40
  ```typescript
37
41
  import { Static, Type } from '@sinclair/typebox'
38
42
 
39
- const T = Type.String() // const T = { type: 'string' }
43
+ const T = Type.Object({ // const T = {
44
+ x: Type.Number(), // type: 'object',
45
+ y: Type.Number(), // required: ['x', 'y', 'z'],
46
+ z: Type.Number() // properties: {
47
+ }) // x: { type: 'number' },
48
+ // y: { type: 'number' },
49
+ // z: { type: 'number' }
50
+ // }
51
+ // }
40
52
 
41
- type T = Static<typeof T> // type T = string
53
+ type T = Static<typeof T> // type T = {
54
+ // x: number,
55
+ // y: number,
56
+ // z: number
57
+ // }
42
58
  ```
43
59
 
60
+
44
61
  <a name="Overview"></a>
45
62
 
46
63
  ## Overview
@@ -54,7 +71,7 @@ License MIT
54
71
  ## Contents
55
72
  - [Install](#install)
56
73
  - [Overview](#overview)
57
- - [Usage](#usage)
74
+ - [Example](#Example)
58
75
  - [Types](#types)
59
76
  - [Standard Types](#types-standard)
60
77
  - [Extended Types](#types-extended)
@@ -80,6 +97,7 @@ License MIT
80
97
  - [TypeCheck](#typecheck)
81
98
  - [Ajv](#typecheck-ajv)
82
99
  - [TypeCompiler](#typecheck-typecompiler)
100
+ - [Custom](#typecheck-custom)
83
101
  - [Formats](#typecheck-formats)
84
102
  - [Benchmark](#benchmark)
85
103
  - [Compile](#benchmark-compile)
@@ -89,7 +107,7 @@ License MIT
89
107
 
90
108
  <a name="Example"></a>
91
109
 
92
- ## Usage
110
+ ## Example
93
111
 
94
112
  The following demonstrates TypeBox's general usage.
95
113
 
@@ -1100,6 +1118,30 @@ console.log(C.Code()) // return function check(va
1100
1118
  // }
1101
1119
  ```
1102
1120
 
1121
+ <a name='typecheck-custom'></a>
1122
+
1123
+ ### Custom
1124
+
1125
+ Use custom module to create a custom types. When creating a custom type you must specify a `Kind` symbol property on the types schema. The `Kind` symbol property should match the name used to register the type. Custom types are used by the Value and TypeCompiler modules only.
1126
+
1127
+ The custom module is an optional import.
1128
+
1129
+ ```typescript
1130
+ import { Custom } from '@sinclair/typebox/custom'
1131
+ ```
1132
+
1133
+ The following registers a BigInt custom type.
1134
+
1135
+ ```typescript
1136
+ import { Type, Kind } from '@sinclair/typebox'
1137
+
1138
+ Custom.Set('BigInt', value => typeof value === 'bigint')
1139
+
1140
+ const T = Type.Unsafe<bigint>({ [Kind]: 'BigInt' }) // const T = { [Kind]: 'BigInt' }
1141
+
1142
+ const R = Value.Check(T, 65536n) // const R = true
1143
+ ```
1144
+
1103
1145
  <a name='typecheck-formats'></a>
1104
1146
 
1105
1147
  ### Formats
@@ -1146,29 +1188,29 @@ This benchmark measures compilation performance for varying types. You can revie
1146
1188
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┐
1147
1189
  │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │
1148
1190
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┤
1149
- │ Number │ 2000 │ ' 421 ms' │ ' 11 ms' │ ' 38.27 x' │
1150
- │ String │ 2000 │ ' 332 ms' │ ' 11 ms' │ ' 30.18 x' │
1151
- │ Boolean │ 2000 │ ' 291 ms' │ ' 12 ms' │ ' 24.25 x' │
1152
- │ Null │ 2000 │ ' 266 ms' │ ' 9 ms' │ ' 29.56 x' │
1153
- │ RegEx │ 2000 │ ' 486 ms' │ ' 17 ms' │ ' 28.59 x' │
1154
- │ ObjectA │ 2000 │ ' 2791 ms' │ ' 50 ms' │ ' 55.82 x' │
1155
- │ ObjectB │ 2000 │ ' 2896 ms' │ ' 37 ms' │ ' 78.27 x' │
1156
- │ Tuple │ 2000 │ ' 1244 ms' │ ' 21 ms' │ ' 59.24 x' │
1157
- │ Union │ 2000 │ ' 1258 ms' │ ' 25 ms' │ ' 50.32 x' │
1158
- │ Vector4 │ 2000 │ ' 1513 ms' │ ' 21 ms' │ ' 72.05 x' │
1159
- │ Matrix4 │ 2000 │ ' 850 ms' │ ' 11 ms' │ ' 77.27 x' │
1160
- │ Literal_String │ 2000 │ ' 335 ms' │ ' 7 ms' │ ' 47.86 x' │
1161
- │ Literal_Number │ 2000 │ ' 358 ms' │ ' 7 ms' │ ' 51.14 x' │
1162
- │ Literal_Boolean │ 2000 │ ' 356 ms' │ ' 7 ms' │ ' 50.86 x' │
1163
- │ Array_Number │ 2000 │ ' 689 ms' │ ' 9 ms' │ ' 76.56 x' │
1164
- │ Array_String │ 2000 │ ' 728 ms' │ ' 12 ms' │ ' 60.67 x' │
1165
- │ Array_Boolean │ 2000 │ ' 726 ms' │ ' 7 ms' │ ' 103.71 x' │
1166
- │ Array_ObjectA │ 2000 │ ' 3631 ms' │ ' 35 ms' │ ' 103.74 x' │
1167
- │ Array_ObjectB │ 2000 │ ' 3636 ms' │ ' 40 ms' │ ' 90.90 x' │
1168
- │ Array_Tuple │ 2000 │ ' 2119 ms' │ ' 31 ms' │ ' 68.35 x' │
1169
- │ Array_Union │ 2000 │ ' 1550 ms' │ ' 23 ms' │ ' 67.39 x' │
1170
- │ Array_Vector4 │ 2000 │ ' 2200 ms' │ ' 18 ms' │ ' 122.22 x' │
1171
- │ Array_Matrix4 │ 2000 │ ' 1494 ms' │ ' 14 ms' │ ' 106.71 x' │
1191
+ │ Number │ 2000 │ ' 427 ms' │ ' 13 ms' │ ' 32.85 x' │
1192
+ │ String │ 2000 │ ' 367 ms' │ ' 12 ms' │ ' 30.58 x' │
1193
+ │ Boolean │ 2000 │ ' 297 ms' │ ' 13 ms' │ ' 22.85 x' │
1194
+ │ Null │ 2000 │ ' 255 ms' │ ' 9 ms' │ ' 28.33 x' │
1195
+ │ RegEx │ 2000 │ ' 487 ms' │ ' 17 ms' │ ' 28.65 x' │
1196
+ │ ObjectA │ 2000 │ ' 2718 ms' │ ' 53 ms' │ ' 51.28 x' │
1197
+ │ ObjectB │ 2000 │ ' 2874 ms' │ ' 36 ms' │ ' 79.83 x' │
1198
+ │ Tuple │ 2000 │ ' 1221 ms' │ ' 22 ms' │ ' 55.50 x' │
1199
+ │ Union │ 2000 │ ' 1223 ms' │ ' 24 ms' │ ' 50.96 x' │
1200
+ │ Vector4 │ 2000 │ ' 1517 ms' │ ' 21 ms' │ ' 72.24 x' │
1201
+ │ Matrix4 │ 2000 │ ' 830 ms' │ ' 10 ms' │ ' 83.00 x' │
1202
+ │ Literal_String │ 2000 │ ' 334 ms' │ ' 8 ms' │ ' 41.75 x' │
1203
+ │ Literal_Number │ 2000 │ ' 357 ms' │ ' 6 ms' │ ' 59.50 x' │
1204
+ │ Literal_Boolean │ 2000 │ ' 353 ms' │ ' 7 ms' │ ' 50.43 x' │
1205
+ │ Array_Number │ 2000 │ ' 679 ms' │ ' 11 ms' │ ' 61.73 x' │
1206
+ │ Array_String │ 2000 │ ' 713 ms' │ ' 10 ms' │ ' 71.30 x' │
1207
+ │ Array_Boolean │ 2000 │ ' 710 ms' │ ' 7 ms' │ ' 101.43 x' │
1208
+ │ Array_ObjectA │ 2000 │ ' 3571 ms' │ ' 35 ms' │ ' 102.03 x' │
1209
+ │ Array_ObjectB │ 2000 │ ' 3567 ms' │ ' 41 ms' │ ' 87.00 x' │
1210
+ │ Array_Tuple │ 2000 │ ' 2083 ms' │ ' 19 ms' │ ' 109.63 x' │
1211
+ │ Array_Union │ 2000 │ ' 1559 ms' │ ' 23 ms' │ ' 67.78 x' │
1212
+ │ Array_Vector4 │ 2000 │ ' 2156 ms' │ ' 19 ms' │ ' 113.47 x' │
1213
+ │ Array_Matrix4 │ 2000 │ ' 1483 ms' │ ' 13 ms' │ ' 114.08 x' │
1172
1214
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┘
1173
1215
  ```
1174
1216
 
@@ -1182,31 +1224,31 @@ This benchmark measures validation performance for varying types. You can review
1182
1224
  ┌──────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
1183
1225
  │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │
1184
1226
  ├──────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
1185
- │ Number │ 1000000 │ ' 28 ms' │ ' 6 ms' │ ' 6 ms' │ ' 1.00 x' │
1186
- │ String │ 1000000 │ ' 25 ms' │ ' 20 ms' │ ' 11 ms' │ ' 1.82 x' │
1187
- │ Boolean │ 1000000 │ ' 34 ms' │ ' 22 ms' │ ' 13 ms' │ ' 1.69 x' │
1188
- │ Null │ 1000000 │ ' 37 ms' │ ' 28 ms' │ ' 10 ms' │ ' 2.80 x' │
1189
- │ RegEx │ 1000000 │ ' 162 ms' │ ' 50 ms' │ ' 37 ms' │ ' 1.35 x' │
1190
- │ ObjectA │ 1000000 │ ' 550 ms' │ ' 38 ms' │ ' 22 ms' │ ' 1.73 x' │
1191
- │ ObjectB │ 1000000 │ ' 1033 ms' │ ' 58 ms' │ ' 38 ms' │ ' 1.53 x' │
1192
- │ Tuple │ 1000000 │ ' 126 ms' │ ' 24 ms' │ ' 14 ms' │ ' 1.71 x' │
1193
- │ Union │ 1000000 │ ' 326 ms' │ ' 25 ms' │ ' 16 ms' │ ' 1.56 x' │
1194
- │ Recursive │ 1000000 │ ' 3089 ms' │ ' 436 ms' │ ' 101 ms' │ ' 4.32 x' │
1195
- │ Vector4 │ 1000000 │ ' 155 ms' │ ' 24 ms' │ ' 12 ms' │ ' 2.00 x' │
1196
- │ Matrix4 │ 1000000 │ ' 579 ms' │ ' 41 ms' │ ' 28 ms' │ ' 1.46 x' │
1197
- │ Literal_String │ 1000000 │ ' 50 ms' │ ' 21 ms' │ ' 13 ms' │ ' 1.62 x' │
1198
- │ Literal_Number │ 1000000 │ ' 46 ms' │ ' 22 ms' │ ' 11 ms' │ ' 2.00 x' │
1227
+ │ Number │ 1000000 │ ' 25 ms' │ ' 6 ms' │ ' 5 ms' │ ' 1.20 x' │
1228
+ │ String │ 1000000 │ ' 22 ms' │ ' 20 ms' │ ' 11 ms' │ ' 1.82 x' │
1229
+ │ Boolean │ 1000000 │ ' 21 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
1230
+ │ Null │ 1000000 │ ' 24 ms' │ ' 21 ms' │ ' 9 ms' │ ' 2.33 x' │
1231
+ │ RegEx │ 1000000 │ ' 158 ms' │ ' 46 ms' │ ' 37 ms' │ ' 1.24 x' │
1232
+ │ ObjectA │ 1000000 │ ' 566 ms' │ ' 36 ms' │ ' 24 ms' │ ' 1.50 x' │
1233
+ │ ObjectB │ 1000000 │ ' 1026 ms' │ ' 52 ms' │ ' 40 ms' │ ' 1.30 x' │
1234
+ │ Tuple │ 1000000 │ ' 121 ms' │ ' 23 ms' │ ' 14 ms' │ ' 1.64 x' │
1235
+ │ Union │ 1000000 │ ' 299 ms' │ ' 26 ms' │ ' 16 ms' │ ' 1.63 x' │
1236
+ │ Recursive │ 1000000 │ ' 3168 ms' │ ' 414 ms' │ ' 97 ms' │ ' 4.27 x' │
1237
+ │ Vector4 │ 1000000 │ ' 147 ms' │ ' 22 ms' │ ' 11 ms' │ ' 2.00 x' │
1238
+ │ Matrix4 │ 1000000 │ ' 573 ms' │ ' 40 ms' │ ' 29 ms' │ ' 1.38 x' │
1239
+ │ Literal_String │ 1000000 │ ' 48 ms' │ ' 19 ms' │ ' 10 ms' │ ' 1.90 x' │
1240
+ │ Literal_Number │ 1000000 │ ' 46 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
1199
1241
  │ Literal_Boolean │ 1000000 │ ' 48 ms' │ ' 20 ms' │ ' 10 ms' │ ' 2.00 x' │
1200
- │ Array_Number │ 1000000 │ ' 424 ms' │ ' 32 ms' │ ' 19 ms' │ ' 1.68 x' │
1201
- │ Array_String │ 1000000 │ ' 483 ms' │ ' 34 ms' │ ' 28 ms' │ ' 1.21 x' │
1202
- │ Array_Boolean │ 1000000 │ ' 432 ms' │ ' 35 ms' │ ' 26 ms' │ ' 1.35 x' │
1203
- │ Array_ObjectA │ 1000000 │ ' 13895 ms' │ ' 2440 ms' │ ' 1495 ms' │ ' 1.63 x' │
1204
- │ Array_ObjectB │ 1000000 │ ' 16261 ms' │ ' 2633 ms' │ ' 2011 ms' │ ' 1.31 x' │
1205
- │ Array_Tuple │ 1000000 │ ' 1741 ms' │ ' 98 ms' │ ' 66 ms' │ ' 1.48 x' │
1206
- │ Array_Union │ 1000000 │ ' 4825 ms' │ ' 232 ms' │ ' 87 ms' │ ' 2.67 x' │
1207
- │ Array_Recursive │ 1000000 │ ' 54158 ms' │ ' 6966 ms' │ ' 1173 ms' │ ' 5.94 x' │
1208
- │ Array_Vector4 │ 1000000 │ ' 2577 ms' │ ' 99 ms' │ ' 48 ms' │ ' 2.06 x' │
1209
- │ Array_Matrix4 │ 1000000 │ ' 12648 ms' │ ' 397 ms' │ ' 249 ms' │ ' 1.59 x' │
1242
+ │ Array_Number │ 1000000 │ ' 454 ms' │ ' 32 ms' │ ' 18 ms' │ ' 1.78 x' │
1243
+ │ Array_String │ 1000000 │ ' 481 ms' │ ' 32 ms' │ ' 22 ms' │ ' 1.45 x' │
1244
+ │ Array_Boolean │ 1000000 │ ' 448 ms' │ ' 34 ms' │ ' 27 ms' │ ' 1.26 x' │
1245
+ │ Array_ObjectA │ 1000000 │ ' 13709 ms' │ ' 2360 ms' │ ' 1548 ms' │ ' 1.52 x' │
1246
+ │ Array_ObjectB │ 1000000 │ ' 16602 ms' │ ' 2585 ms' │ ' 1904 ms' │ ' 1.36 x' │
1247
+ │ Array_Tuple │ 1000000 │ ' 1831 ms' │ ' 96 ms' │ ' 63 ms' │ ' 1.52 x' │
1248
+ │ Array_Union │ 1000000 │ ' 4958 ms' │ ' 234 ms' │ ' 86 ms' │ ' 2.72 x' │
1249
+ │ Array_Recursive │ 1000000 │ ' 55876 ms' │ ' 7160 ms' │ ' 1138 ms' │ ' 6.29 x' │
1250
+ │ Array_Vector4 │ 1000000 │ ' 2381 ms' │ ' 99 ms' │ ' 47 ms' │ ' 2.11 x' │
1251
+ │ Array_Matrix4 │ 1000000 │ ' 11670 ms' │ ' 383 ms' │ ' 228 ms' │ ' 1.68 x' │
1210
1252
  └──────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
1211
1253
  ```
1212
1254
 
@@ -1220,11 +1262,12 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
1220
1262
  ┌──────────────────────┬────────────┬────────────┬─────────────┐
1221
1263
  │ (index) │ Compiled │ Minified │ Compression │
1222
1264
  ├──────────────────────┼────────────┼────────────┼─────────────┤
1223
- │ typebox/compiler │ ' 54 kb' │ ' 27 kb' │ '1.97 x' │
1224
- │ typebox/conditional │ ' 44 kb' │ ' 17 kb' │ '2.45 x' │
1265
+ │ typebox/compiler │ ' 55 kb' │ ' 27 kb' │ '2.00 x' │
1266
+ │ typebox/conditional │ ' 45 kb' │ ' 18 kb' │ '2.44 x' │
1267
+ │ typebox/custom │ ' 0 kb' │ ' 0 kb' │ '2.61 x' │
1225
1268
  │ typebox/format │ ' 0 kb' │ ' 0 kb' │ '2.66 x' │
1226
- │ typebox/guard │ ' 22 kb' │ ' 11 kb' │ '2.05 x' │
1227
- │ typebox/value │ ' 78 kb' │ ' 36 kb' │ '2.13 x' │
1269
+ │ typebox/guard │ ' 23 kb' │ ' 11 kb' │ '2.07 x' │
1270
+ │ typebox/value │ ' 80 kb' │ ' 37 kb' │ '2.15 x' │
1228
1271
  │ typebox │ ' 12 kb' │ ' 6 kb' │ '1.89 x' │
1229
1272
  └──────────────────────┴────────────┴────────────┴─────────────┘
1230
1273
  ```
package/value/cast.js CHANGED
@@ -32,6 +32,7 @@ const Types = require("../typebox");
32
32
  const create_1 = require("./create");
33
33
  const check_1 = require("./check");
34
34
  const clone_1 = require("./clone");
35
+ const index_1 = require("../custom/index");
35
36
  // ----------------------------------------------------------------------------------------------
36
37
  // Errors
37
38
  // ----------------------------------------------------------------------------------------------
@@ -306,6 +307,9 @@ var ValueCast;
306
307
  function Void(schema, references, value) {
307
308
  return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references);
308
309
  }
310
+ function Kind(schema, references, value) {
311
+ return check_1.ValueCheck.Check(schema, references, value) ? clone_1.ValueClone.Clone(value) : create_1.ValueCreate.Create(schema, references);
312
+ }
309
313
  function Visit(schema, references, value) {
310
314
  const anyReferences = schema.$id === undefined ? references : [schema, ...references];
311
315
  const anySchema = schema;
@@ -359,7 +363,9 @@ var ValueCast;
359
363
  case 'Void':
360
364
  return Void(anySchema, anyReferences, value);
361
365
  default:
362
- throw new ValueCastUnknownTypeError(anySchema);
366
+ if (!index_1.Custom.Has(anySchema[Types.Kind]))
367
+ throw new ValueCastUnknownTypeError(anySchema);
368
+ return Kind(anySchema, anyReferences, value);
363
369
  }
364
370
  }
365
371
  ValueCast.Visit = Visit;
package/value/check.js CHANGED
@@ -29,7 +29,8 @@ THE SOFTWARE.
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ValueCheck = exports.ValueCheckUnknownTypeError = void 0;
31
31
  const Types = require("../typebox");
32
- const format_1 = require("../format");
32
+ const index_1 = require("../format/index");
33
+ const index_2 = require("../custom/index");
33
34
  class ValueCheckUnknownTypeError extends Error {
34
35
  constructor(schema) {
35
36
  super('ValueCheck: Unknown type');
@@ -240,9 +241,9 @@ var ValueCheck;
240
241
  return false;
241
242
  }
242
243
  if (schema.format !== undefined) {
243
- if (!format_1.Format.Has(schema.format))
244
+ if (!index_1.Format.Has(schema.format))
244
245
  return false;
245
- const func = format_1.Format.Get(schema.format);
246
+ const func = index_1.Format.Get(schema.format);
246
247
  return func(value);
247
248
  }
248
249
  return true;
@@ -290,6 +291,12 @@ var ValueCheck;
290
291
  function Void(schema, references, value) {
291
292
  return value === null;
292
293
  }
294
+ function Kind(schema, references, value) {
295
+ if (!index_2.Custom.Has(schema[Types.Kind]))
296
+ return false;
297
+ const func = index_2.Custom.Get(schema[Types.Kind]);
298
+ return func(value);
299
+ }
293
300
  function Visit(schema, references, value) {
294
301
  const anyReferences = schema.$id === undefined ? references : [schema, ...references];
295
302
  const anySchema = schema;
@@ -341,7 +348,9 @@ var ValueCheck;
341
348
  case 'Void':
342
349
  return Void(anySchema, anyReferences, value);
343
350
  default:
344
- throw new ValueCheckUnknownTypeError(anySchema);
351
+ if (!index_2.Custom.Has(anySchema[Types.Kind]))
352
+ throw new ValueCheckUnknownTypeError(anySchema);
353
+ return Kind(anySchema, anyReferences, value);
345
354
  }
346
355
  }
347
356
  // -------------------------------------------------------------------------
package/value/create.js CHANGED
@@ -29,6 +29,7 @@ THE SOFTWARE.
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ValueCreate = exports.ValueCreateNeverTypeError = exports.ValueCreateUnknownTypeError = void 0;
31
31
  const Types = require("../typebox");
32
+ const index_1 = require("../custom/index");
32
33
  class ValueCreateUnknownTypeError extends Error {
33
34
  constructor(schema) {
34
35
  super('ValueCreate: Unknown type');
@@ -292,6 +293,14 @@ var ValueCreate;
292
293
  function Void(schema, references) {
293
294
  return null;
294
295
  }
296
+ function Kind(schema, references) {
297
+ if (schema.default !== undefined) {
298
+ return schema.default;
299
+ }
300
+ else {
301
+ throw new Error('ValueCreate.Kind: Custom types must specify a default value');
302
+ }
303
+ }
295
304
  /** Creates a value from the given schema. If the schema specifies a default value, then that value is returned. */
296
305
  function Visit(schema, references) {
297
306
  const anyReferences = schema.$id === undefined ? references : [schema, ...references];
@@ -346,7 +355,9 @@ var ValueCreate;
346
355
  case 'Void':
347
356
  return Void(anySchema, anyReferences);
348
357
  default:
349
- throw new ValueCreateUnknownTypeError(anySchema);
358
+ if (!index_1.Custom.Has(anySchema[Types.Kind]))
359
+ throw new ValueCreateUnknownTypeError(anySchema);
360
+ return Kind(anySchema, anyReferences);
350
361
  }
351
362
  }
352
363
  ValueCreate.Visit = Visit;