@sinclair/typebox 0.20.3 → 0.21.0

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.
Files changed (4) hide show
  1. package/package.json +4 -4
  2. package/readme.md +58 -14
  3. package/typebox.d.ts +109 -125
  4. package/typebox.js +35 -36
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.20.3",
3
+ "version": "0.21.0",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "json-schema",
@@ -23,14 +23,14 @@
23
23
  "test": "hammer task spec"
24
24
  },
25
25
  "devDependencies": {
26
- "@sinclair/hammer": "^0.12.1",
26
+ "@sinclair/hammer": "^0.15.7",
27
27
  "@types/chai": "^4.2.16",
28
28
  "@types/mocha": "^8.2.2",
29
29
  "@types/node": "^14.14.37",
30
30
  "ajv": "^8.6.2",
31
31
  "ajv-formats": "^2.0.2",
32
32
  "chai": "^4.3.4",
33
- "mocha": "^8.3.2",
34
- "typescript": "^4.3.5"
33
+ "mocha": "^9.1.2",
34
+ "typescript": "^4.5.2"
35
35
  }
36
36
  }
package/readme.md CHANGED
@@ -38,7 +38,7 @@ type T = Static<typeof T> // type T = string
38
38
 
39
39
  ## Overview
40
40
 
41
- TypeBox is a library that creates in-memory JSON Schema objects that can be statically resolved to TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox allows one to create a unified type that can be statically checked by the TypeScript compiler and runtime asserted using standard JSON Schema validation.
41
+ TypeBox is a library that builds in-memory JSON Schema objects that can be statically resolved to TypeScript types. The schemas produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox allows one to create a unified type that can be statically checked by the TypeScript compiler and runtime asserted using standard JSON Schema validation.
42
42
 
43
43
  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. TypeBox does not provide any JSON schema validation. Please use libraries such as AJV to validate schemas built with this library.
44
44
 
@@ -59,6 +59,7 @@ License MIT
59
59
  - [Extended Types](#Extended-Types)
60
60
  - [Strict](#Strict)
61
61
  - [Validation](#Validation)
62
+ - [OpenAPI](#OpenAPI)
62
63
 
63
64
  <a name="Example"></a>
64
65
 
@@ -307,7 +308,7 @@ The following table outlines the TypeBox mappings between TypeScript and JSON sc
307
308
  │ Type.Number() │ │ y: { │
308
309
  │ ) │ │ type: 'number' │
309
310
  │ }) │ │ } │
310
- │ ) │ │ }
311
+ │ ) │ │ },
311
312
  │ │ │ required: ['x', 'y'] │
312
313
  │ │ │ } │
313
314
  │ │ │ │
@@ -383,7 +384,7 @@ TypeBox provides modifiers that can be applied to an objects properties. This al
383
384
 
384
385
  ### Options
385
386
 
386
- You can pass additional JSON schema properties on the last argument of any given type. The following are some examples.
387
+ You can pass additional JSON schema options on the last argument of any given type. The following are some examples.
387
388
 
388
389
  ```typescript
389
390
  // string must be an email
@@ -446,10 +447,10 @@ const R = Type.Ref(T) // const R = {
446
447
  // }
447
448
  ```
448
449
 
449
- It can be helpful to organize shared referenced types under a common namespace. The `Type.Box(...)` function can be used to create a shared definition container for related types. The following creates a `Math3D` container and a `Vertex` structure that references types in the container.
450
+ It can be helpful to organize shared referenced types under a common namespace. The `Type.Namespace(...)` function can be used to create a shared definition container for related types. The following creates a `Math3D` container and a `Vertex` structure that references types in the container.
450
451
 
451
452
  ```typescript
452
- const Math3D = Type.Box({ // const Math3D = {
453
+ const Math3D = Type.Namespace({ // const Math3D = {
453
454
  Vector4: Type.Object({ // $id: 'Math3D',
454
455
  x: Type.Number(), // definitions: {
455
456
  y: Type.Number(), // Vector4: {
@@ -690,30 +691,30 @@ const ok = ajv.validate(User, {
690
691
 
691
692
  #### Reference Types
692
693
 
693
- Referenced types can be added to AJV with the `ajv.addSchema(...)` function. The following moves the `userId` and `email` property types into a `Type.Box(...)` and registers the box with AJV.
694
+ Referenced types can be added to AJV with the `ajv.addSchema(...)` function. The following moves the `userId` and `email` property types into a `Type.Namespace(...)` and registers the box with AJV.
694
695
 
695
696
  ```typescript
696
697
  //--------------------------------------------------------------------------------------------
697
698
  //
698
- // Common Types
699
+ // Shared Types
699
700
  //
700
701
  //--------------------------------------------------------------------------------------------
701
702
 
702
- const Common = Type.Box({
703
+ const Shared = Type.Namespace({
703
704
  UserId: Type.String({ format: 'uuid' }),
704
705
  Email: Type.String({ format: 'email' })
705
- }, { $id: 'Common' })
706
+ }, { $id: 'Shared' })
706
707
 
707
708
  //--------------------------------------------------------------------------------------------
708
709
  //
709
- // Setup AJV validator with the following options and formats
710
+ // Setup Validator and Register Shared Types
710
711
  //
711
712
  //--------------------------------------------------------------------------------------------
712
713
 
713
714
  const ajv = addFormats(new Ajv({}), [...])
714
715
  .addKeyword('kind')
715
716
  .addKeyword('modifier')
716
- .addSchema(Common) // <-- Register Common Types
717
+ .addSchema(Shared) // <-- Register Shared Types
717
718
 
718
719
  //--------------------------------------------------------------------------------------------
719
720
  //
@@ -722,8 +723,8 @@ const ajv = addFormats(new Ajv({}), [...])
722
723
  //--------------------------------------------------------------------------------------------
723
724
 
724
725
  const User = Type.Object({
725
- userId: Type.Ref(Common, 'UserId'),
726
- email: Type.Ref(Common, 'Email'),
726
+ userId: Type.Ref(Shared, 'UserId'),
727
+ email: Type.Ref(Shared, 'Email'),
727
728
  online: Type.Boolean()
728
729
  }, { additionalProperties: false })
729
730
 
@@ -741,4 +742,47 @@ const ok = ajv.validate(User, {
741
742
 
742
743
  ```
743
744
 
744
- Please refer to the official AJV [documentation](https://ajv.js.org/guide/getting-started.html) for more information on using this validator.
745
+ Please refer to the official AJV [documentation](https://ajv.js.org/guide/getting-started.html) for additional information.
746
+
747
+ ### OpenAPI
748
+
749
+ TypeBox can be used to create schemas for OpenAPI, however users should be aware of the various differences between the JSON Schema and OpenAPI specifications. Two common instances where OpenAPI diverges from the JSON Schema specification is OpenAPI's handling of `string enum` and `nullable`. The following shows how you can use TypeBox to construct these types.
750
+
751
+ ```typescript
752
+ import { Type, Static, TNull, TLiteral, TUnion, TSchema } from '@sinclair/typebox'
753
+
754
+ //--------------------------------------------------------------------------------------------
755
+ //
756
+ // Nullable<T>
757
+ //
758
+ //--------------------------------------------------------------------------------------------
759
+
760
+ function Nullable<T extends TSchema>(schema: T): TUnion<[T, TNull]> {
761
+ return { ...schema, nullable: true } as any
762
+ }
763
+
764
+ const T = Nullable(Type.String()) // const T = {
765
+ // type: 'string',
766
+ // nullable: true
767
+ // }
768
+
769
+ type T = Static<typeof T> // type T = string | null
770
+
771
+ //--------------------------------------------------------------------------------------------
772
+ //
773
+ // StringUnion<[...]>
774
+ //
775
+ //--------------------------------------------------------------------------------------------
776
+
777
+ type IntoStringUnion<T> = {[K in keyof T]: T[K] extends string ? TLiteral<T[K]>: never }
778
+
779
+ function StringUnion<T extends string[]>(values: [...T]): TUnion<IntoStringUnion<T>> {
780
+ return { enum: values } as any
781
+ }
782
+
783
+ const T = StringUnion(['A', 'B', 'C']) // const T = {
784
+ // enum: ['A', 'B', 'C']
785
+ // }
786
+
787
+ type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
788
+ ```
package/typebox.d.ts CHANGED
@@ -60,103 +60,102 @@ export declare type NumberOptions = {
60
60
  export declare type IntersectOptions = {
61
61
  unevaluatedProperties?: boolean;
62
62
  } & CustomOptions;
63
- export declare type IndexedOptions = {
64
- minProperties?: number;
65
- maxProperties?: number;
66
- } & CustomOptions;
67
63
  export declare type ObjectOptions = {
68
64
  additionalProperties?: boolean;
69
65
  } & CustomOptions;
66
+ export declare type TNamespace<T extends TDefinitions> = {
67
+ kind: typeof BoxKind;
68
+ definitions: T;
69
+ } & CustomOptions;
70
+ export declare type TDefinitions = {
71
+ [key: string]: TSchema;
72
+ };
73
+ export declare type Infer<T> = {
74
+ '_infer': T;
75
+ };
70
76
  export declare type TEnumType = Record<string, string | number>;
71
77
  export declare type TKey = string | number;
72
78
  export declare type TValue = string | number | boolean;
73
- export declare type TRecordKey = TString | TNumber | TUnion<TLiteral<string | number>[]>;
79
+ export declare type TRecordKey = TString | TNumber | TKeyOf<any>;
74
80
  export declare type TEnumKey<T = TKey> = {
75
81
  type: 'number' | 'string';
76
82
  const: T;
77
83
  };
78
- export declare type TDefinitions = {
79
- [key: string]: TSchema;
80
- };
81
84
  export declare type TProperties = {
82
85
  [key: string]: TSchema;
83
86
  };
84
- export declare type TBox<T extends TDefinitions> = {
85
- kind: typeof BoxKind;
86
- definitions: T;
87
- } & CustomOptions;
88
- export declare type TTuple<T extends TSchema[]> = {
87
+ export declare type TTuple<T> = Infer<T> & {
89
88
  kind: typeof TupleKind;
90
89
  type: 'array';
91
- items?: [...T];
90
+ items?: TSchema[];
92
91
  additionalItems?: false;
93
92
  minItems: number;
94
93
  maxItems: number;
95
94
  } & CustomOptions;
96
- export declare type TObject<T extends TProperties> = {
95
+ export declare type TObject<T> = Infer<T> & {
97
96
  kind: typeof ObjectKind;
98
97
  type: 'object';
99
- properties: T;
98
+ properties: TProperties;
100
99
  required?: string[];
101
100
  } & ObjectOptions;
102
- export declare type TUnion<T extends TSchema[]> = {
101
+ export declare type TUnion<T> = Infer<T> & {
103
102
  kind: typeof UnionKind;
104
- anyOf: [...T];
103
+ anyOf: TSchema[];
105
104
  } & CustomOptions;
106
- export declare type TIntersect<T extends TSchema[]> = {
105
+ export declare type TIntersect<T> = Infer<T> & {
107
106
  kind: typeof IntersectKind;
108
107
  type: 'object';
109
- allOf: [...T];
108
+ allOf: TSchema[];
110
109
  } & IntersectOptions;
111
- export declare type TKeyOf<T extends TKey[]> = {
110
+ export declare type TKeyOf<T> = Infer<T> & {
112
111
  kind: typeof KeyOfKind;
113
112
  type: 'string';
114
- enum: [...T];
113
+ enum: string[];
115
114
  } & CustomOptions;
116
- export declare type TRecord<K extends TRecordKey, T extends TSchema> = {
115
+ export declare type TRecord<T> = Infer<T> & {
117
116
  kind: typeof RecordKind;
118
117
  type: 'object';
119
118
  patternProperties: {
120
- [pattern: string]: T;
119
+ [pattern: string]: TSchema;
121
120
  };
122
121
  } & ObjectOptions;
123
- export declare type TArray<T extends TSchema> = {
122
+ export declare type TArray<T> = Infer<T> & {
124
123
  kind: typeof ArrayKind;
125
124
  type: 'array';
126
- items: T;
125
+ items: any;
127
126
  } & ArrayOptions;
128
- export declare type TLiteral<T extends TValue> = {
127
+ export declare type TLiteral<T> = Infer<T> & {
129
128
  kind: typeof LiteralKind;
130
- const: T;
129
+ const: TSchema;
131
130
  } & CustomOptions;
132
- export declare type TEnum<T extends TEnumKey[]> = {
131
+ export declare type TEnum<T> = Infer<T> & {
133
132
  kind: typeof EnumKind;
134
- anyOf: T;
133
+ anyOf: TSchema;
135
134
  } & CustomOptions;
136
- export declare type TString = {
135
+ export declare type TString = Infer<string> & {
137
136
  kind: typeof StringKind;
138
137
  type: 'string';
139
138
  } & StringOptions<string>;
140
- export declare type TNumber = {
139
+ export declare type TNumber = Infer<number> & {
141
140
  kind: typeof NumberKind;
142
141
  type: 'number';
143
142
  } & NumberOptions;
144
- export declare type TInteger = {
143
+ export declare type TInteger = Infer<number> & {
145
144
  kind: typeof IntegerKind;
146
145
  type: 'integer';
147
146
  } & NumberOptions;
148
- export declare type TBoolean = {
147
+ export declare type TBoolean = Infer<boolean> & {
149
148
  kind: typeof BooleanKind;
150
149
  type: 'boolean';
151
150
  } & CustomOptions;
152
- export declare type TNull = {
151
+ export declare type TNull = Infer<null> & {
153
152
  kind: typeof NullKind;
154
153
  type: 'null';
155
154
  } & CustomOptions;
156
- export declare type TUnknown = {
155
+ export declare type TUnknown = Infer<unknown> & {
157
156
  kind: typeof UnknownKind;
158
157
  } & CustomOptions;
159
- export declare type TAny = {
158
+ export declare type TAny = Infer<any> & {
160
159
  kind: typeof AnyKind;
161
160
  } & CustomOptions;
162
161
  export declare const ConstructorKind: unique symbol;
@@ -164,55 +163,44 @@ export declare const FunctionKind: unique symbol;
164
163
  export declare const PromiseKind: unique symbol;
165
164
  export declare const UndefinedKind: unique symbol;
166
165
  export declare const VoidKind: unique symbol;
167
- export declare type TConstructor<T extends TSchema[], U extends TSchema> = {
166
+ export declare type TConstructor<T> = Infer<T> & {
168
167
  kind: typeof ConstructorKind;
169
168
  type: 'constructor';
170
- arguments: readonly [...T];
171
- returns: U;
169
+ arguments: TSchema[];
170
+ returns: TSchema;
172
171
  } & CustomOptions;
173
- export declare type TFunction<T extends TSchema[], U extends TSchema> = {
172
+ export declare type TFunction<T> = Infer<T> & {
174
173
  kind: typeof FunctionKind;
175
174
  type: 'function';
176
- arguments: readonly [...T];
177
- returns: U;
175
+ arguments: TSchema[];
176
+ returns: TSchema;
178
177
  } & CustomOptions;
179
- export declare type TPromise<T extends TSchema> = {
178
+ export declare type TPromise<T> = Infer<T> & {
180
179
  kind: typeof PromiseKind;
181
180
  type: 'promise';
182
- item: T;
181
+ item: TSchema;
183
182
  } & CustomOptions;
184
- export declare type TUndefined = {
183
+ export declare type TUndefined = Infer<undefined> & {
185
184
  kind: typeof UndefinedKind;
186
185
  type: 'undefined';
187
186
  } & CustomOptions;
188
- export declare type TVoid = {
187
+ export declare type TVoid = Infer<void> & {
189
188
  kind: typeof VoidKind;
190
189
  type: 'void';
191
190
  } & CustomOptions;
192
- export declare type TSchema = TIntersect<any> | TUnion<any> | TTuple<any> | TObject<any> | TKeyOf<any> | TRecord<any, any> | TArray<any> | TEnum<any> | TLiteral<any> | TString | TNumber | TInteger | TBoolean | TNull | TUnknown | TAny | TConstructor<any[], any> | TFunction<any[], any> | TPromise<any> | TUndefined | TVoid;
193
- export declare type TRequired<T extends TProperties> = {
194
- [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? TReadonly<U> : T[K] extends TReadonly<infer U> ? TReadonly<U> : T[K] extends TOptional<infer U> ? U : T[K];
195
- };
196
- export declare type TPartial<T extends TProperties> = {
197
- [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? TReadonlyOptional<U> : T[K] extends TReadonly<infer U> ? TReadonlyOptional<U> : T[K] extends TOptional<infer U> ? TOptional<U> : TOptional<T[K]>;
198
- };
191
+ export declare type TSchema = TIntersect<any> | TUnion<any> | TTuple<any> | TObject<any> | TKeyOf<any> | TRecord<any> | TArray<any> | TEnum<any> | TLiteral<any> | TString | TNumber | TInteger | TBoolean | TNull | TUnknown | TAny | TConstructor<any> | TFunction<any> | TPromise<any> | TUndefined | TVoid;
199
192
  export declare type UnionToIntersect<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
200
- export declare type ObjectPropertyKeys<T> = T extends TObject<infer U> ? PropertyKeys<U> : never;
201
- export declare type PropertyKeys<T extends TProperties> = keyof T;
202
193
  export declare type ReadonlyOptionalPropertyKeys<T extends TProperties> = {
203
- [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? K : never;
194
+ [K in keyof T]: T[K] extends TReadonlyOptional<TSchema> ? K : never;
204
195
  }[keyof T];
205
196
  export declare type ReadonlyPropertyKeys<T extends TProperties> = {
206
- [K in keyof T]: T[K] extends TReadonly<infer U> ? K : never;
197
+ [K in keyof T]: T[K] extends TReadonly<TSchema> ? K : never;
207
198
  }[keyof T];
208
199
  export declare type OptionalPropertyKeys<T extends TProperties> = {
209
- [K in keyof T]: T[K] extends TOptional<infer U> ? K : never;
200
+ [K in keyof T]: T[K] extends TOptional<TSchema> ? K : never;
210
201
  }[keyof T];
211
202
  export declare type RequiredPropertyKeys<T extends TProperties> = keyof Omit<T, ReadonlyOptionalPropertyKeys<T> | ReadonlyPropertyKeys<T> | OptionalPropertyKeys<T>>;
212
- export declare type ReduceModifiers<T extends object> = {
213
- [K in keyof T]: T[K];
214
- };
215
- export declare type StaticModifiers<T extends TProperties> = {
203
+ export declare type StaticProperties<T extends TProperties> = {
216
204
  readonly [K in ReadonlyOptionalPropertyKeys<T>]?: Static<T[K]>;
217
205
  } & {
218
206
  readonly [K in ReadonlyPropertyKeys<T>]: Static<T[K]>;
@@ -230,14 +218,8 @@ export declare type StaticUnion<T extends readonly TSchema[]> = {
230
218
  export declare type StaticTuple<T extends readonly TSchema[]> = {
231
219
  [K in keyof T]: Static<T[K]>;
232
220
  };
233
- export declare type StaticObject<T extends TProperties> = ReduceModifiers<StaticModifiers<T>>;
234
- export declare type StaticRecord<K extends TRecordKey, T extends TSchema> = K extends TString ? {
235
- [key: string]: Static<T>;
236
- } : K extends TNumber ? {
237
- [key: number]: Static<T>;
238
- } : K extends TUnion<infer L> ? L extends TLiteral<any>[] ? {
239
- [K in StaticUnion<L>]: Static<T>;
240
- } : never : never;
221
+ export declare type StaticObject<T extends TProperties> = StaticProperties<StaticProperties<T>>;
222
+ export declare type StaticRecord<K extends TRecordKey, T extends TSchema> = K extends TString ? Record<string, Static<T>> : K extends TNumber ? Record<number, Static<T>> : K extends TKeyOf<any> ? Record<K['_infer'], Static<T>> : never;
241
223
  export declare type StaticArray<T extends TSchema> = Array<Static<T>>;
242
224
  export declare type StaticLiteral<T extends TValue> = T;
243
225
  export declare type StaticConstructor<T extends readonly TSchema[], U extends TSchema> = new (...args: [...{
@@ -247,76 +229,78 @@ export declare type StaticFunction<T extends readonly TSchema[], U extends TSche
247
229
  [K in keyof T]: Static<T[K]>;
248
230
  }]) => Static<U>;
249
231
  export declare type StaticPromise<T extends TSchema> = Promise<Static<T>>;
250
- export declare type Static<T> = T extends TKeyOf<infer U> ? StaticKeyOf<U> : T extends TIntersect<infer U> ? StaticIntersect<U> : T extends TUnion<infer U> ? StaticUnion<U> : T extends TTuple<infer U> ? StaticTuple<U> : T extends TObject<infer U> ? StaticObject<U> : T extends TRecord<infer K, infer U> ? StaticRecord<K, U> : T extends TArray<infer U> ? StaticArray<U> : T extends TEnum<infer U> ? StaticEnum<U> : T extends TLiteral<infer U> ? StaticLiteral<U> : T extends TString ? string : T extends TNumber ? number : T extends TInteger ? number : T extends TBoolean ? boolean : T extends TNull ? null : T extends TUnknown ? unknown : T extends TAny ? any : T extends TConstructor<infer U, infer R> ? StaticConstructor<U, R> : T extends TFunction<infer U, infer R> ? StaticFunction<U, R> : T extends TPromise<infer U> ? StaticPromise<U> : T extends TUndefined ? undefined : T extends TVoid ? void : never;
232
+ export declare type Static<T> = T extends TKeyOf<infer I> ? I : T extends TIntersect<infer I> ? I : T extends TUnion<infer I> ? I : T extends TTuple<infer I> ? I : T extends TObject<infer I> ? {
233
+ [K in keyof I]: I[K];
234
+ } : T extends TRecord<infer I> ? I : T extends TArray<infer I> ? I : T extends TEnum<infer I> ? I : T extends TLiteral<infer I> ? I : T extends TString ? T['_infer'] : T extends TNumber ? T['_infer'] : T extends TInteger ? T['_infer'] : T extends TBoolean ? T['_infer'] : T extends TNull ? T['_infer'] : T extends TUnknown ? T['_infer'] : T extends TAny ? T['_infer'] : T extends TConstructor<infer I> ? I : T extends TFunction<infer I> ? I : T extends TPromise<infer I> ? I : T extends TUndefined ? T['_infer'] : T extends TVoid ? T['_infer'] : never;
251
235
  export declare class TypeBuilder {
252
- /** `STANDARD` Modifies a schema object property to be `readonly` and `optional`. */
236
+ /** `standard` Modifies an object property to be both readonly and optional */
253
237
  ReadonlyOptional<T extends TSchema>(item: T): TReadonlyOptional<T>;
254
- /** `STANDARD` Modifies a schema object property to be `readonly`. */
238
+ /** `standard` Modifies an object property to be readonly */
255
239
  Readonly<T extends TSchema>(item: T): TReadonly<T>;
256
- /** `STANDARD` Modifies a schema object property to be `optional`. */
240
+ /** `standard` Modifies an object property to be optional */
257
241
  Optional<T extends TSchema>(item: T): TOptional<T>;
258
- /** `STANDARD` Creates a Tuple schema. */
259
- Tuple<T extends TSchema[]>(items: [...T], options?: CustomOptions): TTuple<T>;
260
- /** `STANDARD` Creates a `object` schema with the given properties. */
261
- Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<T>;
262
- /** `STANDARD` Creates an intersection schema. Note this function requires draft `2019-09` to constrain with `unevaluatedProperties`. */
263
- Intersect<T extends TSchema[]>(items: [...T], options?: IntersectOptions): TIntersect<T>;
264
- /** `STANDARD` Creates a Union schema. */
265
- Union<T extends TSchema[]>(items: [...T], options?: CustomOptions): TUnion<T>;
266
- /** `STANDARD` Creates an `Array<T>` schema. */
267
- Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<T>;
268
- /** `STANDARD` Creates an `Enum<T>` schema from a TypeScript `enum` definition. */
269
- Enum<T extends TEnumType>(item: T, options?: CustomOptions): TEnum<TEnumKey<T[keyof T]>[]>;
270
- /** `STANDARD` Creates a literal schema. Supports `string | number | boolean` values. */
271
- Literal<T extends TValue>(value: T, options?: CustomOptions): TLiteral<T>;
272
- /** `STANDARD` Creates a `string` schema. */
242
+ /** `standard` Creates a type type */
243
+ Tuple<T extends TSchema[]>(items: [...T], options?: CustomOptions): TTuple<StaticTuple<T>>;
244
+ /** `standard` Creates an object type with the given properties */
245
+ Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<StaticProperties<T>>;
246
+ /** `standard` Creates an intersection type. Note this function requires draft `2019-09` to constrain with `unevaluatedProperties` */
247
+ Intersect<T extends TSchema[]>(items: [...T], options?: IntersectOptions): TIntersect<StaticIntersect<T>>;
248
+ /** `standard` Creates a union type */
249
+ Union<T extends TSchema[]>(items: [...T], options?: CustomOptions): TUnion<StaticUnion<T>>;
250
+ /** `standard` Creates an array type */
251
+ Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<StaticArray<T>>;
252
+ /** `standard` Creates an enum type from a TypeScript enum */
253
+ Enum<T extends TEnumType>(item: T, options?: CustomOptions): TEnum<StaticEnum<TEnumKey<T[keyof T]>[]>>;
254
+ /** `standard` Creates a literal type. Supports string, number and boolean values only */
255
+ Literal<T extends TValue>(value: T, options?: CustomOptions): TLiteral<StaticLiteral<T>>;
256
+ /** `standard` Creates a string type */
273
257
  String<TCustomFormatOption extends string>(options?: StringOptions<StringFormatOption | TCustomFormatOption>): TString;
274
- /** `STANDARD` Creates a `string` schema from a regular expression. */
258
+ /** `standard` Creates a string type from a regular expression */
275
259
  RegEx(regex: RegExp, options?: CustomOptions): TString;
276
- /** `STANDARD` Creates a `number` schema. */
260
+ /** `standard` Creates a number type */
277
261
  Number(options?: NumberOptions): TNumber;
278
- /** `STANDARD` Creates a `integer` schema. */
262
+ /** `standard` Creates an integer type */
279
263
  Integer(options?: NumberOptions): TInteger;
280
- /** `STANDARD` Creates a `boolean` schema. */
264
+ /** `standard` Creates a boolean type */
281
265
  Boolean(options?: CustomOptions): TBoolean;
282
- /** `STANDARD` Creates a `null` schema. */
266
+ /** `standard` Creates a null type */
283
267
  Null(options?: CustomOptions): TNull;
284
- /** `STANDARD` Creates an `unknown` schema. */
268
+ /** `standard` Creates an unknown type */
285
269
  Unknown(options?: CustomOptions): TUnknown;
286
- /** `STANDARD` Creates an `any` schema. */
270
+ /** `standard` Creates an any type */
287
271
  Any(options?: CustomOptions): TAny;
288
- /** `STANDARD` Creates a `keyof` schema. */
289
- KeyOf<T extends TObject<TProperties>>(schema: T, options?: CustomOptions): TKeyOf<ObjectPropertyKeys<T>[]>;
290
- /** `STANDARD` Creates a `Record<Keys, Value>` schema. */
291
- Record<K extends TRecordKey, T extends TSchema>(key: K, value: T, options?: ObjectOptions): TRecord<K, T>;
292
- /** `STANDARD` Make all properties in schema object required. */
293
- Required<T extends TObject<TProperties>>(schema: T, options?: ObjectOptions): TObject<TRequired<T['properties']>>;
294
- /** `STANDARD` Make all properties in schema object optional. */
295
- Partial<T extends TObject<TProperties>>(schema: T, options?: ObjectOptions): TObject<TPartial<T['properties']>>;
296
- /** `STANDARD` Picks property keys from the given object schema. */
297
- Pick<T extends TObject<TProperties>, K extends PropertyKeys<T['properties']>[]>(schema: T, keys: [...K], options?: ObjectOptions): TObject<Pick<T['properties'], K[number]>>;
298
- /** `STANDARD` Omits property keys from the given object schema. */
299
- Omit<T extends TObject<TProperties>, K extends PropertyKeys<T['properties']>[]>(schema: T, keys: [...K], options?: ObjectOptions): TObject<Omit<T['properties'], K[number]>>;
300
- /** `STANDARD` Omits the `kind` and `modifier` properties from the given schema. */
272
+ /** `standard` Creates a keyof type from the given object */
273
+ KeyOf<T extends TObject<any>>(schema: T, options?: CustomOptions): TKeyOf<keyof T['_infer']>;
274
+ /** `standard` Creates a record type */
275
+ Record<K extends TRecordKey, T extends TSchema>(key: K, value: T, options?: ObjectOptions): TRecord<StaticRecord<K, T>>;
276
+ /** `standard` Makes all properties in the given object type required */
277
+ Required<T extends TObject<any>>(schema: T, options?: ObjectOptions): TObject<Required<T['_infer']>>;
278
+ /** `standard` Makes all properties in the given object type optional */
279
+ Partial<T extends TObject<any>>(schema: T, options?: ObjectOptions): TObject<Partial<T['_infer']>>;
280
+ /** `standard` Picks property keys from the given object type */
281
+ Pick<T extends TObject<any>, K extends (keyof T['_infer'])[]>(schema: T, keys: [...K], options?: ObjectOptions): TObject<Pick<T['_infer'], K[number]>>;
282
+ /** `standard` Omits property keys from the given object type */
283
+ Omit<T extends TObject<any>, K extends (keyof T['_infer'])[]>(schema: T, keys: [...K], options?: ObjectOptions): TObject<Omit<T['_infer'], K[number]>>;
284
+ /** `standard` Omits the `kind` and `modifier` properties from the underlying schema */
301
285
  Strict<T extends TSchema>(schema: T, options?: CustomOptions): T;
302
- /** `EXTENDED` Creates a `constructor` schema. */
303
- Constructor<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TConstructor<T, U>;
304
- /** `EXTENDED` Creates a `function` schema. */
305
- Function<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TFunction<T, U>;
306
- /** `EXTENDED` Creates a `Promise<T>` schema. */
307
- Promise<T extends TSchema>(item: T, options?: CustomOptions): TPromise<T>;
308
- /** `EXTENDED` Creates a `undefined` schema. */
286
+ /** `extended` Creates a constructor type */
287
+ Constructor<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TConstructor<StaticConstructor<T, U>>;
288
+ /** `extended` Creates a function type */
289
+ Function<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TFunction<StaticFunction<T, U>>;
290
+ /** `extended` Creates a promise type */
291
+ Promise<T extends TSchema>(item: T, options?: CustomOptions): TPromise<StaticPromise<T>>;
292
+ /** `extended` Creates a undefined type */
309
293
  Undefined(options?: CustomOptions): TUndefined;
310
- /** `EXTENDED` Creates a `void` schema. */
294
+ /** `extended` Creates a void type */
311
295
  Void(options?: CustomOptions): TVoid;
312
- /** `EXPERIMENTAL` Creates a recursive type. */
296
+ /** `experimental` Creates a recursive type */
313
297
  Rec<T extends TSchema>(callback: (self: TAny) => T, options?: CustomOptions): T;
314
- /** `EXPERIMENTAL` Creates a recursive type. Pending https://github.com/ajv-validator/ajv/issues/1709 */
315
- /** `EXPERIMENTAL` Creates a container for schema definitions. */
316
- Box<T extends TDefinitions>(definitions: T, options?: CustomOptions): TBox<T>;
317
- /** `EXPERIMENTAL` References a schema inside a box. The referenced box must specify an `$id`. */
318
- Ref<T extends TBox<TDefinitions>, K extends keyof T['definitions']>(box: T, key: K): T['definitions'][K];
319
- /** `EXPERIMENTAL` References a schema. The referenced schema must specify an `$id`. */
298
+ /** `experimental` Creates a recursive type. Pending https://github.com/ajv-validator/ajv/issues/1709 */
299
+ /** `experimental` Creates a namespace for a set of related types */
300
+ Namespace<T extends TDefinitions>(definitions: T, options?: CustomOptions): TNamespace<T>;
301
+ /** `experimental` References a type within a namespace. The referenced namespace must specify an `$id` */
302
+ Ref<T extends TNamespace<TDefinitions>, K extends keyof T['definitions']>(box: T, key: K): T['definitions'][K];
303
+ /** `experimental` References type. The referenced type must specify an `$id` */
320
304
  Ref<T extends TSchema>(schema: T): T;
321
305
  }
322
306
  export declare const Type: TypeBuilder;
package/typebox.js CHANGED
@@ -82,19 +82,19 @@ function clone(object) {
82
82
  // TypeBuilder
83
83
  // ------------------------------------------------------------------------
84
84
  class TypeBuilder {
85
- /** `STANDARD` Modifies a schema object property to be `readonly` and `optional`. */
85
+ /** `standard` Modifies an object property to be both readonly and optional */
86
86
  ReadonlyOptional(item) {
87
87
  return { ...item, modifier: exports.ReadonlyOptionalModifier };
88
88
  }
89
- /** `STANDARD` Modifies a schema object property to be `readonly`. */
89
+ /** `standard` Modifies an object property to be readonly */
90
90
  Readonly(item) {
91
91
  return { ...item, modifier: exports.ReadonlyModifier };
92
92
  }
93
- /** `STANDARD` Modifies a schema object property to be `optional`. */
93
+ /** `standard` Modifies an object property to be optional */
94
94
  Optional(item) {
95
95
  return { ...item, modifier: exports.OptionalModifier };
96
96
  }
97
- /** `STANDARD` Creates a Tuple schema. */
97
+ /** `standard` Creates a type type */
98
98
  Tuple(items, options = {}) {
99
99
  const additionalItems = false;
100
100
  const minItems = items.length;
@@ -103,7 +103,7 @@ class TypeBuilder {
103
103
  ? { ...options, kind: exports.TupleKind, type: 'array', items, additionalItems, minItems, maxItems }
104
104
  : { ...options, kind: exports.TupleKind, type: 'array', minItems, maxItems };
105
105
  }
106
- /** `STANDARD` Creates a `object` schema with the given properties. */
106
+ /** `standard` Creates an object type with the given properties */
107
107
  Object(properties, options = {}) {
108
108
  const property_names = Object.keys(properties);
109
109
  const optional = property_names.filter(name => {
@@ -118,73 +118,73 @@ class TypeBuilder {
118
118
  { ...options, kind: exports.ObjectKind, type: 'object', properties, required } :
119
119
  { ...options, kind: exports.ObjectKind, type: 'object', properties };
120
120
  }
121
- /** `STANDARD` Creates an intersection schema. Note this function requires draft `2019-09` to constrain with `unevaluatedProperties`. */
121
+ /** `standard` Creates an intersection type. Note this function requires draft `2019-09` to constrain with `unevaluatedProperties` */
122
122
  Intersect(items, options = {}) {
123
123
  return { ...options, kind: exports.IntersectKind, type: 'object', allOf: items };
124
124
  }
125
- /** `STANDARD` Creates a Union schema. */
125
+ /** `standard` Creates a union type */
126
126
  Union(items, options = {}) {
127
127
  return { ...options, kind: exports.UnionKind, anyOf: items };
128
128
  }
129
- /** `STANDARD` Creates an `Array<T>` schema. */
129
+ /** `standard` Creates an array type */
130
130
  Array(items, options = {}) {
131
131
  return { ...options, kind: exports.ArrayKind, type: 'array', items };
132
132
  }
133
- /** `STANDARD` Creates an `Enum<T>` schema from a TypeScript `enum` definition. */
133
+ /** `standard` Creates an enum type from a TypeScript enum */
134
134
  Enum(item, options = {}) {
135
135
  const values = Object.keys(item).filter(key => isNaN(key)).map(key => item[key]);
136
136
  const anyOf = values.map(value => typeof value === 'string' ? { type: 'string', const: value } : { type: 'number', const: value });
137
137
  return { ...options, kind: exports.EnumKind, anyOf };
138
138
  }
139
- /** `STANDARD` Creates a literal schema. Supports `string | number | boolean` values. */
139
+ /** `standard` Creates a literal type. Supports string, number and boolean values only */
140
140
  Literal(value, options = {}) {
141
141
  return { ...options, kind: exports.LiteralKind, const: value, type: typeof value };
142
142
  }
143
- /** `STANDARD` Creates a `string` schema. */
143
+ /** `standard` Creates a string type */
144
144
  String(options = {}) {
145
145
  return { ...options, kind: exports.StringKind, type: 'string' };
146
146
  }
147
- /** `STANDARD` Creates a `string` schema from a regular expression. */
147
+ /** `standard` Creates a string type from a regular expression */
148
148
  RegEx(regex, options = {}) {
149
149
  return this.String({ ...options, pattern: regex.source });
150
150
  }
151
- /** `STANDARD` Creates a `number` schema. */
151
+ /** `standard` Creates a number type */
152
152
  Number(options = {}) {
153
153
  return { ...options, kind: exports.NumberKind, type: 'number' };
154
154
  }
155
- /** `STANDARD` Creates a `integer` schema. */
155
+ /** `standard` Creates an integer type */
156
156
  Integer(options = {}) {
157
157
  return { ...options, kind: exports.IntegerKind, type: 'integer' };
158
158
  }
159
- /** `STANDARD` Creates a `boolean` schema. */
159
+ /** `standard` Creates a boolean type */
160
160
  Boolean(options = {}) {
161
161
  return { ...options, kind: exports.BooleanKind, type: 'boolean' };
162
162
  }
163
- /** `STANDARD` Creates a `null` schema. */
163
+ /** `standard` Creates a null type */
164
164
  Null(options = {}) {
165
165
  return { ...options, kind: exports.NullKind, type: 'null' };
166
166
  }
167
- /** `STANDARD` Creates an `unknown` schema. */
167
+ /** `standard` Creates an unknown type */
168
168
  Unknown(options = {}) {
169
169
  return { ...options, kind: exports.UnknownKind };
170
170
  }
171
- /** `STANDARD` Creates an `any` schema. */
171
+ /** `standard` Creates an any type */
172
172
  Any(options = {}) {
173
173
  return { ...options, kind: exports.AnyKind };
174
174
  }
175
- /** `STANDARD` Creates a `keyof` schema. */
175
+ /** `standard` Creates a keyof type from the given object */
176
176
  KeyOf(schema, options = {}) {
177
177
  const keys = Object.keys(schema.properties);
178
178
  return { ...options, kind: exports.KeyOfKind, type: 'string', enum: keys };
179
179
  }
180
- /** `STANDARD` Creates a `Record<Keys, Value>` schema. */
180
+ /** `standard` Creates a record type */
181
181
  Record(key, value, options = {}) {
182
- const pattern = key.kind === exports.UnionKind ? `^${key.anyOf.map((literal) => literal.const).join('|')}$` :
182
+ const pattern = key.kind === exports.KeyOfKind ? `^${key.enum.join('|')}$` :
183
183
  key.kind === exports.NumberKind ? '^(0|[1-9][0-9]*)$' :
184
184
  key.pattern ? key.pattern : '^.*$';
185
185
  return { ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } };
186
186
  }
187
- /** `STANDARD` Make all properties in schema object required. */
187
+ /** `standard` Makes all properties in the given object type required */
188
188
  Required(schema, options = {}) {
189
189
  const next = { ...clone(schema), ...options };
190
190
  next.required = Object.keys(next.properties);
@@ -207,7 +207,7 @@ class TypeBuilder {
207
207
  }
208
208
  return next;
209
209
  }
210
- /** `STANDARD` Make all properties in schema object optional. */
210
+ /** `standard` Makes all properties in the given object type optional */
211
211
  Partial(schema, options = {}) {
212
212
  const next = { ...clone(schema), ...options };
213
213
  delete next.required;
@@ -230,7 +230,7 @@ class TypeBuilder {
230
230
  }
231
231
  return next;
232
232
  }
233
- /** `STANDARD` Picks property keys from the given object schema. */
233
+ /** `standard` Picks property keys from the given object type */
234
234
  Pick(schema, keys, options = {}) {
235
235
  const next = { ...clone(schema), ...options };
236
236
  next.required = next.required ? next.required.filter((key) => keys.includes(key)) : undefined;
@@ -240,7 +240,7 @@ class TypeBuilder {
240
240
  }
241
241
  return next;
242
242
  }
243
- /** `STANDARD` Omits property keys from the given object schema. */
243
+ /** `standard` Omits property keys from the given object type */
244
244
  Omit(schema, keys, options = {}) {
245
245
  const next = { ...clone(schema), ...options };
246
246
  next.required = next.required ? next.required.filter((key) => !keys.includes(key)) : undefined;
@@ -250,46 +250,45 @@ class TypeBuilder {
250
250
  }
251
251
  return next;
252
252
  }
253
- /** `STANDARD` Omits the `kind` and `modifier` properties from the given schema. */
253
+ /** `standard` Omits the `kind` and `modifier` properties from the underlying schema */
254
254
  Strict(schema, options = {}) {
255
255
  return JSON.parse(JSON.stringify({ ...options, ...schema }));
256
256
  }
257
- /** `EXTENDED` Creates a `constructor` schema. */
257
+ /** `extended` Creates a constructor type */
258
258
  Constructor(args, returns, options = {}) {
259
259
  return { ...options, kind: exports.ConstructorKind, type: 'constructor', arguments: args, returns };
260
260
  }
261
- /** `EXTENDED` Creates a `function` schema. */
261
+ /** `extended` Creates a function type */
262
262
  Function(args, returns, options = {}) {
263
263
  return { ...options, kind: exports.FunctionKind, type: 'function', arguments: args, returns };
264
264
  }
265
- /** `EXTENDED` Creates a `Promise<T>` schema. */
265
+ /** `extended` Creates a promise type */
266
266
  Promise(item, options = {}) {
267
267
  return { ...options, type: 'promise', kind: exports.PromiseKind, item };
268
268
  }
269
- /** `EXTENDED` Creates a `undefined` schema. */
269
+ /** `extended` Creates a undefined type */
270
270
  Undefined(options = {}) {
271
271
  return { ...options, type: 'undefined', kind: exports.UndefinedKind };
272
272
  }
273
- /** `EXTENDED` Creates a `void` schema. */
273
+ /** `extended` Creates a void type */
274
274
  Void(options = {}) {
275
275
  return { ...options, type: 'void', kind: exports.VoidKind };
276
276
  }
277
- /** `EXPERIMENTAL` Creates a recursive type. */
277
+ /** `experimental` Creates a recursive type */
278
278
  Rec(callback, options = {}) {
279
279
  const $id = options.$id || '';
280
280
  const self = callback({ $ref: `${$id}#/definitions/self` });
281
281
  return { ...options, $ref: `${$id}#/definitions/self`, definitions: { self } };
282
282
  }
283
- /** `EXPERIMENTAL` Creates a recursive type. Pending https://github.com/ajv-validator/ajv/issues/1709 */
283
+ /** `experimental` Creates a recursive type. Pending https://github.com/ajv-validator/ajv/issues/1709 */
284
284
  // public Rec<T extends TProperties>($id: string, callback: (self: TAny) => T, options: ObjectOptions = {}): TObject<T> {
285
285
  // const properties = callback({ $recursiveRef: `${$id}` } as any)
286
286
  // return { ...options, kind: ObjectKind, $id, $recursiveAnchor: true, type: 'object', properties }
287
287
  // }
288
- /** `EXPERIMENTAL` Creates a container for schema definitions. */
289
- Box(definitions, options = {}) {
288
+ /** `experimental` Creates a namespace for a set of related types */
289
+ Namespace(definitions, options = {}) {
290
290
  return { ...options, kind: exports.BoxKind, definitions };
291
291
  }
292
- /** `EXPERIMENTAL` References a schema. */
293
292
  Ref(...args) {
294
293
  const $id = args[0]['$id'] || '';
295
294
  const key = args[1];