@sinclair/typebox 0.22.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 +1 -1
- package/typebox.d.ts +25 -12
- package/typebox.js +98 -64
package/package.json
CHANGED
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;
|
|
@@ -174,6 +175,11 @@ export interface TAny extends TSchema, CustomOptions {
|
|
|
174
175
|
$static: any;
|
|
175
176
|
kind: typeof AnyKind;
|
|
176
177
|
}
|
|
178
|
+
export interface TRef<T extends TSchema> extends TSchema, CustomOptions {
|
|
179
|
+
$static: Static<T>;
|
|
180
|
+
kind: typeof RefKind;
|
|
181
|
+
$ref: string;
|
|
182
|
+
}
|
|
177
183
|
export declare const ConstructorKind: unique symbol;
|
|
178
184
|
export declare const FunctionKind: unique symbol;
|
|
179
185
|
export declare const PromiseKind: unique symbol;
|
|
@@ -209,6 +215,9 @@ export interface TVoid extends TSchema, CustomOptions {
|
|
|
209
215
|
kind: typeof VoidKind;
|
|
210
216
|
type: 'void';
|
|
211
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;
|
|
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;
|
|
@@ -262,6 +271,7 @@ export declare type StaticFunction<T extends readonly TSchema[], U extends TSche
|
|
|
262
271
|
export declare type StaticPromise<T extends TSchema> = Promise<Static<T>>;
|
|
263
272
|
export declare type Static<T extends TSchema> = T['$static'];
|
|
264
273
|
export declare class TypeBuilder {
|
|
274
|
+
private readonly schemas;
|
|
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 */
|
|
@@ -299,17 +309,17 @@ export declare class TypeBuilder {
|
|
|
299
309
|
/** `Standard` Creates an any type */
|
|
300
310
|
Any(options?: CustomOptions): TAny;
|
|
301
311
|
/** `Standard` Creates a keyof type from the given object */
|
|
302
|
-
KeyOf<T extends TObject<TProperties>>(
|
|
312
|
+
KeyOf<T extends TObject<TProperties>>(object: T, options?: CustomOptions): TKeyOf<(keyof T['properties'])[]>;
|
|
303
313
|
/** `Standard` Creates a record type */
|
|
304
314
|
Record<K extends TRecordKey, T extends TSchema>(key: K, value: T, options?: ObjectOptions): TRecord<K, 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 PickablePropertyKeys<T>[]>(object: T, keys: [...K], options?: ObjectOptions): TObject<Pick<PickableProperties<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 PickablePropertyKeys<T>[]>(object: T, keys: [...K], options?: ObjectOptions): TObject<Omit<PickableProperties<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']>(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>;
|
|
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
|
+
/** 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;
|
|
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,32 @@ 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 };
|
|
176
|
+
return this.Store({ ...options, kind: exports.AnyKind });
|
|
174
177
|
}
|
|
175
178
|
/** `Standard` Creates a keyof type from the given object */
|
|
176
|
-
KeyOf(
|
|
177
|
-
const keys = Object.keys(
|
|
178
|
-
return { ...options, kind: exports.KeyOfKind, type: 'string', enum: keys };
|
|
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 = {}) {
|
|
@@ -188,14 +191,15 @@ class TypeBuilder {
|
|
|
188
191
|
default: throw Error('Invalid Record Key');
|
|
189
192
|
}
|
|
190
193
|
})();
|
|
191
|
-
return { ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } };
|
|
194
|
+
return this.Store({ ...options, kind: exports.RecordKind, type: 'object', patternProperties: { [pattern]: value } });
|
|
192
195
|
}
|
|
193
196
|
/** `Standard` Makes all properties in the given object type required */
|
|
194
|
-
Required(
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
|
218
|
+
return this.Store(schema);
|
|
215
219
|
}
|
|
216
220
|
/** `Standard` Makes all properties in the given object type optional */
|
|
217
|
-
Partial(
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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,27 +239,29 @@ class TypeBuilder {
|
|
|
234
239
|
break;
|
|
235
240
|
}
|
|
236
241
|
}
|
|
237
|
-
return
|
|
242
|
+
return this.Store(schema);
|
|
238
243
|
}
|
|
239
244
|
/** `Standard` Picks property keys from the given object type */
|
|
240
|
-
Pick(
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
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
|
|
253
|
+
return this.Store(schema);
|
|
248
254
|
}
|
|
249
255
|
/** `Standard` Omits property keys from the given object type */
|
|
250
|
-
Omit(
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
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 = {}) {
|
|
@@ -262,43 +269,70 @@ class TypeBuilder {
|
|
|
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 });
|
|
289
|
+
}
|
|
290
|
+
/** `Standard` Creates a namespace for a set of related types */
|
|
291
|
+
Namespace($defs, options = {}) {
|
|
292
|
+
return this.Store({ ...options, kind: exports.BoxKind, $defs });
|
|
293
|
+
}
|
|
294
|
+
Ref(...args) {
|
|
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
|
+
}
|
|
282
315
|
}
|
|
283
316
|
/** `Experimental` Creates a recursive type */
|
|
284
317
|
Rec(callback, options = {}) {
|
|
285
318
|
const $id = options.$id || '';
|
|
286
319
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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;
|