@sinclair/typebox 0.21.1 → 0.23.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.
- package/package.json +13 -9
- package/readme.md +10 -8
- package/typebox.d.ts +182 -140
- package/typebox.js +147 -113
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sinclair/typebox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"json-schema",
|
|
@@ -20,17 +20,21 @@
|
|
|
20
20
|
"clean": "hammer task clean",
|
|
21
21
|
"build": "hammer task build",
|
|
22
22
|
"example": "hammer task example",
|
|
23
|
-
"
|
|
23
|
+
"spec": "hammer task spec",
|
|
24
|
+
"spec:types": "hammer task spec_types",
|
|
25
|
+
"spec:schemas": "hammer task spec_schemas",
|
|
26
|
+
"test": "npm run spec"
|
|
24
27
|
},
|
|
25
28
|
"devDependencies": {
|
|
26
|
-
"@sinclair/hammer": "^0.15.
|
|
27
|
-
"@types/chai": "^4.2.
|
|
28
|
-
"@types/mocha": "^
|
|
29
|
-
"@types/node": "^
|
|
30
|
-
"ajv": "^8.
|
|
31
|
-
"ajv-formats": "^2.
|
|
29
|
+
"@sinclair/hammer": "^0.15.8",
|
|
30
|
+
"@types/chai": "^4.2.22",
|
|
31
|
+
"@types/mocha": "^9.0.0",
|
|
32
|
+
"@types/node": "^16.11.9",
|
|
33
|
+
"ajv": "^8.8.2",
|
|
34
|
+
"ajv-formats": "^2.1.1",
|
|
32
35
|
"chai": "^4.3.4",
|
|
33
|
-
"mocha": "^9.1.
|
|
36
|
+
"mocha": "^9.1.3",
|
|
37
|
+
"tsd": "^0.19.0",
|
|
34
38
|
"typescript": "^4.5.2"
|
|
35
39
|
}
|
|
36
40
|
}
|
package/readme.md
CHANGED
|
@@ -452,7 +452,7 @@ It can be helpful to organize shared referenced types under a common namespace.
|
|
|
452
452
|
```typescript
|
|
453
453
|
const Math3D = Type.Namespace({ // const Math3D = {
|
|
454
454
|
Vector4: Type.Object({ // $id: 'Math3D',
|
|
455
|
-
x: Type.Number(), //
|
|
455
|
+
x: Type.Number(), // $defs: {
|
|
456
456
|
y: Type.Number(), // Vector4: {
|
|
457
457
|
z: Type.Number(), // type: 'object',
|
|
458
458
|
w: Type.Number() // properties: {
|
|
@@ -486,9 +486,9 @@ const Math3D = Type.Namespace({ // const Math3D = {
|
|
|
486
486
|
const Vertex = Type.Object({ // const Vertex = {
|
|
487
487
|
position: Type.Ref(Math3D, 'Vector4'), // type: 'object',
|
|
488
488
|
normal: Type.Ref(Math3D, 'Vector3'), // properties: {
|
|
489
|
-
uv: Type.Ref(Math3D, 'Vector2') // position: { $ref: 'Math3D
|
|
490
|
-
}) // normal: { $ref: 'Math3D
|
|
491
|
-
// uv: { $ref: 'Math3D
|
|
489
|
+
uv: Type.Ref(Math3D, 'Vector2') // position: { $ref: 'Math3D#/$defs/Vector4' },
|
|
490
|
+
}) // normal: { $ref: 'Math3D#/$defs/Vector3' },
|
|
491
|
+
// uv: { $ref: 'Math3D#/$defs/Vector2' }
|
|
492
492
|
// },
|
|
493
493
|
// required: ['position', 'normal', 'uv']
|
|
494
494
|
// }
|
|
@@ -503,8 +503,8 @@ Recursive types can be created with the `Type.Rec(...)` function. The following
|
|
|
503
503
|
```typescript
|
|
504
504
|
const Node = Type.Rec(Self => Type.Object({ // const Node = {
|
|
505
505
|
id: Type.String(), // $id: 'Node',
|
|
506
|
-
nodes: Type.Array(Self), // $ref: 'Node
|
|
507
|
-
}), { $id: 'Node' }) //
|
|
506
|
+
nodes: Type.Array(Self), // $ref: 'Node#/$defs/self',
|
|
507
|
+
}), { $id: 'Node' }) // $defs: {
|
|
508
508
|
// self: {
|
|
509
509
|
// type: 'object',
|
|
510
510
|
// properties: {
|
|
@@ -514,7 +514,7 @@ const Node = Type.Rec(Self => Type.Object({ // const Node = {
|
|
|
514
514
|
// nodes: {
|
|
515
515
|
// type: 'array',
|
|
516
516
|
// items: {
|
|
517
|
-
// $ref: 'Node
|
|
517
|
+
// $ref: 'Node#/$defs/self'
|
|
518
518
|
// }
|
|
519
519
|
// }
|
|
520
520
|
// }
|
|
@@ -774,7 +774,9 @@ type T = Static<typeof T> // type T = string | null
|
|
|
774
774
|
//
|
|
775
775
|
//--------------------------------------------------------------------------------------------
|
|
776
776
|
|
|
777
|
-
|
|
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>> {
|
|
778
780
|
return { enum: values } as any
|
|
779
781
|
}
|
|
780
782
|
|
package/typebox.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export declare const BooleanKind: unique symbol;
|
|
|
28
28
|
export declare const NullKind: unique symbol;
|
|
29
29
|
export declare const UnknownKind: unique symbol;
|
|
30
30
|
export declare const AnyKind: unique symbol;
|
|
31
|
+
export declare const RefKind: unique symbol;
|
|
31
32
|
export interface CustomOptions {
|
|
32
33
|
$id?: string;
|
|
33
34
|
title?: string;
|
|
@@ -68,239 +69,280 @@ export declare type TDefinitions = {
|
|
|
68
69
|
};
|
|
69
70
|
export declare type TNamespace<T extends TDefinitions> = {
|
|
70
71
|
kind: typeof BoxKind;
|
|
71
|
-
|
|
72
|
+
$defs: T;
|
|
72
73
|
} & CustomOptions;
|
|
73
|
-
export
|
|
74
|
-
|
|
75
|
-
}
|
|
74
|
+
export interface TSchema {
|
|
75
|
+
$static: unknown;
|
|
76
|
+
}
|
|
76
77
|
export declare type TEnumType = Record<string, string | number>;
|
|
77
|
-
export declare type TKey = string | number;
|
|
78
|
+
export declare type TKey = string | number | symbol;
|
|
78
79
|
export declare type TValue = string | number | boolean;
|
|
79
|
-
export declare type TRecordKey = TString | TNumber | TKeyOf<any> | TUnion<
|
|
80
|
+
export declare type TRecordKey = TString | TNumber | TKeyOf<any> | TUnion<any>;
|
|
80
81
|
export declare type TEnumKey<T = TKey> = {
|
|
81
82
|
type: 'number' | 'string';
|
|
82
83
|
const: T;
|
|
83
84
|
};
|
|
84
|
-
export
|
|
85
|
+
export interface TProperties {
|
|
85
86
|
[key: string]: TSchema;
|
|
86
|
-
}
|
|
87
|
-
export
|
|
87
|
+
}
|
|
88
|
+
export interface TRecord<K extends TRecordKey, T extends TSchema> extends TSchema, ObjectOptions {
|
|
89
|
+
$static: StaticRecord<K, T>;
|
|
90
|
+
kind: typeof RecordKind;
|
|
91
|
+
type: 'object';
|
|
92
|
+
patternProperties: {
|
|
93
|
+
[pattern: string]: T;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export interface TTuple<T extends TSchema[]> extends TSchema, CustomOptions {
|
|
97
|
+
$static: StaticTuple<T>;
|
|
88
98
|
kind: typeof TupleKind;
|
|
89
99
|
type: 'array';
|
|
90
|
-
items?:
|
|
100
|
+
items?: T;
|
|
91
101
|
additionalItems?: false;
|
|
92
102
|
minItems: number;
|
|
93
103
|
maxItems: number;
|
|
94
|
-
}
|
|
95
|
-
export
|
|
104
|
+
}
|
|
105
|
+
export interface TObject<T extends TProperties> extends TSchema, ObjectOptions {
|
|
106
|
+
$static: StaticObject<T>;
|
|
96
107
|
kind: typeof ObjectKind;
|
|
97
108
|
type: 'object';
|
|
98
|
-
properties:
|
|
109
|
+
properties: T;
|
|
99
110
|
required?: string[];
|
|
100
|
-
}
|
|
101
|
-
export
|
|
111
|
+
}
|
|
112
|
+
export interface TUnion<T extends TSchema[]> extends TSchema, CustomOptions {
|
|
113
|
+
$static: StaticUnion<T>;
|
|
102
114
|
kind: typeof UnionKind;
|
|
103
|
-
anyOf:
|
|
104
|
-
}
|
|
105
|
-
export
|
|
115
|
+
anyOf: T;
|
|
116
|
+
}
|
|
117
|
+
export interface TIntersect<T extends TSchema[]> extends TSchema, IntersectOptions {
|
|
118
|
+
$static: StaticIntersect<T>;
|
|
106
119
|
kind: typeof IntersectKind;
|
|
107
120
|
type: 'object';
|
|
108
|
-
allOf:
|
|
109
|
-
}
|
|
110
|
-
export
|
|
121
|
+
allOf: T;
|
|
122
|
+
}
|
|
123
|
+
export interface TKeyOf<T extends TKey[]> extends TSchema, CustomOptions {
|
|
124
|
+
$static: StaticKeyOf<T>;
|
|
111
125
|
kind: typeof KeyOfKind;
|
|
112
126
|
type: 'string';
|
|
113
|
-
enum:
|
|
114
|
-
}
|
|
115
|
-
export
|
|
116
|
-
|
|
117
|
-
type: 'object';
|
|
118
|
-
patternProperties: {
|
|
119
|
-
[pattern: string]: TSchema;
|
|
120
|
-
};
|
|
121
|
-
} & ObjectOptions;
|
|
122
|
-
export declare type TArray<I> = Infer<I> & {
|
|
127
|
+
enum: T;
|
|
128
|
+
}
|
|
129
|
+
export interface TArray<T extends TSchema> extends TSchema, ArrayOptions {
|
|
130
|
+
$static: StaticArray<T>;
|
|
123
131
|
kind: typeof ArrayKind;
|
|
124
132
|
type: 'array';
|
|
125
|
-
items:
|
|
126
|
-
}
|
|
127
|
-
export
|
|
133
|
+
items: T;
|
|
134
|
+
}
|
|
135
|
+
export interface TLiteral<T extends TValue> extends TSchema, CustomOptions {
|
|
136
|
+
$static: StaticLiteral<T>;
|
|
128
137
|
kind: typeof LiteralKind;
|
|
129
|
-
const:
|
|
130
|
-
}
|
|
131
|
-
export
|
|
138
|
+
const: T;
|
|
139
|
+
}
|
|
140
|
+
export interface TEnum<T extends TEnumKey[]> extends TSchema, CustomOptions {
|
|
141
|
+
$static: StaticEnum<T>;
|
|
132
142
|
kind: typeof EnumKind;
|
|
133
|
-
anyOf:
|
|
134
|
-
}
|
|
135
|
-
export
|
|
143
|
+
anyOf: T;
|
|
144
|
+
}
|
|
145
|
+
export interface TString extends TSchema, StringOptions<string> {
|
|
146
|
+
$static: string;
|
|
136
147
|
kind: typeof StringKind;
|
|
137
148
|
type: 'string';
|
|
138
|
-
}
|
|
139
|
-
export
|
|
149
|
+
}
|
|
150
|
+
export interface TNumber extends TSchema, NumberOptions {
|
|
151
|
+
$static: number;
|
|
140
152
|
kind: typeof NumberKind;
|
|
141
153
|
type: 'number';
|
|
142
|
-
}
|
|
143
|
-
export
|
|
154
|
+
}
|
|
155
|
+
export interface TInteger extends TSchema, NumberOptions {
|
|
156
|
+
$static: number;
|
|
144
157
|
kind: typeof IntegerKind;
|
|
145
158
|
type: 'integer';
|
|
146
|
-
}
|
|
147
|
-
export
|
|
159
|
+
}
|
|
160
|
+
export interface TBoolean extends TSchema, CustomOptions {
|
|
161
|
+
$static: boolean;
|
|
148
162
|
kind: typeof BooleanKind;
|
|
149
163
|
type: 'boolean';
|
|
150
|
-
}
|
|
151
|
-
export
|
|
164
|
+
}
|
|
165
|
+
export interface TNull extends TSchema, CustomOptions {
|
|
166
|
+
$static: null;
|
|
152
167
|
kind: typeof NullKind;
|
|
153
168
|
type: 'null';
|
|
154
|
-
}
|
|
155
|
-
export
|
|
169
|
+
}
|
|
170
|
+
export interface TUnknown extends TSchema, CustomOptions {
|
|
171
|
+
$static: unknown;
|
|
156
172
|
kind: typeof UnknownKind;
|
|
157
|
-
}
|
|
158
|
-
export
|
|
173
|
+
}
|
|
174
|
+
export interface TAny extends TSchema, CustomOptions {
|
|
175
|
+
$static: any;
|
|
159
176
|
kind: typeof AnyKind;
|
|
160
|
-
}
|
|
177
|
+
}
|
|
178
|
+
export interface TRef<T extends TSchema> extends TSchema, CustomOptions {
|
|
179
|
+
$static: Static<T>;
|
|
180
|
+
kind: typeof RefKind;
|
|
181
|
+
$ref: string;
|
|
182
|
+
}
|
|
161
183
|
export declare const ConstructorKind: unique symbol;
|
|
162
184
|
export declare const FunctionKind: unique symbol;
|
|
163
185
|
export declare const PromiseKind: unique symbol;
|
|
164
186
|
export declare const UndefinedKind: unique symbol;
|
|
165
187
|
export declare const VoidKind: unique symbol;
|
|
166
|
-
export
|
|
188
|
+
export interface TConstructor<T extends TSchema[], U extends TSchema> extends TSchema, CustomOptions {
|
|
189
|
+
$static: StaticConstructor<T, U>;
|
|
167
190
|
kind: typeof ConstructorKind;
|
|
168
191
|
type: 'constructor';
|
|
169
192
|
arguments: TSchema[];
|
|
170
193
|
returns: TSchema;
|
|
171
|
-
}
|
|
172
|
-
export
|
|
194
|
+
}
|
|
195
|
+
export interface TFunction<T extends TSchema[], U extends TSchema> extends TSchema, CustomOptions {
|
|
196
|
+
$static: StaticFunction<T, U>;
|
|
173
197
|
kind: typeof FunctionKind;
|
|
174
198
|
type: 'function';
|
|
175
199
|
arguments: TSchema[];
|
|
176
200
|
returns: TSchema;
|
|
177
|
-
}
|
|
178
|
-
export
|
|
201
|
+
}
|
|
202
|
+
export interface TPromise<T extends TSchema> extends TSchema, CustomOptions {
|
|
203
|
+
$static: StaticPromise<T>;
|
|
179
204
|
kind: typeof PromiseKind;
|
|
180
205
|
type: 'promise';
|
|
181
206
|
item: TSchema;
|
|
182
|
-
}
|
|
183
|
-
export
|
|
207
|
+
}
|
|
208
|
+
export interface TUndefined extends TSchema, CustomOptions {
|
|
209
|
+
$static: undefined;
|
|
184
210
|
kind: typeof UndefinedKind;
|
|
185
211
|
type: 'undefined';
|
|
186
|
-
}
|
|
187
|
-
export
|
|
212
|
+
}
|
|
213
|
+
export interface TVoid extends TSchema, CustomOptions {
|
|
214
|
+
$static: void;
|
|
188
215
|
kind: typeof VoidKind;
|
|
189
216
|
type: 'void';
|
|
190
|
-
}
|
|
191
|
-
export declare type
|
|
217
|
+
}
|
|
218
|
+
export declare type Pickable = TObject<TProperties> | TRef<TObject<TProperties>>;
|
|
219
|
+
export declare type PickablePropertyKeys<T extends Pickable> = T extends TObject<infer U> ? keyof U : T extends TRef<TObject<infer U>> ? keyof U : never;
|
|
220
|
+
export declare type PickableProperties<T extends Pickable> = T extends TObject<infer U> ? U : T extends TRef<TObject<infer U>> ? U : never;
|
|
192
221
|
export declare type UnionToIntersect<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
193
|
-
export declare type
|
|
222
|
+
export declare type StaticReadonlyOptionalPropertyKeys<T extends TProperties> = {
|
|
194
223
|
[K in keyof T]: T[K] extends TReadonlyOptional<TSchema> ? K : never;
|
|
195
224
|
}[keyof T];
|
|
196
|
-
export declare type
|
|
225
|
+
export declare type StaticReadonlyPropertyKeys<T extends TProperties> = {
|
|
197
226
|
[K in keyof T]: T[K] extends TReadonly<TSchema> ? K : never;
|
|
198
227
|
}[keyof T];
|
|
199
|
-
export declare type
|
|
228
|
+
export declare type StaticOptionalPropertyKeys<T extends TProperties> = {
|
|
200
229
|
[K in keyof T]: T[K] extends TOptional<TSchema> ? K : never;
|
|
201
230
|
}[keyof T];
|
|
202
|
-
export declare type
|
|
231
|
+
export declare type StaticRequiredPropertyKeys<T extends TProperties> = keyof Omit<T, StaticReadonlyOptionalPropertyKeys<T> | StaticReadonlyPropertyKeys<T> | StaticOptionalPropertyKeys<T>>;
|
|
232
|
+
export declare type StaticIntersectEvaluate<T extends readonly TSchema[]> = {
|
|
233
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
234
|
+
};
|
|
235
|
+
export declare type StaticIntersectReduce<I extends unknown, T extends readonly any[]> = T extends [infer A, ...infer B] ? StaticIntersectReduce<I & A, B> : I;
|
|
236
|
+
export declare type StaticRequired<T extends TProperties> = {
|
|
237
|
+
[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];
|
|
238
|
+
};
|
|
239
|
+
export declare type StaticPartial<T extends TProperties> = {
|
|
240
|
+
[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]>;
|
|
241
|
+
};
|
|
203
242
|
export declare type StaticProperties<T extends TProperties> = {
|
|
204
|
-
readonly [K in
|
|
243
|
+
readonly [K in StaticReadonlyOptionalPropertyKeys<T>]?: Static<T[K]>;
|
|
205
244
|
} & {
|
|
206
|
-
readonly [K in
|
|
245
|
+
readonly [K in StaticReadonlyPropertyKeys<T>]: Static<T[K]>;
|
|
207
246
|
} & {
|
|
208
|
-
[K in
|
|
247
|
+
[K in StaticOptionalPropertyKeys<T>]?: Static<T[K]>;
|
|
209
248
|
} & {
|
|
210
|
-
[K in
|
|
249
|
+
[K in StaticRequiredPropertyKeys<T>]: Static<T[K]>;
|
|
211
250
|
};
|
|
251
|
+
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<TKey[]> ? Record<K['$static'], Static<T>> : K extends TUnion<TSchema[]> ? Record<K['$static'], Static<T>> : never;
|
|
212
252
|
export declare type StaticEnum<T> = T extends TEnumKey<infer U>[] ? U : never;
|
|
213
253
|
export declare type StaticKeyOf<T extends TKey[]> = T extends Array<infer K> ? K : never;
|
|
214
|
-
export declare type StaticIntersect<T extends readonly TSchema[]> =
|
|
254
|
+
export declare type StaticIntersect<T extends readonly TSchema[]> = StaticIntersectReduce<unknown, StaticIntersectEvaluate<T>>;
|
|
215
255
|
export declare type StaticUnion<T extends readonly TSchema[]> = {
|
|
216
|
-
[K in keyof T]: Static<T[K]
|
|
256
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
217
257
|
}[number];
|
|
218
258
|
export declare type StaticTuple<T extends readonly TSchema[]> = {
|
|
219
|
-
[K in keyof T]: Static<T[K]
|
|
259
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
220
260
|
};
|
|
221
|
-
export declare type StaticObject<T extends TProperties> = StaticProperties<
|
|
222
|
-
|
|
261
|
+
export declare type StaticObject<T extends TProperties> = StaticProperties<T> extends infer I ? {
|
|
262
|
+
[K in keyof I]: I[K];
|
|
263
|
+
} : never;
|
|
223
264
|
export declare type StaticArray<T extends TSchema> = Array<Static<T>>;
|
|
224
265
|
export declare type StaticLiteral<T extends TValue> = T;
|
|
225
|
-
export declare type
|
|
226
|
-
[K in keyof T]: Static<T[K]
|
|
227
|
-
}
|
|
228
|
-
export declare type
|
|
229
|
-
|
|
230
|
-
}]) => Static<U>;
|
|
266
|
+
export declare type StaticParameters<T extends readonly TSchema[]> = {
|
|
267
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
268
|
+
};
|
|
269
|
+
export declare type StaticConstructor<T extends readonly TSchema[], U extends TSchema> = new (...args: [...StaticParameters<T>]) => Static<U>;
|
|
270
|
+
export declare type StaticFunction<T extends readonly TSchema[], U extends TSchema> = (...args: [...StaticParameters<T>]) => Static<U>;
|
|
231
271
|
export declare type StaticPromise<T extends TSchema> = Promise<Static<T>>;
|
|
232
|
-
export declare type Static<T
|
|
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;
|
|
272
|
+
export declare type Static<T extends TSchema> = T['$static'];
|
|
235
273
|
export declare class TypeBuilder {
|
|
236
|
-
|
|
274
|
+
private readonly schemas;
|
|
275
|
+
/** `Standard` Modifies an object property to be both readonly and optional */
|
|
237
276
|
ReadonlyOptional<T extends TSchema>(item: T): TReadonlyOptional<T>;
|
|
238
|
-
/** `
|
|
277
|
+
/** `Standard` Modifies an object property to be readonly */
|
|
239
278
|
Readonly<T extends TSchema>(item: T): TReadonly<T>;
|
|
240
|
-
/** `
|
|
279
|
+
/** `Standard` Modifies an object property to be optional */
|
|
241
280
|
Optional<T extends TSchema>(item: T): TOptional<T>;
|
|
242
|
-
/** `
|
|
243
|
-
Tuple<T extends TSchema[]>(items: [...T], options?: CustomOptions): TTuple<
|
|
244
|
-
/** `
|
|
245
|
-
Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<
|
|
246
|
-
/** `
|
|
247
|
-
Intersect<T extends TSchema[]>(items: [...T], options?: IntersectOptions): TIntersect<
|
|
248
|
-
/** `
|
|
249
|
-
Union<T extends TSchema[]>(items: [...T], options?: CustomOptions): TUnion<
|
|
250
|
-
/** `
|
|
251
|
-
Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<
|
|
252
|
-
/** `
|
|
253
|
-
Enum<T extends TEnumType>(item: T, options?: CustomOptions): TEnum<
|
|
254
|
-
/** `
|
|
255
|
-
Literal<T extends TValue>(value: T, options?: CustomOptions): TLiteral<
|
|
256
|
-
/** `
|
|
281
|
+
/** `Standard` Creates a type type */
|
|
282
|
+
Tuple<T extends TSchema[]>(items: [...T], options?: CustomOptions): TTuple<T>;
|
|
283
|
+
/** `Standard` Creates an object type with the given properties */
|
|
284
|
+
Object<T extends TProperties>(properties: T, options?: ObjectOptions): TObject<T>;
|
|
285
|
+
/** `Standard` Creates an intersect type. */
|
|
286
|
+
Intersect<T extends TSchema[]>(items: [...T], options?: IntersectOptions): TIntersect<T>;
|
|
287
|
+
/** `Standard` Creates a union type */
|
|
288
|
+
Union<T extends TSchema[]>(items: [...T], options?: CustomOptions): TUnion<T>;
|
|
289
|
+
/** `Standard` Creates an array type */
|
|
290
|
+
Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<T>;
|
|
291
|
+
/** `Standard` Creates an enum type from a TypeScript enum */
|
|
292
|
+
Enum<T extends TEnumType>(item: T, options?: CustomOptions): TEnum<TEnumKey<T[keyof T]>[]>;
|
|
293
|
+
/** `Standard` Creates a literal type. Supports string, number and boolean values only */
|
|
294
|
+
Literal<T extends TValue>(value: T, options?: CustomOptions): TLiteral<T>;
|
|
295
|
+
/** `Standard` Creates a string type */
|
|
257
296
|
String<TCustomFormatOption extends string>(options?: StringOptions<StringFormatOption | TCustomFormatOption>): TString;
|
|
258
|
-
/** `
|
|
297
|
+
/** `Standard` Creates a string type from a regular expression */
|
|
259
298
|
RegEx(regex: RegExp, options?: CustomOptions): TString;
|
|
260
|
-
/** `
|
|
299
|
+
/** `Standard` Creates a number type */
|
|
261
300
|
Number(options?: NumberOptions): TNumber;
|
|
262
|
-
/** `
|
|
301
|
+
/** `Standard` Creates an integer type */
|
|
263
302
|
Integer(options?: NumberOptions): TInteger;
|
|
264
|
-
/** `
|
|
303
|
+
/** `Standard` Creates a boolean type */
|
|
265
304
|
Boolean(options?: CustomOptions): TBoolean;
|
|
266
|
-
/** `
|
|
305
|
+
/** `Standard` Creates a null type */
|
|
267
306
|
Null(options?: CustomOptions): TNull;
|
|
268
|
-
/** `
|
|
307
|
+
/** `Standard` Creates an unknown type */
|
|
269
308
|
Unknown(options?: CustomOptions): TUnknown;
|
|
270
|
-
/** `
|
|
309
|
+
/** `Standard` Creates an any type */
|
|
271
310
|
Any(options?: CustomOptions): TAny;
|
|
272
|
-
/** `
|
|
273
|
-
KeyOf<T extends TObject<
|
|
274
|
-
/** `
|
|
275
|
-
Record<K extends TRecordKey, T extends TSchema>(key: K, value: T, options?: ObjectOptions): TRecord<
|
|
276
|
-
/** `
|
|
277
|
-
Required<T extends TObject<
|
|
278
|
-
/** `
|
|
279
|
-
Partial<T extends TObject<
|
|
280
|
-
/** `
|
|
281
|
-
Pick<T extends TObject<
|
|
282
|
-
/** `
|
|
283
|
-
Omit<T extends TObject<
|
|
284
|
-
/** `
|
|
311
|
+
/** `Standard` Creates a keyof type from the given object */
|
|
312
|
+
KeyOf<T extends TObject<TProperties>>(object: T, options?: CustomOptions): TKeyOf<(keyof T['properties'])[]>;
|
|
313
|
+
/** `Standard` Creates a record type */
|
|
314
|
+
Record<K extends TRecordKey, T extends TSchema>(key: K, value: T, options?: ObjectOptions): TRecord<K, T>;
|
|
315
|
+
/** `Standard` Makes all properties in the given object type required */
|
|
316
|
+
Required<T extends TObject<TProperties> | TRef<TObject<TProperties>>>(object: T, options?: ObjectOptions): TObject<StaticRequired<T['properties']>>;
|
|
317
|
+
/** `Standard` Makes all properties in the given object type optional */
|
|
318
|
+
Partial<T extends TObject<TProperties> | TRef<TObject<TProperties>>>(object: T, options?: ObjectOptions): TObject<StaticPartial<T['properties']>>;
|
|
319
|
+
/** `Standard` Picks property keys from the given object type */
|
|
320
|
+
Pick<T extends TObject<TProperties> | TRef<TObject<TProperties>>, K extends PickablePropertyKeys<T>[]>(object: T, keys: [...K], options?: ObjectOptions): TObject<Pick<PickableProperties<T>, K[number]>>;
|
|
321
|
+
/** `Standard` Omits property keys from the given object type */
|
|
322
|
+
Omit<T extends TObject<TProperties> | TRef<TObject<TProperties>>, K extends PickablePropertyKeys<T>[]>(object: T, keys: [...K], options?: ObjectOptions): TObject<Omit<PickableProperties<T>, K[number]>>;
|
|
323
|
+
/** `Standard` Omits the `kind` and `modifier` properties from the underlying schema */
|
|
285
324
|
Strict<T extends TSchema>(schema: T, options?: CustomOptions): T;
|
|
286
|
-
/** `
|
|
287
|
-
Constructor<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TConstructor<
|
|
288
|
-
/** `
|
|
289
|
-
Function<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TFunction<
|
|
290
|
-
/** `
|
|
291
|
-
Promise<T extends TSchema>(item: T, options?: CustomOptions): TPromise<
|
|
292
|
-
/** `
|
|
325
|
+
/** `Extended` Creates a constructor type */
|
|
326
|
+
Constructor<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TConstructor<T, U>;
|
|
327
|
+
/** `Extended` Creates a function type */
|
|
328
|
+
Function<T extends TSchema[], U extends TSchema>(args: [...T], returns: U, options?: CustomOptions): TFunction<T, U>;
|
|
329
|
+
/** `Extended` Creates a promise type */
|
|
330
|
+
Promise<T extends TSchema>(item: T, options?: CustomOptions): TPromise<T>;
|
|
331
|
+
/** `Extended` Creates a undefined type */
|
|
293
332
|
Undefined(options?: CustomOptions): TUndefined;
|
|
294
|
-
/** `
|
|
333
|
+
/** `Extended` Creates a void type */
|
|
295
334
|
Void(options?: CustomOptions): TVoid;
|
|
296
|
-
/** `
|
|
335
|
+
/** `Standard` Creates a namespace for a set of related types */
|
|
336
|
+
Namespace<T extends TDefinitions>($defs: T, options?: CustomOptions): TNamespace<T>;
|
|
337
|
+
/** `Standard` References a type within a namespace. The referenced namespace must specify an `$id` */
|
|
338
|
+
Ref<T extends TNamespace<TDefinitions>, K extends keyof T['$defs']>(box: T, key: K): TRef<T['$defs'][K]>;
|
|
339
|
+
/** `Standard` References type. The referenced type must specify an `$id` */
|
|
340
|
+
Ref<T extends TSchema>(schema: T): TRef<T>;
|
|
341
|
+
/** `Experimental` Creates a recursive type */
|
|
297
342
|
Rec<T extends TSchema>(callback: (self: TAny) => T, options?: CustomOptions): T;
|
|
298
|
-
/**
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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` */
|
|
304
|
-
Ref<T extends TSchema>(schema: T): T;
|
|
343
|
+
/** Stores this schema if it contains an $id. This function is used for later referencing. */
|
|
344
|
+
private Store;
|
|
345
|
+
/** Resolves a schema by $id. May resolve recursively if the target is a TRef. */
|
|
346
|
+
private Resolve;
|
|
305
347
|
}
|
|
306
348
|
export declare const Type: TypeBuilder;
|
package/typebox.js
CHANGED
|
@@ -27,16 +27,16 @@ THE SOFTWARE.
|
|
|
27
27
|
|
|
28
28
|
---------------------------------------------------------------------------*/
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.Type = exports.TypeBuilder = exports.VoidKind = exports.UndefinedKind = exports.PromiseKind = exports.FunctionKind = exports.ConstructorKind = exports.AnyKind = exports.UnknownKind = exports.NullKind = exports.BooleanKind = exports.IntegerKind = exports.NumberKind = exports.StringKind = exports.LiteralKind = exports.EnumKind = exports.ArrayKind = exports.RecordKind = exports.ObjectKind = exports.TupleKind = exports.UnionKind = exports.IntersectKind = exports.KeyOfKind = exports.BoxKind = exports.ReadonlyModifier = exports.OptionalModifier = exports.ReadonlyOptionalModifier = void 0;
|
|
31
|
-
//
|
|
30
|
+
exports.Type = exports.TypeBuilder = exports.VoidKind = exports.UndefinedKind = exports.PromiseKind = exports.FunctionKind = exports.ConstructorKind = exports.RefKind = exports.AnyKind = exports.UnknownKind = exports.NullKind = exports.BooleanKind = exports.IntegerKind = exports.NumberKind = exports.StringKind = exports.LiteralKind = exports.EnumKind = exports.ArrayKind = exports.RecordKind = exports.ObjectKind = exports.TupleKind = exports.UnionKind = exports.IntersectKind = exports.KeyOfKind = exports.BoxKind = exports.ReadonlyModifier = exports.OptionalModifier = exports.ReadonlyOptionalModifier = void 0;
|
|
31
|
+
// --------------------------------------------------------------------------
|
|
32
32
|
// Modifiers
|
|
33
|
-
//
|
|
33
|
+
// --------------------------------------------------------------------------
|
|
34
34
|
exports.ReadonlyOptionalModifier = Symbol('ReadonlyOptionalModifier');
|
|
35
35
|
exports.OptionalModifier = Symbol('OptionalModifier');
|
|
36
36
|
exports.ReadonlyModifier = Symbol('ReadonlyModifier');
|
|
37
|
-
//
|
|
37
|
+
// --------------------------------------------------------------------------
|
|
38
38
|
// Schema Standard
|
|
39
|
-
//
|
|
39
|
+
// --------------------------------------------------------------------------
|
|
40
40
|
exports.BoxKind = Symbol('BoxKind');
|
|
41
41
|
exports.KeyOfKind = Symbol('KeyOfKind');
|
|
42
42
|
exports.IntersectKind = Symbol('IntersectKind');
|
|
@@ -54,17 +54,18 @@ exports.BooleanKind = Symbol('BooleanKind');
|
|
|
54
54
|
exports.NullKind = Symbol('NullKind');
|
|
55
55
|
exports.UnknownKind = Symbol('UnknownKind');
|
|
56
56
|
exports.AnyKind = Symbol('AnyKind');
|
|
57
|
-
|
|
57
|
+
exports.RefKind = Symbol('RefKind');
|
|
58
|
+
// --------------------------------------------------------------------------
|
|
58
59
|
// Extended Schema Types
|
|
59
|
-
//
|
|
60
|
+
// --------------------------------------------------------------------------
|
|
60
61
|
exports.ConstructorKind = Symbol('ConstructorKind');
|
|
61
62
|
exports.FunctionKind = Symbol('FunctionKind');
|
|
62
63
|
exports.PromiseKind = Symbol('PromiseKind');
|
|
63
64
|
exports.UndefinedKind = Symbol('UndefinedKind');
|
|
64
65
|
exports.VoidKind = Symbol('VoidKind');
|
|
65
|
-
//
|
|
66
|
+
// --------------------------------------------------------------------------
|
|
66
67
|
// Utility
|
|
67
|
-
//
|
|
68
|
+
// --------------------------------------------------------------------------
|
|
68
69
|
function isObject(object) {
|
|
69
70
|
return typeof object === 'object' && object !== null && !Array.isArray(object);
|
|
70
71
|
}
|
|
@@ -78,32 +79,34 @@ function clone(object) {
|
|
|
78
79
|
return object.map((item) => clone(item));
|
|
79
80
|
return object;
|
|
80
81
|
}
|
|
81
|
-
//
|
|
82
|
+
// --------------------------------------------------------------------------
|
|
82
83
|
// TypeBuilder
|
|
83
|
-
//
|
|
84
|
+
// --------------------------------------------------------------------------
|
|
84
85
|
class TypeBuilder {
|
|
85
|
-
|
|
86
|
+
schemas = new Map();
|
|
87
|
+
/** `Standard` Modifies an object property to be both readonly and optional */
|
|
86
88
|
ReadonlyOptional(item) {
|
|
87
89
|
return { ...item, modifier: exports.ReadonlyOptionalModifier };
|
|
88
90
|
}
|
|
89
|
-
/** `
|
|
91
|
+
/** `Standard` Modifies an object property to be readonly */
|
|
90
92
|
Readonly(item) {
|
|
91
93
|
return { ...item, modifier: exports.ReadonlyModifier };
|
|
92
94
|
}
|
|
93
|
-
/** `
|
|
95
|
+
/** `Standard` Modifies an object property to be optional */
|
|
94
96
|
Optional(item) {
|
|
95
97
|
return { ...item, modifier: exports.OptionalModifier };
|
|
96
98
|
}
|
|
97
|
-
/** `
|
|
99
|
+
/** `Standard` Creates a type type */
|
|
98
100
|
Tuple(items, options = {}) {
|
|
99
101
|
const additionalItems = false;
|
|
100
102
|
const minItems = items.length;
|
|
101
103
|
const maxItems = items.length;
|
|
102
|
-
|
|
104
|
+
const schema = ((items.length > 0)
|
|
103
105
|
? { ...options, kind: exports.TupleKind, type: 'array', items, additionalItems, minItems, maxItems }
|
|
104
|
-
: { ...options, kind: exports.TupleKind, type: 'array', minItems, maxItems };
|
|
106
|
+
: { ...options, kind: exports.TupleKind, type: 'array', minItems, maxItems });
|
|
107
|
+
return this.Store(schema);
|
|
105
108
|
}
|
|
106
|
-
/** `
|
|
109
|
+
/** `Standard` Creates an object type with the given properties */
|
|
107
110
|
Object(properties, options = {}) {
|
|
108
111
|
const property_names = Object.keys(properties);
|
|
109
112
|
const optional = property_names.filter(name => {
|
|
@@ -114,88 +117,89 @@ class TypeBuilder {
|
|
|
114
117
|
});
|
|
115
118
|
const required_names = property_names.filter(name => !optional.includes(name));
|
|
116
119
|
const required = (required_names.length > 0) ? required_names : undefined;
|
|
117
|
-
return (required)
|
|
118
|
-
{ ...options, kind: exports.ObjectKind, type: 'object', properties, required }
|
|
119
|
-
{ ...options, kind: exports.ObjectKind, type: 'object', properties };
|
|
120
|
+
return this.Store(((required)
|
|
121
|
+
? { ...options, kind: exports.ObjectKind, type: 'object', properties, required }
|
|
122
|
+
: { ...options, kind: exports.ObjectKind, type: 'object', properties }));
|
|
120
123
|
}
|
|
121
|
-
/** `
|
|
124
|
+
/** `Standard` Creates an intersect type. */
|
|
122
125
|
Intersect(items, options = {}) {
|
|
123
|
-
return { ...options, kind: exports.IntersectKind, type: 'object', allOf: items };
|
|
126
|
+
return this.Store({ ...options, kind: exports.IntersectKind, type: 'object', allOf: items });
|
|
124
127
|
}
|
|
125
|
-
/** `
|
|
128
|
+
/** `Standard` Creates a union type */
|
|
126
129
|
Union(items, options = {}) {
|
|
127
|
-
return { ...options, kind: exports.UnionKind, anyOf: items };
|
|
130
|
+
return this.Store({ ...options, kind: exports.UnionKind, anyOf: items });
|
|
128
131
|
}
|
|
129
|
-
/** `
|
|
132
|
+
/** `Standard` Creates an array type */
|
|
130
133
|
Array(items, options = {}) {
|
|
131
|
-
return { ...options, kind: exports.ArrayKind, type: 'array', items };
|
|
134
|
+
return this.Store({ ...options, kind: exports.ArrayKind, type: 'array', items });
|
|
132
135
|
}
|
|
133
|
-
/** `
|
|
136
|
+
/** `Standard` Creates an enum type from a TypeScript enum */
|
|
134
137
|
Enum(item, options = {}) {
|
|
135
138
|
const values = Object.keys(item).filter(key => isNaN(key)).map(key => item[key]);
|
|
136
139
|
const anyOf = values.map(value => typeof value === 'string' ? { type: 'string', const: value } : { type: 'number', const: value });
|
|
137
|
-
return { ...options, kind: exports.EnumKind, anyOf };
|
|
140
|
+
return this.Store({ ...options, kind: exports.EnumKind, anyOf });
|
|
138
141
|
}
|
|
139
|
-
/** `
|
|
142
|
+
/** `Standard` Creates a literal type. Supports string, number and boolean values only */
|
|
140
143
|
Literal(value, options = {}) {
|
|
141
|
-
return { ...options, kind: exports.LiteralKind, const: value, type: typeof value };
|
|
144
|
+
return this.Store({ ...options, kind: exports.LiteralKind, const: value, type: typeof value });
|
|
142
145
|
}
|
|
143
|
-
/** `
|
|
146
|
+
/** `Standard` Creates a string type */
|
|
144
147
|
String(options = {}) {
|
|
145
|
-
return { ...options, kind: exports.StringKind, type: 'string' };
|
|
148
|
+
return this.Store({ ...options, kind: exports.StringKind, type: 'string' });
|
|
146
149
|
}
|
|
147
|
-
/** `
|
|
150
|
+
/** `Standard` Creates a string type from a regular expression */
|
|
148
151
|
RegEx(regex, options = {}) {
|
|
149
152
|
return this.String({ ...options, pattern: regex.source });
|
|
150
153
|
}
|
|
151
|
-
/** `
|
|
154
|
+
/** `Standard` Creates a number type */
|
|
152
155
|
Number(options = {}) {
|
|
153
|
-
return { ...options, kind: exports.NumberKind, type: 'number' };
|
|
156
|
+
return this.Store({ ...options, kind: exports.NumberKind, type: 'number' });
|
|
154
157
|
}
|
|
155
|
-
/** `
|
|
158
|
+
/** `Standard` Creates an integer type */
|
|
156
159
|
Integer(options = {}) {
|
|
157
|
-
return { ...options, kind: exports.IntegerKind, type: 'integer' };
|
|
160
|
+
return this.Store({ ...options, kind: exports.IntegerKind, type: 'integer' });
|
|
158
161
|
}
|
|
159
|
-
/** `
|
|
162
|
+
/** `Standard` Creates a boolean type */
|
|
160
163
|
Boolean(options = {}) {
|
|
161
|
-
return { ...options, kind: exports.BooleanKind, type: 'boolean' };
|
|
164
|
+
return this.Store({ ...options, kind: exports.BooleanKind, type: 'boolean' });
|
|
162
165
|
}
|
|
163
|
-
/** `
|
|
166
|
+
/** `Standard` Creates a null type */
|
|
164
167
|
Null(options = {}) {
|
|
165
|
-
return { ...options, kind: exports.NullKind, type: 'null' };
|
|
168
|
+
return this.Store({ ...options, kind: exports.NullKind, type: 'null' });
|
|
166
169
|
}
|
|
167
|
-
/** `
|
|
170
|
+
/** `Standard` Creates an unknown type */
|
|
168
171
|
Unknown(options = {}) {
|
|
169
|
-
return { ...options, kind: exports.UnknownKind };
|
|
172
|
+
return this.Store({ ...options, kind: exports.UnknownKind });
|
|
170
173
|
}
|
|
171
|
-
/** `
|
|
174
|
+
/** `Standard` Creates an any type */
|
|
172
175
|
Any(options = {}) {
|
|
173
|
-
return { ...options, kind: exports.AnyKind };
|
|
176
|
+
return this.Store({ ...options, kind: exports.AnyKind });
|
|
174
177
|
}
|
|
175
|
-
/** `
|
|
176
|
-
KeyOf(
|
|
177
|
-
const keys = Object.keys(
|
|
178
|
-
return { ...options, kind: exports.KeyOfKind, type: 'string', enum: keys };
|
|
178
|
+
/** `Standard` Creates a keyof type from the given object */
|
|
179
|
+
KeyOf(object, options = {}) {
|
|
180
|
+
const keys = Object.keys(object.properties);
|
|
181
|
+
return this.Store({ ...options, kind: exports.KeyOfKind, type: 'string', enum: keys });
|
|
179
182
|
}
|
|
180
|
-
/** `
|
|
183
|
+
/** `Standard` Creates a record type */
|
|
181
184
|
Record(key, value, options = {}) {
|
|
182
185
|
const pattern = (() => {
|
|
183
186
|
switch (key.kind) {
|
|
184
|
-
case exports.UnionKind: return `^${key.anyOf.map(literal => literal.const).join('|')}$`;
|
|
187
|
+
case exports.UnionKind: return `^${key.anyOf.map((literal) => literal.const).join('|')}$`;
|
|
185
188
|
case exports.KeyOfKind: return `^${key.enum.join('|')}$`;
|
|
186
189
|
case exports.NumberKind: return '^(0|[1-9][0-9]*)$';
|
|
187
190
|
case exports.StringKind: return key.pattern ? key.pattern : '^.*$';
|
|
188
191
|
default: throw Error('Invalid Record Key');
|
|
189
192
|
}
|
|
190
193
|
})();
|
|
191
|
-
return { ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } };
|
|
192
|
-
}
|
|
193
|
-
/** `
|
|
194
|
-
Required(
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
194
|
+
return this.Store({ ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } });
|
|
195
|
+
}
|
|
196
|
+
/** `Standard` Makes all properties in the given object type required */
|
|
197
|
+
Required(object, options = {}) {
|
|
198
|
+
const source = this.Resolve(object);
|
|
199
|
+
const schema = { ...clone(source), ...options };
|
|
200
|
+
schema.required = Object.keys(schema.properties);
|
|
201
|
+
for (const key of Object.keys(schema.properties)) {
|
|
202
|
+
const property = schema.properties[key];
|
|
199
203
|
switch (property.modifier) {
|
|
200
204
|
case exports.ReadonlyOptionalModifier:
|
|
201
205
|
property.modifier = exports.ReadonlyModifier;
|
|
@@ -211,14 +215,15 @@ class TypeBuilder {
|
|
|
211
215
|
break;
|
|
212
216
|
}
|
|
213
217
|
}
|
|
214
|
-
return
|
|
215
|
-
}
|
|
216
|
-
/** `
|
|
217
|
-
Partial(
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
218
|
+
return this.Store(schema);
|
|
219
|
+
}
|
|
220
|
+
/** `Standard` Makes all properties in the given object type optional */
|
|
221
|
+
Partial(object, options = {}) {
|
|
222
|
+
const source = this.Resolve(object);
|
|
223
|
+
const schema = { ...clone(source), ...options };
|
|
224
|
+
delete schema.required;
|
|
225
|
+
for (const key of Object.keys(schema.properties)) {
|
|
226
|
+
const property = schema.properties[key];
|
|
222
227
|
switch (property.modifier) {
|
|
223
228
|
case exports.ReadonlyOptionalModifier:
|
|
224
229
|
property.modifier = exports.ReadonlyOptionalModifier;
|
|
@@ -234,71 +239,100 @@ class TypeBuilder {
|
|
|
234
239
|
break;
|
|
235
240
|
}
|
|
236
241
|
}
|
|
237
|
-
return
|
|
238
|
-
}
|
|
239
|
-
/** `
|
|
240
|
-
Pick(
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
return this.Store(schema);
|
|
243
|
+
}
|
|
244
|
+
/** `Standard` Picks property keys from the given object type */
|
|
245
|
+
Pick(object, keys, options = {}) {
|
|
246
|
+
const source = this.Resolve(object);
|
|
247
|
+
const schema = { ...clone(source), ...options };
|
|
248
|
+
schema.required = schema.required ? schema.required.filter((key) => keys.includes(key)) : undefined;
|
|
249
|
+
for (const key of Object.keys(schema.properties)) {
|
|
244
250
|
if (!keys.includes(key))
|
|
245
|
-
delete
|
|
251
|
+
delete schema.properties[key];
|
|
246
252
|
}
|
|
247
|
-
return
|
|
248
|
-
}
|
|
249
|
-
/** `
|
|
250
|
-
Omit(
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
253
|
+
return this.Store(schema);
|
|
254
|
+
}
|
|
255
|
+
/** `Standard` Omits property keys from the given object type */
|
|
256
|
+
Omit(object, keys, options = {}) {
|
|
257
|
+
const source = this.Resolve(object);
|
|
258
|
+
const schema = { ...clone(source), ...options };
|
|
259
|
+
schema.required = schema.required ? schema.required.filter((key) => !keys.includes(key)) : undefined;
|
|
260
|
+
for (const key of Object.keys(schema.properties)) {
|
|
254
261
|
if (keys.includes(key))
|
|
255
|
-
delete
|
|
262
|
+
delete schema.properties[key];
|
|
256
263
|
}
|
|
257
|
-
return
|
|
264
|
+
return this.Store(schema);
|
|
258
265
|
}
|
|
259
|
-
/** `
|
|
266
|
+
/** `Standard` Omits the `kind` and `modifier` properties from the underlying schema */
|
|
260
267
|
Strict(schema, options = {}) {
|
|
261
268
|
return JSON.parse(JSON.stringify({ ...options, ...schema }));
|
|
262
269
|
}
|
|
263
|
-
/** `
|
|
270
|
+
/** `Extended` Creates a constructor type */
|
|
264
271
|
Constructor(args, returns, options = {}) {
|
|
265
|
-
return { ...options, kind: exports.ConstructorKind, type: 'constructor', arguments: args, returns };
|
|
272
|
+
return this.Store({ ...options, kind: exports.ConstructorKind, type: 'constructor', arguments: args, returns });
|
|
266
273
|
}
|
|
267
|
-
/** `
|
|
274
|
+
/** `Extended` Creates a function type */
|
|
268
275
|
Function(args, returns, options = {}) {
|
|
269
|
-
return { ...options, kind: exports.FunctionKind, type: 'function', arguments: args, returns };
|
|
276
|
+
return this.Store({ ...options, kind: exports.FunctionKind, type: 'function', arguments: args, returns });
|
|
270
277
|
}
|
|
271
|
-
/** `
|
|
278
|
+
/** `Extended` Creates a promise type */
|
|
272
279
|
Promise(item, options = {}) {
|
|
273
|
-
return { ...options, type: 'promise', kind: exports.PromiseKind, item };
|
|
280
|
+
return this.Store({ ...options, type: 'promise', kind: exports.PromiseKind, item });
|
|
274
281
|
}
|
|
275
|
-
/** `
|
|
282
|
+
/** `Extended` Creates a undefined type */
|
|
276
283
|
Undefined(options = {}) {
|
|
277
|
-
return { ...options, type: 'undefined', kind: exports.UndefinedKind };
|
|
284
|
+
return this.Store({ ...options, type: 'undefined', kind: exports.UndefinedKind });
|
|
278
285
|
}
|
|
279
|
-
/** `
|
|
286
|
+
/** `Extended` Creates a void type */
|
|
280
287
|
Void(options = {}) {
|
|
281
|
-
return { ...options, type: 'void', kind: exports.VoidKind };
|
|
288
|
+
return this.Store({ ...options, type: 'void', kind: exports.VoidKind });
|
|
282
289
|
}
|
|
283
|
-
/** `
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const self = callback({ $ref: `${$id}#/definitions/self` });
|
|
287
|
-
return { ...options, $ref: `${$id}#/definitions/self`, definitions: { self } };
|
|
288
|
-
}
|
|
289
|
-
/** `experimental` Creates a recursive type. Pending https://github.com/ajv-validator/ajv/issues/1709 */
|
|
290
|
-
// public Rec<T extends TProperties>($id: string, callback: (self: TAny) => T, options: ObjectOptions = {}): TObject<T> {
|
|
291
|
-
// const properties = callback({ $recursiveRef: `${$id}` } as any)
|
|
292
|
-
// return { ...options, kind: ObjectKind, $id, $recursiveAnchor: true, type: 'object', properties }
|
|
293
|
-
// }
|
|
294
|
-
/** `experimental` Creates a namespace for a set of related types */
|
|
295
|
-
Namespace(definitions, options = {}) {
|
|
296
|
-
return { ...options, kind: exports.BoxKind, definitions };
|
|
290
|
+
/** `Standard` Creates a namespace for a set of related types */
|
|
291
|
+
Namespace($defs, options = {}) {
|
|
292
|
+
return this.Store({ ...options, kind: exports.BoxKind, $defs });
|
|
297
293
|
}
|
|
298
294
|
Ref(...args) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
295
|
+
if (args.length === 2) {
|
|
296
|
+
const namespace = args[0];
|
|
297
|
+
const targetKey = args[1];
|
|
298
|
+
if (namespace.$id === undefined)
|
|
299
|
+
throw new Error(`Referenced namespace has no $id`);
|
|
300
|
+
if (!this.schemas.has(namespace.$id))
|
|
301
|
+
throw new Error(`Unable to locate namespace with $id '${namespace.$id}'`);
|
|
302
|
+
return this.Store({ kind: exports.RefKind, $ref: `${namespace.$id}#/$defs/${targetKey}` });
|
|
303
|
+
}
|
|
304
|
+
else if (args.length === 1) {
|
|
305
|
+
const target = args[0];
|
|
306
|
+
if (target.$id === undefined)
|
|
307
|
+
throw new Error(`Referenced schema has no $id`);
|
|
308
|
+
if (!this.schemas.has(target.$id))
|
|
309
|
+
throw new Error(`Unable to locate schema with $id '${target.$id}'`);
|
|
310
|
+
return this.Store({ kind: exports.RefKind, $ref: target.$id });
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
throw new Error('Type.Ref: Invalid arguments');
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/** `Experimental` Creates a recursive type */
|
|
317
|
+
Rec(callback, options = {}) {
|
|
318
|
+
const $id = options.$id || '';
|
|
319
|
+
const self = callback({ $ref: `${$id}#/$defs/self` });
|
|
320
|
+
return this.Store({ ...options, $ref: `${$id}#/$defs/self`, $defs: { self } });
|
|
321
|
+
}
|
|
322
|
+
/** Stores this schema if it contains an $id. This function is used for later referencing. */
|
|
323
|
+
Store(schema) {
|
|
324
|
+
if (!schema.$id)
|
|
325
|
+
return schema;
|
|
326
|
+
this.schemas.set(schema.$id, schema);
|
|
327
|
+
return schema;
|
|
328
|
+
}
|
|
329
|
+
/** Resolves a schema by $id. May resolve recursively if the target is a TRef. */
|
|
330
|
+
Resolve(schema) {
|
|
331
|
+
if (schema.kind !== exports.RefKind)
|
|
332
|
+
return schema;
|
|
333
|
+
if (!this.schemas.has(schema.$ref))
|
|
334
|
+
throw Error(`Unable to locate schema with $id '${schema.$ref}'`);
|
|
335
|
+
return this.Resolve(this.schemas.get(schema.$ref));
|
|
302
336
|
}
|
|
303
337
|
}
|
|
304
338
|
exports.TypeBuilder = TypeBuilder;
|