@sinclair/typebox 0.20.4 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/readme.md +55 -13
- package/typebox.d.ts +109 -121
- package/typebox.js +44 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sinclair/typebox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.1",
|
|
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.
|
|
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": "^
|
|
34
|
-
"typescript": "^4.
|
|
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
|
|
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
|
│ │ │ │
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
-
//
|
|
699
|
+
// Shared Types
|
|
699
700
|
//
|
|
700
701
|
//--------------------------------------------------------------------------------------------
|
|
701
702
|
|
|
702
|
-
const
|
|
703
|
+
const Shared = Type.Namespace({
|
|
703
704
|
UserId: Type.String({ format: 'uuid' }),
|
|
704
705
|
Email: Type.String({ format: 'email' })
|
|
705
|
-
}, { $id: '
|
|
706
|
+
}, { $id: 'Shared' })
|
|
706
707
|
|
|
707
708
|
//--------------------------------------------------------------------------------------------
|
|
708
709
|
//
|
|
709
|
-
// Setup
|
|
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(
|
|
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(
|
|
726
|
-
email: Type.Ref(
|
|
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,45 @@ 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
|
|
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
|
+
function StringUnion<T extends string[]>(values: [...T]): TUnion<{[K in keyof T]: T[K] }[number]> {
|
|
778
|
+
return { enum: values } as any
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
const T = StringUnion(['A', 'B', 'C']) // const T = {
|
|
782
|
+
// enum: ['A', 'B', 'C']
|
|
783
|
+
// }
|
|
784
|
+
|
|
785
|
+
type T = Static<typeof T> // type T = 'A' | 'B' | 'C'
|
|
786
|
+
```
|
package/typebox.d.ts
CHANGED
|
@@ -63,96 +63,99 @@ export declare type IntersectOptions = {
|
|
|
63
63
|
export declare type ObjectOptions = {
|
|
64
64
|
additionalProperties?: boolean;
|
|
65
65
|
} & CustomOptions;
|
|
66
|
+
export declare type TDefinitions = {
|
|
67
|
+
[key: string]: TSchema;
|
|
68
|
+
};
|
|
69
|
+
export declare type TNamespace<T extends TDefinitions> = {
|
|
70
|
+
kind: typeof BoxKind;
|
|
71
|
+
definitions: T;
|
|
72
|
+
} & CustomOptions;
|
|
73
|
+
export declare type Infer<T> = {
|
|
74
|
+
'_infer': T;
|
|
75
|
+
};
|
|
66
76
|
export declare type TEnumType = Record<string, string | number>;
|
|
67
77
|
export declare type TKey = string | number;
|
|
68
78
|
export declare type TValue = string | number | boolean;
|
|
69
|
-
export declare type TRecordKey = TString | TNumber | TUnion<
|
|
79
|
+
export declare type TRecordKey = TString | TNumber | TKeyOf<any> | TUnion<string | number>;
|
|
70
80
|
export declare type TEnumKey<T = TKey> = {
|
|
71
81
|
type: 'number' | 'string';
|
|
72
82
|
const: T;
|
|
73
83
|
};
|
|
74
|
-
export declare type TDefinitions = {
|
|
75
|
-
[key: string]: TSchema;
|
|
76
|
-
};
|
|
77
84
|
export declare type TProperties = {
|
|
78
85
|
[key: string]: TSchema;
|
|
79
86
|
};
|
|
80
|
-
export declare type
|
|
81
|
-
kind: typeof BoxKind;
|
|
82
|
-
definitions: T;
|
|
83
|
-
} & CustomOptions;
|
|
84
|
-
export declare type TTuple<T extends TSchema[]> = {
|
|
87
|
+
export declare type TTuple<I> = Infer<I> & {
|
|
85
88
|
kind: typeof TupleKind;
|
|
86
89
|
type: 'array';
|
|
87
|
-
items?: [
|
|
90
|
+
items?: TSchema[];
|
|
88
91
|
additionalItems?: false;
|
|
89
92
|
minItems: number;
|
|
90
93
|
maxItems: number;
|
|
91
94
|
} & CustomOptions;
|
|
92
|
-
export declare type TObject<
|
|
95
|
+
export declare type TObject<I> = Infer<I> & {
|
|
93
96
|
kind: typeof ObjectKind;
|
|
94
97
|
type: 'object';
|
|
95
|
-
properties:
|
|
98
|
+
properties: TProperties;
|
|
96
99
|
required?: string[];
|
|
97
100
|
} & ObjectOptions;
|
|
98
|
-
export declare type TUnion<
|
|
101
|
+
export declare type TUnion<I> = Infer<I> & {
|
|
99
102
|
kind: typeof UnionKind;
|
|
100
|
-
anyOf: [
|
|
103
|
+
anyOf: TSchema[];
|
|
101
104
|
} & CustomOptions;
|
|
102
|
-
export declare type TIntersect<
|
|
105
|
+
export declare type TIntersect<I> = Infer<I> & {
|
|
103
106
|
kind: typeof IntersectKind;
|
|
104
107
|
type: 'object';
|
|
105
|
-
allOf: [
|
|
108
|
+
allOf: TSchema[];
|
|
106
109
|
} & IntersectOptions;
|
|
107
|
-
export declare type TKeyOf<
|
|
110
|
+
export declare type TKeyOf<I> = Infer<I> & {
|
|
108
111
|
kind: typeof KeyOfKind;
|
|
109
112
|
type: 'string';
|
|
110
|
-
enum: [
|
|
113
|
+
enum: string[];
|
|
111
114
|
} & CustomOptions;
|
|
112
|
-
export declare type TRecord<
|
|
115
|
+
export declare type TRecord<I> = Infer<I> & {
|
|
113
116
|
kind: typeof RecordKind;
|
|
114
117
|
type: 'object';
|
|
115
118
|
patternProperties: {
|
|
116
|
-
[pattern: string]:
|
|
119
|
+
[pattern: string]: TSchema;
|
|
117
120
|
};
|
|
118
121
|
} & ObjectOptions;
|
|
119
|
-
export declare type TArray<
|
|
122
|
+
export declare type TArray<I> = Infer<I> & {
|
|
120
123
|
kind: typeof ArrayKind;
|
|
121
124
|
type: 'array';
|
|
122
|
-
items:
|
|
125
|
+
items: any;
|
|
123
126
|
} & ArrayOptions;
|
|
124
|
-
export declare type TLiteral<
|
|
127
|
+
export declare type TLiteral<I> = Infer<I> & {
|
|
125
128
|
kind: typeof LiteralKind;
|
|
126
|
-
const:
|
|
129
|
+
const: TValue;
|
|
127
130
|
} & CustomOptions;
|
|
128
|
-
export declare type TEnum<
|
|
131
|
+
export declare type TEnum<I> = Infer<I> & {
|
|
129
132
|
kind: typeof EnumKind;
|
|
130
|
-
anyOf:
|
|
133
|
+
anyOf: TSchema;
|
|
131
134
|
} & CustomOptions;
|
|
132
|
-
export declare type TString = {
|
|
135
|
+
export declare type TString = Infer<string> & {
|
|
133
136
|
kind: typeof StringKind;
|
|
134
137
|
type: 'string';
|
|
135
138
|
} & StringOptions<string>;
|
|
136
|
-
export declare type TNumber = {
|
|
139
|
+
export declare type TNumber = Infer<number> & {
|
|
137
140
|
kind: typeof NumberKind;
|
|
138
141
|
type: 'number';
|
|
139
142
|
} & NumberOptions;
|
|
140
|
-
export declare type TInteger = {
|
|
143
|
+
export declare type TInteger = Infer<number> & {
|
|
141
144
|
kind: typeof IntegerKind;
|
|
142
145
|
type: 'integer';
|
|
143
146
|
} & NumberOptions;
|
|
144
|
-
export declare type TBoolean = {
|
|
147
|
+
export declare type TBoolean = Infer<boolean> & {
|
|
145
148
|
kind: typeof BooleanKind;
|
|
146
149
|
type: 'boolean';
|
|
147
150
|
} & CustomOptions;
|
|
148
|
-
export declare type TNull = {
|
|
151
|
+
export declare type TNull = Infer<null> & {
|
|
149
152
|
kind: typeof NullKind;
|
|
150
153
|
type: 'null';
|
|
151
154
|
} & CustomOptions;
|
|
152
|
-
export declare type TUnknown = {
|
|
155
|
+
export declare type TUnknown = Infer<unknown> & {
|
|
153
156
|
kind: typeof UnknownKind;
|
|
154
157
|
} & CustomOptions;
|
|
155
|
-
export declare type TAny = {
|
|
158
|
+
export declare type TAny = Infer<any> & {
|
|
156
159
|
kind: typeof AnyKind;
|
|
157
160
|
} & CustomOptions;
|
|
158
161
|
export declare const ConstructorKind: unique symbol;
|
|
@@ -160,55 +163,44 @@ export declare const FunctionKind: unique symbol;
|
|
|
160
163
|
export declare const PromiseKind: unique symbol;
|
|
161
164
|
export declare const UndefinedKind: unique symbol;
|
|
162
165
|
export declare const VoidKind: unique symbol;
|
|
163
|
-
export declare type TConstructor<T
|
|
166
|
+
export declare type TConstructor<T> = Infer<T> & {
|
|
164
167
|
kind: typeof ConstructorKind;
|
|
165
168
|
type: 'constructor';
|
|
166
|
-
arguments:
|
|
167
|
-
returns:
|
|
169
|
+
arguments: TSchema[];
|
|
170
|
+
returns: TSchema;
|
|
168
171
|
} & CustomOptions;
|
|
169
|
-
export declare type TFunction<T
|
|
172
|
+
export declare type TFunction<T> = Infer<T> & {
|
|
170
173
|
kind: typeof FunctionKind;
|
|
171
174
|
type: 'function';
|
|
172
|
-
arguments:
|
|
173
|
-
returns:
|
|
175
|
+
arguments: TSchema[];
|
|
176
|
+
returns: TSchema;
|
|
174
177
|
} & CustomOptions;
|
|
175
|
-
export declare type TPromise<T
|
|
178
|
+
export declare type TPromise<T> = Infer<T> & {
|
|
176
179
|
kind: typeof PromiseKind;
|
|
177
180
|
type: 'promise';
|
|
178
|
-
item:
|
|
181
|
+
item: TSchema;
|
|
179
182
|
} & CustomOptions;
|
|
180
|
-
export declare type TUndefined = {
|
|
183
|
+
export declare type TUndefined = Infer<undefined> & {
|
|
181
184
|
kind: typeof UndefinedKind;
|
|
182
185
|
type: 'undefined';
|
|
183
186
|
} & CustomOptions;
|
|
184
|
-
export declare type TVoid = {
|
|
187
|
+
export declare type TVoid = Infer<void> & {
|
|
185
188
|
kind: typeof VoidKind;
|
|
186
189
|
type: 'void';
|
|
187
190
|
} & CustomOptions;
|
|
188
|
-
export declare type TSchema = TIntersect<any> | TUnion<any> | TTuple<any> | TObject<any> | TKeyOf<any> | TRecord<any
|
|
189
|
-
export declare type TRequired<T extends TProperties> = {
|
|
190
|
-
[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];
|
|
191
|
-
};
|
|
192
|
-
export declare type TPartial<T extends TProperties> = {
|
|
193
|
-
[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]>;
|
|
194
|
-
};
|
|
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;
|
|
195
192
|
export declare type UnionToIntersect<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
196
|
-
export declare type ObjectPropertyKeys<T> = T extends TObject<infer U> ? PropertyKeys<U> : never;
|
|
197
|
-
export declare type PropertyKeys<T extends TProperties> = keyof T;
|
|
198
193
|
export declare type ReadonlyOptionalPropertyKeys<T extends TProperties> = {
|
|
199
|
-
[K in keyof T]: T[K] extends TReadonlyOptional<
|
|
194
|
+
[K in keyof T]: T[K] extends TReadonlyOptional<TSchema> ? K : never;
|
|
200
195
|
}[keyof T];
|
|
201
196
|
export declare type ReadonlyPropertyKeys<T extends TProperties> = {
|
|
202
|
-
[K in keyof T]: T[K] extends TReadonly<
|
|
197
|
+
[K in keyof T]: T[K] extends TReadonly<TSchema> ? K : never;
|
|
203
198
|
}[keyof T];
|
|
204
199
|
export declare type OptionalPropertyKeys<T extends TProperties> = {
|
|
205
|
-
[K in keyof T]: T[K] extends TOptional<
|
|
200
|
+
[K in keyof T]: T[K] extends TOptional<TSchema> ? K : never;
|
|
206
201
|
}[keyof T];
|
|
207
202
|
export declare type RequiredPropertyKeys<T extends TProperties> = keyof Omit<T, ReadonlyOptionalPropertyKeys<T> | ReadonlyPropertyKeys<T> | OptionalPropertyKeys<T>>;
|
|
208
|
-
export declare type
|
|
209
|
-
[K in keyof T]: T[K];
|
|
210
|
-
};
|
|
211
|
-
export declare type StaticModifiers<T extends TProperties> = {
|
|
203
|
+
export declare type StaticProperties<T extends TProperties> = {
|
|
212
204
|
readonly [K in ReadonlyOptionalPropertyKeys<T>]?: Static<T[K]>;
|
|
213
205
|
} & {
|
|
214
206
|
readonly [K in ReadonlyPropertyKeys<T>]: Static<T[K]>;
|
|
@@ -226,14 +218,8 @@ export declare type StaticUnion<T extends readonly TSchema[]> = {
|
|
|
226
218
|
export declare type StaticTuple<T extends readonly TSchema[]> = {
|
|
227
219
|
[K in keyof T]: Static<T[K]>;
|
|
228
220
|
};
|
|
229
|
-
export declare type StaticObject<T extends TProperties> =
|
|
230
|
-
export declare type StaticRecord<K extends TRecordKey, T extends TSchema> = K extends TString ?
|
|
231
|
-
[key: string]: Static<T>;
|
|
232
|
-
} : K extends TNumber ? {
|
|
233
|
-
[key: number]: Static<T>;
|
|
234
|
-
} : K extends TUnion<infer L> ? L extends TLiteral<any>[] ? {
|
|
235
|
-
[K in StaticUnion<L>]: Static<T>;
|
|
236
|
-
} : 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>> : K extends TUnion<any> ? Record<K['_infer'], Static<T>> : never;
|
|
237
223
|
export declare type StaticArray<T extends TSchema> = Array<Static<T>>;
|
|
238
224
|
export declare type StaticLiteral<T extends TValue> = T;
|
|
239
225
|
export declare type StaticConstructor<T extends readonly TSchema[], U extends TSchema> = new (...args: [...{
|
|
@@ -243,76 +229,78 @@ export declare type StaticFunction<T extends readonly TSchema[], U extends TSche
|
|
|
243
229
|
[K in keyof T]: Static<T[K]>;
|
|
244
230
|
}]) => Static<U>;
|
|
245
231
|
export declare type StaticPromise<T extends TSchema> = Promise<Static<T>>;
|
|
246
|
-
export declare type Static<T> = T extends TKeyOf<infer
|
|
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;
|
|
247
235
|
export declare class TypeBuilder {
|
|
248
|
-
/** `
|
|
236
|
+
/** `standard` Modifies an object property to be both readonly and optional */
|
|
249
237
|
ReadonlyOptional<T extends TSchema>(item: T): TReadonlyOptional<T>;
|
|
250
|
-
/** `
|
|
238
|
+
/** `standard` Modifies an object property to be readonly */
|
|
251
239
|
Readonly<T extends TSchema>(item: T): TReadonly<T>;
|
|
252
|
-
/** `
|
|
240
|
+
/** `standard` Modifies an object property to be optional */
|
|
253
241
|
Optional<T extends TSchema>(item: T): TOptional<T>;
|
|
254
|
-
/** `
|
|
255
|
-
Tuple<T extends TSchema[]>(items: [...T], options?: CustomOptions): TTuple<T
|
|
256
|
-
/** `
|
|
257
|
-
Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<T
|
|
258
|
-
/** `
|
|
259
|
-
Intersect<T extends TSchema[]>(items: [...T], options?: IntersectOptions): TIntersect<T
|
|
260
|
-
/** `
|
|
261
|
-
Union<T extends TSchema[]>(items: [...T], options?: CustomOptions): TUnion<T
|
|
262
|
-
/** `
|
|
263
|
-
Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<T
|
|
264
|
-
/** `
|
|
265
|
-
Enum<T extends TEnumType>(item: T, options?: CustomOptions): TEnum<TEnumKey<T[keyof T]>[]
|
|
266
|
-
/** `
|
|
267
|
-
Literal<T extends TValue>(value: T, options?: CustomOptions): TLiteral<T
|
|
268
|
-
/** `
|
|
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 */
|
|
269
257
|
String<TCustomFormatOption extends string>(options?: StringOptions<StringFormatOption | TCustomFormatOption>): TString;
|
|
270
|
-
/** `
|
|
258
|
+
/** `standard` Creates a string type from a regular expression */
|
|
271
259
|
RegEx(regex: RegExp, options?: CustomOptions): TString;
|
|
272
|
-
/** `
|
|
260
|
+
/** `standard` Creates a number type */
|
|
273
261
|
Number(options?: NumberOptions): TNumber;
|
|
274
|
-
/** `
|
|
262
|
+
/** `standard` Creates an integer type */
|
|
275
263
|
Integer(options?: NumberOptions): TInteger;
|
|
276
|
-
/** `
|
|
264
|
+
/** `standard` Creates a boolean type */
|
|
277
265
|
Boolean(options?: CustomOptions): TBoolean;
|
|
278
|
-
/** `
|
|
266
|
+
/** `standard` Creates a null type */
|
|
279
267
|
Null(options?: CustomOptions): TNull;
|
|
280
|
-
/** `
|
|
268
|
+
/** `standard` Creates an unknown type */
|
|
281
269
|
Unknown(options?: CustomOptions): TUnknown;
|
|
282
|
-
/** `
|
|
270
|
+
/** `standard` Creates an any type */
|
|
283
271
|
Any(options?: CustomOptions): TAny;
|
|
284
|
-
/** `
|
|
285
|
-
KeyOf<T extends TObject<
|
|
286
|
-
/** `
|
|
287
|
-
Record<K extends TRecordKey, T extends TSchema>(key: K, value: T, options?: ObjectOptions): TRecord<K, T
|
|
288
|
-
/** `
|
|
289
|
-
Required<T extends TObject<
|
|
290
|
-
/** `
|
|
291
|
-
Partial<T extends TObject<
|
|
292
|
-
/** `
|
|
293
|
-
Pick<T extends TObject<
|
|
294
|
-
/** `
|
|
295
|
-
Omit<T extends TObject<
|
|
296
|
-
/** `
|
|
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 */
|
|
297
285
|
Strict<T extends TSchema>(schema: T, options?: CustomOptions): T;
|
|
298
|
-
/** `
|
|
299
|
-
Constructor<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TConstructor<T, U
|
|
300
|
-
/** `
|
|
301
|
-
Function<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TFunction<T, U
|
|
302
|
-
/** `
|
|
303
|
-
Promise<T extends TSchema>(item: T, options?: CustomOptions): TPromise<T
|
|
304
|
-
/** `
|
|
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 */
|
|
305
293
|
Undefined(options?: CustomOptions): TUndefined;
|
|
306
|
-
/** `
|
|
294
|
+
/** `extended` Creates a void type */
|
|
307
295
|
Void(options?: CustomOptions): TVoid;
|
|
308
|
-
/** `
|
|
296
|
+
/** `experimental` Creates a recursive type */
|
|
309
297
|
Rec<T extends TSchema>(callback: (self: TAny) => T, options?: CustomOptions): T;
|
|
310
|
-
/** `
|
|
311
|
-
/** `
|
|
312
|
-
|
|
313
|
-
/** `
|
|
314
|
-
Ref<T extends
|
|
315
|
-
/** `
|
|
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` */
|
|
316
304
|
Ref<T extends TSchema>(schema: T): T;
|
|
317
305
|
}
|
|
318
306
|
export declare const Type: TypeBuilder;
|
package/typebox.js
CHANGED
|
@@ -55,7 +55,7 @@ exports.NullKind = Symbol('NullKind');
|
|
|
55
55
|
exports.UnknownKind = Symbol('UnknownKind');
|
|
56
56
|
exports.AnyKind = Symbol('AnyKind');
|
|
57
57
|
// ------------------------------------------------------------------------
|
|
58
|
-
// Schema
|
|
58
|
+
// Extended Schema Types
|
|
59
59
|
// ------------------------------------------------------------------------
|
|
60
60
|
exports.ConstructorKind = Symbol('ConstructorKind');
|
|
61
61
|
exports.FunctionKind = Symbol('FunctionKind');
|
|
@@ -82,19 +82,19 @@ function clone(object) {
|
|
|
82
82
|
// TypeBuilder
|
|
83
83
|
// ------------------------------------------------------------------------
|
|
84
84
|
class TypeBuilder {
|
|
85
|
-
/** `
|
|
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
|
-
/** `
|
|
89
|
+
/** `standard` Modifies an object property to be readonly */
|
|
90
90
|
Readonly(item) {
|
|
91
91
|
return { ...item, modifier: exports.ReadonlyModifier };
|
|
92
92
|
}
|
|
93
|
-
/** `
|
|
93
|
+
/** `standard` Modifies an object property to be optional */
|
|
94
94
|
Optional(item) {
|
|
95
95
|
return { ...item, modifier: exports.OptionalModifier };
|
|
96
96
|
}
|
|
97
|
-
/** `
|
|
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
|
-
/** `
|
|
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,79 @@ class TypeBuilder {
|
|
|
118
118
|
{ ...options, kind: exports.ObjectKind, type: 'object', properties, required } :
|
|
119
119
|
{ ...options, kind: exports.ObjectKind, type: 'object', properties };
|
|
120
120
|
}
|
|
121
|
-
/** `
|
|
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
|
-
/** `
|
|
125
|
+
/** `standard` Creates a union type */
|
|
126
126
|
Union(items, options = {}) {
|
|
127
127
|
return { ...options, kind: exports.UnionKind, anyOf: items };
|
|
128
128
|
}
|
|
129
|
-
/** `
|
|
129
|
+
/** `standard` Creates an array type */
|
|
130
130
|
Array(items, options = {}) {
|
|
131
131
|
return { ...options, kind: exports.ArrayKind, type: 'array', items };
|
|
132
132
|
}
|
|
133
|
-
/** `
|
|
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
|
-
/** `
|
|
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
|
-
/** `
|
|
143
|
+
/** `standard` Creates a string type */
|
|
144
144
|
String(options = {}) {
|
|
145
145
|
return { ...options, kind: exports.StringKind, type: 'string' };
|
|
146
146
|
}
|
|
147
|
-
/** `
|
|
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
|
-
/** `
|
|
151
|
+
/** `standard` Creates a number type */
|
|
152
152
|
Number(options = {}) {
|
|
153
153
|
return { ...options, kind: exports.NumberKind, type: 'number' };
|
|
154
154
|
}
|
|
155
|
-
/** `
|
|
155
|
+
/** `standard` Creates an integer type */
|
|
156
156
|
Integer(options = {}) {
|
|
157
157
|
return { ...options, kind: exports.IntegerKind, type: 'integer' };
|
|
158
158
|
}
|
|
159
|
-
/** `
|
|
159
|
+
/** `standard` Creates a boolean type */
|
|
160
160
|
Boolean(options = {}) {
|
|
161
161
|
return { ...options, kind: exports.BooleanKind, type: 'boolean' };
|
|
162
162
|
}
|
|
163
|
-
/** `
|
|
163
|
+
/** `standard` Creates a null type */
|
|
164
164
|
Null(options = {}) {
|
|
165
165
|
return { ...options, kind: exports.NullKind, type: 'null' };
|
|
166
166
|
}
|
|
167
|
-
/** `
|
|
167
|
+
/** `standard` Creates an unknown type */
|
|
168
168
|
Unknown(options = {}) {
|
|
169
169
|
return { ...options, kind: exports.UnknownKind };
|
|
170
170
|
}
|
|
171
|
-
/** `
|
|
171
|
+
/** `standard` Creates an any type */
|
|
172
172
|
Any(options = {}) {
|
|
173
173
|
return { ...options, kind: exports.AnyKind };
|
|
174
174
|
}
|
|
175
|
-
/** `
|
|
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
|
-
/** `
|
|
180
|
+
/** `standard` Creates a record type */
|
|
181
181
|
Record(key, value, options = {}) {
|
|
182
|
-
const pattern =
|
|
183
|
-
key.kind
|
|
184
|
-
|
|
182
|
+
const pattern = (() => {
|
|
183
|
+
switch (key.kind) {
|
|
184
|
+
case exports.UnionKind: return `^${key.anyOf.map(literal => literal.const).join('|')}$`;
|
|
185
|
+
case exports.KeyOfKind: return `^${key.enum.join('|')}$`;
|
|
186
|
+
case exports.NumberKind: return '^(0|[1-9][0-9]*)$';
|
|
187
|
+
case exports.StringKind: return key.pattern ? key.pattern : '^.*$';
|
|
188
|
+
default: throw Error('Invalid Record Key');
|
|
189
|
+
}
|
|
190
|
+
})();
|
|
185
191
|
return { ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } };
|
|
186
192
|
}
|
|
187
|
-
/** `
|
|
193
|
+
/** `standard` Makes all properties in the given object type required */
|
|
188
194
|
Required(schema, options = {}) {
|
|
189
195
|
const next = { ...clone(schema), ...options };
|
|
190
196
|
next.required = Object.keys(next.properties);
|
|
@@ -207,7 +213,7 @@ class TypeBuilder {
|
|
|
207
213
|
}
|
|
208
214
|
return next;
|
|
209
215
|
}
|
|
210
|
-
/** `
|
|
216
|
+
/** `standard` Makes all properties in the given object type optional */
|
|
211
217
|
Partial(schema, options = {}) {
|
|
212
218
|
const next = { ...clone(schema), ...options };
|
|
213
219
|
delete next.required;
|
|
@@ -230,7 +236,7 @@ class TypeBuilder {
|
|
|
230
236
|
}
|
|
231
237
|
return next;
|
|
232
238
|
}
|
|
233
|
-
/** `
|
|
239
|
+
/** `standard` Picks property keys from the given object type */
|
|
234
240
|
Pick(schema, keys, options = {}) {
|
|
235
241
|
const next = { ...clone(schema), ...options };
|
|
236
242
|
next.required = next.required ? next.required.filter((key) => keys.includes(key)) : undefined;
|
|
@@ -240,7 +246,7 @@ class TypeBuilder {
|
|
|
240
246
|
}
|
|
241
247
|
return next;
|
|
242
248
|
}
|
|
243
|
-
/** `
|
|
249
|
+
/** `standard` Omits property keys from the given object type */
|
|
244
250
|
Omit(schema, keys, options = {}) {
|
|
245
251
|
const next = { ...clone(schema), ...options };
|
|
246
252
|
next.required = next.required ? next.required.filter((key) => !keys.includes(key)) : undefined;
|
|
@@ -250,46 +256,45 @@ class TypeBuilder {
|
|
|
250
256
|
}
|
|
251
257
|
return next;
|
|
252
258
|
}
|
|
253
|
-
/** `
|
|
259
|
+
/** `standard` Omits the `kind` and `modifier` properties from the underlying schema */
|
|
254
260
|
Strict(schema, options = {}) {
|
|
255
261
|
return JSON.parse(JSON.stringify({ ...options, ...schema }));
|
|
256
262
|
}
|
|
257
|
-
/** `
|
|
263
|
+
/** `extended` Creates a constructor type */
|
|
258
264
|
Constructor(args, returns, options = {}) {
|
|
259
265
|
return { ...options, kind: exports.ConstructorKind, type: 'constructor', arguments: args, returns };
|
|
260
266
|
}
|
|
261
|
-
/** `
|
|
267
|
+
/** `extended` Creates a function type */
|
|
262
268
|
Function(args, returns, options = {}) {
|
|
263
269
|
return { ...options, kind: exports.FunctionKind, type: 'function', arguments: args, returns };
|
|
264
270
|
}
|
|
265
|
-
/** `
|
|
271
|
+
/** `extended` Creates a promise type */
|
|
266
272
|
Promise(item, options = {}) {
|
|
267
273
|
return { ...options, type: 'promise', kind: exports.PromiseKind, item };
|
|
268
274
|
}
|
|
269
|
-
/** `
|
|
275
|
+
/** `extended` Creates a undefined type */
|
|
270
276
|
Undefined(options = {}) {
|
|
271
277
|
return { ...options, type: 'undefined', kind: exports.UndefinedKind };
|
|
272
278
|
}
|
|
273
|
-
/** `
|
|
279
|
+
/** `extended` Creates a void type */
|
|
274
280
|
Void(options = {}) {
|
|
275
281
|
return { ...options, type: 'void', kind: exports.VoidKind };
|
|
276
282
|
}
|
|
277
|
-
/** `
|
|
283
|
+
/** `experimental` Creates a recursive type */
|
|
278
284
|
Rec(callback, options = {}) {
|
|
279
285
|
const $id = options.$id || '';
|
|
280
286
|
const self = callback({ $ref: `${$id}#/definitions/self` });
|
|
281
287
|
return { ...options, $ref: `${$id}#/definitions/self`, definitions: { self } };
|
|
282
288
|
}
|
|
283
|
-
/** `
|
|
289
|
+
/** `experimental` Creates a recursive type. Pending https://github.com/ajv-validator/ajv/issues/1709 */
|
|
284
290
|
// public Rec<T extends TProperties>($id: string, callback: (self: TAny) => T, options: ObjectOptions = {}): TObject<T> {
|
|
285
291
|
// const properties = callback({ $recursiveRef: `${$id}` } as any)
|
|
286
292
|
// return { ...options, kind: ObjectKind, $id, $recursiveAnchor: true, type: 'object', properties }
|
|
287
293
|
// }
|
|
288
|
-
/** `
|
|
289
|
-
|
|
294
|
+
/** `experimental` Creates a namespace for a set of related types */
|
|
295
|
+
Namespace(definitions, options = {}) {
|
|
290
296
|
return { ...options, kind: exports.BoxKind, definitions };
|
|
291
297
|
}
|
|
292
|
-
/** `EXPERIMENTAL` References a schema. */
|
|
293
298
|
Ref(...args) {
|
|
294
299
|
const $id = args[0]['$id'] || '';
|
|
295
300
|
const key = args[1];
|