@sinclair/typebox 0.22.0 → 0.23.2
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 +1 -1
- package/readme.md +209 -258
- package/typebox.d.ts +54 -41
- package/typebox.js +103 -66
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;
|
|
@@ -71,7 +72,7 @@ export declare type TNamespace<T extends TDefinitions> = {
|
|
|
71
72
|
$defs: T;
|
|
72
73
|
} & CustomOptions;
|
|
73
74
|
export interface TSchema {
|
|
74
|
-
|
|
75
|
+
$static: unknown;
|
|
75
76
|
}
|
|
76
77
|
export declare type TEnumType = Record<string, string | number>;
|
|
77
78
|
export declare type TKey = string | number | symbol;
|
|
@@ -85,7 +86,7 @@ export interface TProperties {
|
|
|
85
86
|
[key: string]: TSchema;
|
|
86
87
|
}
|
|
87
88
|
export interface TRecord<K extends TRecordKey, T extends TSchema> extends TSchema, ObjectOptions {
|
|
88
|
-
|
|
89
|
+
$static: StaticRecord<K, T>;
|
|
89
90
|
kind: typeof RecordKind;
|
|
90
91
|
type: 'object';
|
|
91
92
|
patternProperties: {
|
|
@@ -93,7 +94,7 @@ export interface TRecord<K extends TRecordKey, T extends TSchema> extends TSchem
|
|
|
93
94
|
};
|
|
94
95
|
}
|
|
95
96
|
export interface TTuple<T extends TSchema[]> extends TSchema, CustomOptions {
|
|
96
|
-
|
|
97
|
+
$static: StaticTuple<T>;
|
|
97
98
|
kind: typeof TupleKind;
|
|
98
99
|
type: 'array';
|
|
99
100
|
items?: T;
|
|
@@ -102,76 +103,81 @@ export interface TTuple<T extends TSchema[]> extends TSchema, CustomOptions {
|
|
|
102
103
|
maxItems: number;
|
|
103
104
|
}
|
|
104
105
|
export interface TObject<T extends TProperties> extends TSchema, ObjectOptions {
|
|
105
|
-
|
|
106
|
+
$static: StaticObject<T>;
|
|
106
107
|
kind: typeof ObjectKind;
|
|
107
108
|
type: 'object';
|
|
108
109
|
properties: T;
|
|
109
110
|
required?: string[];
|
|
110
111
|
}
|
|
111
112
|
export interface TUnion<T extends TSchema[]> extends TSchema, CustomOptions {
|
|
112
|
-
|
|
113
|
+
$static: StaticUnion<T>;
|
|
113
114
|
kind: typeof UnionKind;
|
|
114
115
|
anyOf: T;
|
|
115
116
|
}
|
|
116
117
|
export interface TIntersect<T extends TSchema[]> extends TSchema, IntersectOptions {
|
|
117
|
-
|
|
118
|
+
$static: StaticIntersect<T>;
|
|
118
119
|
kind: typeof IntersectKind;
|
|
119
120
|
type: 'object';
|
|
120
121
|
allOf: T;
|
|
121
122
|
}
|
|
122
123
|
export interface TKeyOf<T extends TKey[]> extends TSchema, CustomOptions {
|
|
123
|
-
|
|
124
|
+
$static: StaticKeyOf<T>;
|
|
124
125
|
kind: typeof KeyOfKind;
|
|
125
126
|
type: 'string';
|
|
126
127
|
enum: T;
|
|
127
128
|
}
|
|
128
129
|
export interface TArray<T extends TSchema> extends TSchema, ArrayOptions {
|
|
129
|
-
|
|
130
|
+
$static: StaticArray<T>;
|
|
130
131
|
kind: typeof ArrayKind;
|
|
131
132
|
type: 'array';
|
|
132
133
|
items: T;
|
|
133
134
|
}
|
|
134
135
|
export interface TLiteral<T extends TValue> extends TSchema, CustomOptions {
|
|
135
|
-
|
|
136
|
+
$static: StaticLiteral<T>;
|
|
136
137
|
kind: typeof LiteralKind;
|
|
137
138
|
const: T;
|
|
138
139
|
}
|
|
139
140
|
export interface TEnum<T extends TEnumKey[]> extends TSchema, CustomOptions {
|
|
140
|
-
|
|
141
|
+
$static: StaticEnum<T>;
|
|
141
142
|
kind: typeof EnumKind;
|
|
142
143
|
anyOf: T;
|
|
143
144
|
}
|
|
145
|
+
export interface TRef<T extends TSchema> extends TSchema, CustomOptions {
|
|
146
|
+
$static: Static<T>;
|
|
147
|
+
kind: typeof RefKind;
|
|
148
|
+
$ref: string;
|
|
149
|
+
}
|
|
144
150
|
export interface TString extends TSchema, StringOptions<string> {
|
|
145
|
-
|
|
151
|
+
$static: string;
|
|
146
152
|
kind: typeof StringKind;
|
|
147
153
|
type: 'string';
|
|
148
154
|
}
|
|
149
155
|
export interface TNumber extends TSchema, NumberOptions {
|
|
150
|
-
|
|
156
|
+
$static: number;
|
|
151
157
|
kind: typeof NumberKind;
|
|
152
158
|
type: 'number';
|
|
153
159
|
}
|
|
154
160
|
export interface TInteger extends TSchema, NumberOptions {
|
|
155
|
-
|
|
161
|
+
$static: number;
|
|
156
162
|
kind: typeof IntegerKind;
|
|
157
163
|
type: 'integer';
|
|
158
164
|
}
|
|
159
165
|
export interface TBoolean extends TSchema, CustomOptions {
|
|
160
|
-
|
|
166
|
+
$static: boolean;
|
|
161
167
|
kind: typeof BooleanKind;
|
|
162
168
|
type: 'boolean';
|
|
163
169
|
}
|
|
164
170
|
export interface TNull extends TSchema, CustomOptions {
|
|
165
|
-
|
|
171
|
+
$static: null;
|
|
166
172
|
kind: typeof NullKind;
|
|
167
173
|
type: 'null';
|
|
168
174
|
}
|
|
169
175
|
export interface TUnknown extends TSchema, CustomOptions {
|
|
170
|
-
|
|
176
|
+
$static: unknown;
|
|
171
177
|
kind: typeof UnknownKind;
|
|
172
178
|
}
|
|
173
179
|
export interface TAny extends TSchema, CustomOptions {
|
|
174
|
-
|
|
180
|
+
$static: any;
|
|
175
181
|
kind: typeof AnyKind;
|
|
176
182
|
}
|
|
177
183
|
export declare const ConstructorKind: unique symbol;
|
|
@@ -180,35 +186,38 @@ export declare const PromiseKind: unique symbol;
|
|
|
180
186
|
export declare const UndefinedKind: unique symbol;
|
|
181
187
|
export declare const VoidKind: unique symbol;
|
|
182
188
|
export interface TConstructor<T extends TSchema[], U extends TSchema> extends TSchema, CustomOptions {
|
|
183
|
-
|
|
189
|
+
$static: StaticConstructor<T, U>;
|
|
184
190
|
kind: typeof ConstructorKind;
|
|
185
191
|
type: 'constructor';
|
|
186
192
|
arguments: TSchema[];
|
|
187
193
|
returns: TSchema;
|
|
188
194
|
}
|
|
189
195
|
export interface TFunction<T extends TSchema[], U extends TSchema> extends TSchema, CustomOptions {
|
|
190
|
-
|
|
196
|
+
$static: StaticFunction<T, U>;
|
|
191
197
|
kind: typeof FunctionKind;
|
|
192
198
|
type: 'function';
|
|
193
199
|
arguments: TSchema[];
|
|
194
200
|
returns: TSchema;
|
|
195
201
|
}
|
|
196
202
|
export interface TPromise<T extends TSchema> extends TSchema, CustomOptions {
|
|
197
|
-
|
|
203
|
+
$static: StaticPromise<T>;
|
|
198
204
|
kind: typeof PromiseKind;
|
|
199
205
|
type: 'promise';
|
|
200
206
|
item: TSchema;
|
|
201
207
|
}
|
|
202
208
|
export interface TUndefined extends TSchema, CustomOptions {
|
|
203
|
-
|
|
209
|
+
$static: undefined;
|
|
204
210
|
kind: typeof UndefinedKind;
|
|
205
211
|
type: 'undefined';
|
|
206
212
|
}
|
|
207
213
|
export interface TVoid extends TSchema, CustomOptions {
|
|
208
|
-
|
|
214
|
+
$static: void;
|
|
209
215
|
kind: typeof VoidKind;
|
|
210
216
|
type: 'void';
|
|
211
217
|
}
|
|
218
|
+
export declare type Selectable = TObject<TProperties> | TRef<TObject<TProperties>>;
|
|
219
|
+
export declare type SelectablePropertyKeys<T extends Selectable> = T extends TObject<infer U> ? keyof U : T extends TRef<TObject<infer U>> ? keyof U : never;
|
|
220
|
+
export declare type SelectableProperties<T extends Selectable> = T extends TObject<infer U> ? U : T extends TRef<TObject<infer U>> ? U : never;
|
|
212
221
|
export declare type UnionToIntersect<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
213
222
|
export declare type StaticReadonlyOptionalPropertyKeys<T extends TProperties> = {
|
|
214
223
|
[K in keyof T]: T[K] extends TReadonlyOptional<TSchema> ? K : never;
|
|
@@ -221,7 +230,7 @@ export declare type StaticOptionalPropertyKeys<T extends TProperties> = {
|
|
|
221
230
|
}[keyof T];
|
|
222
231
|
export declare type StaticRequiredPropertyKeys<T extends TProperties> = keyof Omit<T, StaticReadonlyOptionalPropertyKeys<T> | StaticReadonlyPropertyKeys<T> | StaticOptionalPropertyKeys<T>>;
|
|
223
232
|
export declare type StaticIntersectEvaluate<T extends readonly TSchema[]> = {
|
|
224
|
-
[K in keyof T]: Static<T[K]
|
|
233
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
225
234
|
};
|
|
226
235
|
export declare type StaticIntersectReduce<I extends unknown, T extends readonly any[]> = T extends [infer A, ...infer B] ? StaticIntersectReduce<I & A, B> : I;
|
|
227
236
|
export declare type StaticRequired<T extends TProperties> = {
|
|
@@ -239,15 +248,15 @@ export declare type StaticProperties<T extends TProperties> = {
|
|
|
239
248
|
} & {
|
|
240
249
|
[K in StaticRequiredPropertyKeys<T>]: Static<T[K]>;
|
|
241
250
|
};
|
|
242
|
-
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['
|
|
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;
|
|
243
252
|
export declare type StaticEnum<T> = T extends TEnumKey<infer U>[] ? U : never;
|
|
244
253
|
export declare type StaticKeyOf<T extends TKey[]> = T extends Array<infer K> ? K : never;
|
|
245
254
|
export declare type StaticIntersect<T extends readonly TSchema[]> = StaticIntersectReduce<unknown, StaticIntersectEvaluate<T>>;
|
|
246
255
|
export declare type StaticUnion<T extends readonly TSchema[]> = {
|
|
247
|
-
[K in keyof T]: Static<T[K]
|
|
256
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
248
257
|
}[number];
|
|
249
258
|
export declare type StaticTuple<T extends readonly TSchema[]> = {
|
|
250
|
-
[K in keyof T]: Static<T[K]
|
|
259
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
251
260
|
};
|
|
252
261
|
export declare type StaticObject<T extends TProperties> = StaticProperties<T> extends infer I ? {
|
|
253
262
|
[K in keyof I]: I[K];
|
|
@@ -255,13 +264,14 @@ export declare type StaticObject<T extends TProperties> = StaticProperties<T> ex
|
|
|
255
264
|
export declare type StaticArray<T extends TSchema> = Array<Static<T>>;
|
|
256
265
|
export declare type StaticLiteral<T extends TValue> = T;
|
|
257
266
|
export declare type StaticParameters<T extends readonly TSchema[]> = {
|
|
258
|
-
[K in keyof T]: Static<T[K]
|
|
267
|
+
[K in keyof T]: T[K] extends TSchema ? Static<T[K]> : never;
|
|
259
268
|
};
|
|
260
269
|
export declare type StaticConstructor<T extends readonly TSchema[], U extends TSchema> = new (...args: [...StaticParameters<T>]) => Static<U>;
|
|
261
270
|
export declare type StaticFunction<T extends readonly TSchema[], U extends TSchema> = (...args: [...StaticParameters<T>]) => Static<U>;
|
|
262
271
|
export declare type StaticPromise<T extends TSchema> = Promise<Static<T>>;
|
|
263
|
-
export declare type Static<T
|
|
272
|
+
export declare type Static<T extends TSchema> = T['$static'];
|
|
264
273
|
export declare class TypeBuilder {
|
|
274
|
+
protected readonly schemas: Map<string, TSchema>;
|
|
265
275
|
/** `Standard` Modifies an object property to be both readonly and optional */
|
|
266
276
|
ReadonlyOptional<T extends TSchema>(item: T): TReadonlyOptional<T>;
|
|
267
277
|
/** `Standard` Modifies an object property to be readonly */
|
|
@@ -298,18 +308,18 @@ export declare class TypeBuilder {
|
|
|
298
308
|
Unknown(options?: CustomOptions): TUnknown;
|
|
299
309
|
/** `Standard` Creates an any type */
|
|
300
310
|
Any(options?: CustomOptions): TAny;
|
|
301
|
-
/** `Standard` Creates a keyof type from the given object */
|
|
302
|
-
KeyOf<T extends TObject<TProperties>>(schema: T, options?: CustomOptions): TKeyOf<(keyof T['properties'])[]>;
|
|
303
311
|
/** `Standard` Creates a record type */
|
|
304
312
|
Record<K extends TRecordKey, T extends TSchema>(key: K, value: T, options?: ObjectOptions): TRecord<K, T>;
|
|
313
|
+
/** `Standard` Creates a keyof type from the given object */
|
|
314
|
+
KeyOf<T extends TObject<TProperties> | TRef<TObject<TProperties>>>(object: T, options?: CustomOptions): TKeyOf<SelectablePropertyKeys<T>[]>;
|
|
305
315
|
/** `Standard` Makes all properties in the given object type required */
|
|
306
|
-
Required<T extends TObject<
|
|
316
|
+
Required<T extends TObject<TProperties> | TRef<TObject<TProperties>>>(object: T, options?: ObjectOptions): TObject<StaticRequired<T['properties']>>;
|
|
307
317
|
/** `Standard` Makes all properties in the given object type optional */
|
|
308
|
-
Partial<T extends TObject<
|
|
318
|
+
Partial<T extends TObject<TProperties> | TRef<TObject<TProperties>>>(object: T, options?: ObjectOptions): TObject<StaticPartial<T['properties']>>;
|
|
309
319
|
/** `Standard` Picks property keys from the given object type */
|
|
310
|
-
Pick<T extends TObject<TProperties
|
|
320
|
+
Pick<T extends TObject<TProperties> | TRef<TObject<TProperties>>, K extends SelectablePropertyKeys<T>[]>(object: T, keys: [...K], options?: ObjectOptions): TObject<Pick<SelectableProperties<T>, K[number]>>;
|
|
311
321
|
/** `Standard` Omits property keys from the given object type */
|
|
312
|
-
Omit<T extends TObject<
|
|
322
|
+
Omit<T extends TObject<TProperties> | TRef<TObject<TProperties>>, K extends SelectablePropertyKeys<T>[]>(object: T, keys: [...K], options?: ObjectOptions): TObject<Omit<SelectableProperties<T>, K[number]>>;
|
|
313
323
|
/** `Standard` Omits the `kind` and `modifier` properties from the underlying schema */
|
|
314
324
|
Strict<T extends TSchema>(schema: T, options?: CustomOptions): T;
|
|
315
325
|
/** `Extended` Creates a constructor type */
|
|
@@ -322,14 +332,17 @@ export declare class TypeBuilder {
|
|
|
322
332
|
Undefined(options?: CustomOptions): TUndefined;
|
|
323
333
|
/** `Extended` Creates a void type */
|
|
324
334
|
Void(options?: CustomOptions): TVoid;
|
|
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']>(namespace: 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>;
|
|
325
341
|
/** `Experimental` Creates a recursive type */
|
|
326
342
|
Rec<T extends TSchema>(callback: (self: TAny) => T, options?: CustomOptions): T;
|
|
327
|
-
/**
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
Ref<T extends TNamespace<TDefinitions>, K extends keyof T['$defs']>(box: T, key: K): T['$defs'][K];
|
|
332
|
-
/** `Experimental` References type. The referenced type must specify an `$id` */
|
|
333
|
-
Ref<T extends TSchema>(schema: T): T;
|
|
343
|
+
/** Conditionally stores and schema if it contains an $id and returns */
|
|
344
|
+
protected Store<T extends TSchema | TNamespace<TDefinitions>, S = Omit<T, '$static'>>(schema: S): T;
|
|
345
|
+
/** Conditionally dereferences a schema if RefKind. Otherwise return argument */
|
|
346
|
+
protected Deref<T extends TSchema>(schema: T): any;
|
|
334
347
|
}
|
|
335
348
|
export declare const Type: TypeBuilder;
|
package/typebox.js
CHANGED
|
@@ -27,7 +27,7 @@ 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;
|
|
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
31
|
// --------------------------------------------------------------------------
|
|
32
32
|
// Modifiers
|
|
33
33
|
// --------------------------------------------------------------------------
|
|
@@ -54,6 +54,7 @@ exports.BooleanKind = Symbol('BooleanKind');
|
|
|
54
54
|
exports.NullKind = Symbol('NullKind');
|
|
55
55
|
exports.UnknownKind = Symbol('UnknownKind');
|
|
56
56
|
exports.AnyKind = Symbol('AnyKind');
|
|
57
|
+
exports.RefKind = Symbol('RefKind');
|
|
57
58
|
// --------------------------------------------------------------------------
|
|
58
59
|
// Extended Schema Types
|
|
59
60
|
// --------------------------------------------------------------------------
|
|
@@ -82,6 +83,7 @@ function clone(object) {
|
|
|
82
83
|
// TypeBuilder
|
|
83
84
|
// --------------------------------------------------------------------------
|
|
84
85
|
class TypeBuilder {
|
|
86
|
+
schemas = new Map();
|
|
85
87
|
/** `Standard` Modifies an object property to be both readonly and optional */
|
|
86
88
|
ReadonlyOptional(item) {
|
|
87
89
|
return { ...item, modifier: exports.ReadonlyOptionalModifier };
|
|
@@ -99,9 +101,10 @@ class TypeBuilder {
|
|
|
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
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 = {}) {
|
|
@@ -114,35 +117,35 @@ 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)
|
|
120
|
+
return this.Store(((required)
|
|
118
121
|
? { ...options, kind: exports.ObjectKind, type: 'object', properties, required }
|
|
119
|
-
: { ...options, kind: exports.ObjectKind, type: 'object', properties });
|
|
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 = {}) {
|
|
@@ -150,32 +153,27 @@ class TypeBuilder {
|
|
|
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 };
|
|
174
|
-
}
|
|
175
|
-
/** `Standard` Creates a keyof type from the given object */
|
|
176
|
-
KeyOf(schema, options = {}) {
|
|
177
|
-
const keys = Object.keys(schema.properties);
|
|
178
|
-
return { ...options, kind: exports.KeyOfKind, type: 'string', enum: keys };
|
|
176
|
+
return this.Store({ ...options, kind: exports.AnyKind });
|
|
179
177
|
}
|
|
180
178
|
/** `Standard` Creates a record type */
|
|
181
179
|
Record(key, value, options = {}) {
|
|
@@ -188,14 +186,21 @@ class TypeBuilder {
|
|
|
188
186
|
default: throw Error('Invalid Record Key');
|
|
189
187
|
}
|
|
190
188
|
})();
|
|
191
|
-
return { ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } };
|
|
189
|
+
return this.Store({ ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } });
|
|
190
|
+
}
|
|
191
|
+
/** `Standard` Creates a keyof type from the given object */
|
|
192
|
+
KeyOf(object, options = {}) {
|
|
193
|
+
const source = this.Deref(object);
|
|
194
|
+
const keys = Object.keys(source.properties);
|
|
195
|
+
return this.Store({ ...options, kind: exports.KeyOfKind, type: 'string', enum: keys });
|
|
192
196
|
}
|
|
193
197
|
/** `Standard` Makes all properties in the given object type required */
|
|
194
|
-
Required(
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
198
|
+
Required(object, options = {}) {
|
|
199
|
+
const source = this.Deref(object);
|
|
200
|
+
const schema = { ...clone(source), ...options };
|
|
201
|
+
schema.required = Object.keys(schema.properties);
|
|
202
|
+
for (const key of Object.keys(schema.properties)) {
|
|
203
|
+
const property = schema.properties[key];
|
|
199
204
|
switch (property.modifier) {
|
|
200
205
|
case exports.ReadonlyOptionalModifier:
|
|
201
206
|
property.modifier = exports.ReadonlyModifier;
|
|
@@ -211,14 +216,15 @@ class TypeBuilder {
|
|
|
211
216
|
break;
|
|
212
217
|
}
|
|
213
218
|
}
|
|
214
|
-
return
|
|
219
|
+
return this.Store(schema);
|
|
215
220
|
}
|
|
216
221
|
/** `Standard` Makes all properties in the given object type optional */
|
|
217
|
-
Partial(
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
+
Partial(object, options = {}) {
|
|
223
|
+
const source = this.Deref(object);
|
|
224
|
+
const schema = { ...clone(source), ...options };
|
|
225
|
+
delete schema.required;
|
|
226
|
+
for (const key of Object.keys(schema.properties)) {
|
|
227
|
+
const property = schema.properties[key];
|
|
222
228
|
switch (property.modifier) {
|
|
223
229
|
case exports.ReadonlyOptionalModifier:
|
|
224
230
|
property.modifier = exports.ReadonlyOptionalModifier;
|
|
@@ -234,27 +240,29 @@ class TypeBuilder {
|
|
|
234
240
|
break;
|
|
235
241
|
}
|
|
236
242
|
}
|
|
237
|
-
return
|
|
243
|
+
return this.Store(schema);
|
|
238
244
|
}
|
|
239
245
|
/** `Standard` Picks property keys from the given object type */
|
|
240
|
-
Pick(
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
246
|
+
Pick(object, keys, options = {}) {
|
|
247
|
+
const source = this.Deref(object);
|
|
248
|
+
const schema = { ...clone(source), ...options };
|
|
249
|
+
schema.required = schema.required ? schema.required.filter((key) => keys.includes(key)) : undefined;
|
|
250
|
+
for (const key of Object.keys(schema.properties)) {
|
|
244
251
|
if (!keys.includes(key))
|
|
245
|
-
delete
|
|
252
|
+
delete schema.properties[key];
|
|
246
253
|
}
|
|
247
|
-
return
|
|
254
|
+
return this.Store(schema);
|
|
248
255
|
}
|
|
249
256
|
/** `Standard` Omits property keys from the given object type */
|
|
250
|
-
Omit(
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
257
|
+
Omit(object, keys, options = {}) {
|
|
258
|
+
const source = this.Deref(object);
|
|
259
|
+
const schema = { ...clone(source), ...options };
|
|
260
|
+
schema.required = schema.required ? schema.required.filter((key) => !keys.includes(key)) : undefined;
|
|
261
|
+
for (const key of Object.keys(schema.properties)) {
|
|
254
262
|
if (keys.includes(key))
|
|
255
|
-
delete
|
|
263
|
+
delete schema.properties[key];
|
|
256
264
|
}
|
|
257
|
-
return
|
|
265
|
+
return this.Store(schema);
|
|
258
266
|
}
|
|
259
267
|
/** `Standard` Omits the `kind` and `modifier` properties from the underlying schema */
|
|
260
268
|
Strict(schema, options = {}) {
|
|
@@ -262,43 +270,72 @@ class TypeBuilder {
|
|
|
262
270
|
}
|
|
263
271
|
/** `Extended` Creates a constructor type */
|
|
264
272
|
Constructor(args, returns, options = {}) {
|
|
265
|
-
return { ...options, kind: exports.ConstructorKind, type: 'constructor', arguments: args, returns };
|
|
273
|
+
return this.Store({ ...options, kind: exports.ConstructorKind, type: 'constructor', arguments: args, returns });
|
|
266
274
|
}
|
|
267
275
|
/** `Extended` Creates a function type */
|
|
268
276
|
Function(args, returns, options = {}) {
|
|
269
|
-
return { ...options, kind: exports.FunctionKind, type: 'function', arguments: args, returns };
|
|
277
|
+
return this.Store({ ...options, kind: exports.FunctionKind, type: 'function', arguments: args, returns });
|
|
270
278
|
}
|
|
271
279
|
/** `Extended` Creates a promise type */
|
|
272
280
|
Promise(item, options = {}) {
|
|
273
|
-
return { ...options, type: 'promise', kind: exports.PromiseKind, item };
|
|
281
|
+
return this.Store({ ...options, type: 'promise', kind: exports.PromiseKind, item });
|
|
274
282
|
}
|
|
275
283
|
/** `Extended` Creates a undefined type */
|
|
276
284
|
Undefined(options = {}) {
|
|
277
|
-
return { ...options, type: 'undefined', kind: exports.UndefinedKind };
|
|
285
|
+
return this.Store({ ...options, type: 'undefined', kind: exports.UndefinedKind });
|
|
278
286
|
}
|
|
279
287
|
/** `Extended` Creates a void type */
|
|
280
288
|
Void(options = {}) {
|
|
281
|
-
return { ...options, type: 'void', kind: exports.VoidKind };
|
|
289
|
+
return this.Store({ ...options, type: 'void', kind: exports.VoidKind });
|
|
290
|
+
}
|
|
291
|
+
/** `Standard` Creates a namespace for a set of related types */
|
|
292
|
+
Namespace($defs, options = {}) {
|
|
293
|
+
return this.Store({ ...options, kind: exports.BoxKind, $defs });
|
|
294
|
+
}
|
|
295
|
+
Ref(...args) {
|
|
296
|
+
if (args.length === 2) {
|
|
297
|
+
const namespace = args[0];
|
|
298
|
+
const targetKey = args[1];
|
|
299
|
+
if (namespace.$id === undefined)
|
|
300
|
+
throw new Error(`Referenced namespace has no $id`);
|
|
301
|
+
if (!this.schemas.has(namespace.$id))
|
|
302
|
+
throw new Error(`Unable to locate namespace with $id '${namespace.$id}'`);
|
|
303
|
+
return this.Store({ kind: exports.RefKind, $ref: `${namespace.$id}#/$defs/${targetKey}` });
|
|
304
|
+
}
|
|
305
|
+
else if (args.length === 1) {
|
|
306
|
+
const target = args[0];
|
|
307
|
+
if (target.$id === undefined)
|
|
308
|
+
throw new Error(`Referenced schema has no $id`);
|
|
309
|
+
if (!this.schemas.has(target.$id))
|
|
310
|
+
throw new Error(`Unable to locate schema with $id '${target.$id}'`);
|
|
311
|
+
return this.Store({ kind: exports.RefKind, $ref: target.$id });
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
throw new Error('Type.Ref: Invalid arguments');
|
|
315
|
+
}
|
|
282
316
|
}
|
|
283
317
|
/** `Experimental` Creates a recursive type */
|
|
284
318
|
Rec(callback, options = {}) {
|
|
285
319
|
const $id = options.$id || '';
|
|
286
320
|
const self = callback({ $ref: `${$id}#/$defs/self` });
|
|
287
|
-
return { ...options, $ref: `${$id}#/$defs/self`, $defs: { self } };
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const $
|
|
300
|
-
|
|
301
|
-
|
|
321
|
+
return this.Store({ ...options, $ref: `${$id}#/$defs/self`, $defs: { self } });
|
|
322
|
+
}
|
|
323
|
+
/** Conditionally stores and schema if it contains an $id and returns */
|
|
324
|
+
Store(schema) {
|
|
325
|
+
const $schema = schema;
|
|
326
|
+
if (!$schema['$id'])
|
|
327
|
+
return $schema;
|
|
328
|
+
this.schemas.set($schema['$id'], $schema);
|
|
329
|
+
return $schema;
|
|
330
|
+
}
|
|
331
|
+
/** Conditionally dereferences a schema if RefKind. Otherwise return argument */
|
|
332
|
+
Deref(schema) {
|
|
333
|
+
const $schema = schema;
|
|
334
|
+
if ($schema['kind'] !== exports.RefKind)
|
|
335
|
+
return schema;
|
|
336
|
+
if (!this.schemas.has($schema['$ref']))
|
|
337
|
+
throw Error(`Unable to locate schema with $id '${$schema['$ref']}'`);
|
|
338
|
+
return this.Deref(this.schemas.get($schema['$ref']));
|
|
302
339
|
}
|
|
303
340
|
}
|
|
304
341
|
exports.TypeBuilder = TypeBuilder;
|