@naturalcycles/js-lib 15.35.0 → 15.36.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.
@@ -1,5 +1,5 @@
1
1
  import type { AnyObject, StringMap } from '../types.js';
2
- export type JsonSchema<T = unknown> = JsonSchemaAny<T> | JsonSchemaOneOf<T> | JsonSchemaAllOf<T> | JsonSchemaAnyOf<T> | JsonSchemaNot<T> | JsonSchemaRef<T> | JsonSchemaConst<T> | JsonSchemaEnum<T> | JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaNull | JsonSchemaObject | JsonSchemaArray<T> | JsonSchemaTuple<T>;
2
+ export type JsonSchema<T = unknown> = JsonSchemaAny<T> | JsonSchemaOneOf<T> | JsonSchemaAllOf<T> | JsonSchemaAnyOf<T> | JsonSchemaNot<T> | JsonSchemaRef<T> | JsonSchemaConst<T> | JsonSchemaEnum<T> | JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaNull | JsonSchemaObject<T extends AnyObject ? T : AnyObject> | JsonSchemaArray<T> | JsonSchemaTuple<T>;
3
3
  export interface JsonSchemaAny<T = unknown> {
4
4
  $schema?: string;
5
5
  $id?: string;
@@ -8,7 +8,7 @@ export interface JsonSchemaAny<T = unknown> {
8
8
  deprecated?: boolean;
9
9
  readOnly?: boolean;
10
10
  writeOnly?: boolean;
11
- type?: string;
11
+ type?: string | string[];
12
12
  default?: T;
13
13
  if?: JsonSchema;
14
14
  then?: JsonSchema;
@@ -8,36 +8,36 @@ export interface JsonSchemaBuilder<T = unknown> {
8
8
  * Inspired by Joi and Zod.
9
9
  */
10
10
  export declare const j: {
11
- any<T = unknown>(): JsonSchemaAnyBuilder<T, JsonSchemaAny<T>>;
12
- const<T = unknown>(value: T): JsonSchemaAnyBuilder<T, JsonSchemaConst<T>>;
13
- null(): JsonSchemaAnyBuilder<null, JsonSchemaNull>;
14
- ref<T = unknown>($ref: string): JsonSchemaAnyBuilder<T, JsonSchemaRef<T>>;
15
- enum<T = unknown>(enumValues: T[]): JsonSchemaAnyBuilder<T, JsonSchemaEnum<T>>;
16
- boolean(): JsonSchemaAnyBuilder<boolean, JsonSchemaBoolean>;
17
- buffer(): JsonSchemaAnyBuilder<Buffer<ArrayBufferLike>, JsonSchemaAny<Buffer<ArrayBufferLike>>>;
18
- number<T extends number = number>(): JsonSchemaNumberBuilder<T>;
19
- integer<T extends number = number>(): JsonSchemaNumberBuilder<T>;
20
- unixTimestamp(): JsonSchemaNumberBuilder<UnixTimestamp>;
21
- unixTimestamp2000(): JsonSchemaNumberBuilder<UnixTimestamp>;
22
- string<T extends string = string>(): JsonSchemaStringBuilder<T>;
11
+ any<T = unknown>(): JsonSchemaAnyBuilder<T, JsonSchemaAny<T>, false>;
12
+ const<T = unknown>(value: T): JsonSchemaAnyBuilder<T, JsonSchemaConst<T>, false>;
13
+ null(): JsonSchemaAnyBuilder<null, JsonSchemaNull, false>;
14
+ ref<T = unknown>($ref: string): JsonSchemaAnyBuilder<T, JsonSchemaRef<T>, false>;
15
+ enum<T = unknown>(enumValues: T[]): JsonSchemaAnyBuilder<T, JsonSchemaEnum<T>, false>;
16
+ boolean(): JsonSchemaAnyBuilder<boolean, JsonSchemaBoolean, false>;
17
+ buffer(): JsonSchemaAnyBuilder<Buffer<ArrayBufferLike>, JsonSchemaAny<Buffer<ArrayBufferLike>>, false>;
18
+ number<T extends number = number>(): JsonSchemaNumberBuilder<T, false>;
19
+ integer<T extends number = number>(): JsonSchemaNumberBuilder<T, false>;
20
+ unixTimestamp(): JsonSchemaNumberBuilder<UnixTimestamp, false>;
21
+ unixTimestamp2000(): JsonSchemaNumberBuilder<UnixTimestamp, false>;
22
+ string<T extends string = string>(): JsonSchemaStringBuilder<T, false>;
23
23
  /**
24
24
  * Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
25
25
  */
26
- isoDate(): JsonSchemaStringBuilder<IsoDate>;
26
+ isoDate(): JsonSchemaStringBuilder<IsoDate, false>;
27
27
  /**
28
28
  * Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
29
29
  * and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
30
30
  */
31
- isoDateTime(): JsonSchemaStringBuilder<IsoDateTime>;
31
+ isoDateTime(): JsonSchemaStringBuilder<IsoDateTime, false>;
32
32
  object: typeof object;
33
- dbEntity<T extends AnyObject>(props: T): JsonSchemaObjectBuilder<BaseDBEntity & { [K in keyof T]: T[K] extends JsonSchemaAnyBuilder<infer U, any> ? U : never; }>;
34
- rootObject<T extends AnyObject>(props: { [K in keyof T]: JsonSchemaAnyBuilder<T[K]>; }): JsonSchemaObjectBuilder<T>;
35
- array<T extends JsonSchemaAnyBuilder<any>>(itemSchema: T): JsonSchemaArrayBuilder<T["infer"]>;
33
+ dbEntity<T extends AnyObject>(props: T): JsonSchemaObjectBuilder<BaseDBEntity & ({ [K in keyof T as T[K] extends JsonSchemaAnyBuilder<any, any, infer Opt extends boolean> ? Opt extends true ? never : K : never]: T[K] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never; } & { [K_1 in keyof T as T[K_1] extends JsonSchemaAnyBuilder<any, any, infer Opt extends boolean> ? Opt extends true ? K_1 : never : never]?: (T[K_1] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never) | undefined; } extends infer O ? { [K_2 in keyof O]: O[K_2]; } : never) extends infer O_1 ? { [K_3 in keyof O_1]: O_1[K_3]; } : never, false>;
34
+ rootObject<T extends AnyObject>(props: { [K in keyof T]: JsonSchemaAnyBuilder<T[K]>; }): JsonSchemaObjectBuilder<T, false>;
35
+ array<T extends JsonSchemaAnyBuilder<any>>(itemSchema: T): JsonSchemaArrayBuilder<T["infer"], false>;
36
36
  tuple<T extends any[] = unknown[]>(items: JsonSchemaAnyBuilder[]): JsonSchemaTupleBuilder<T>;
37
- oneOf<T = unknown>(items: JsonSchemaAnyBuilder[]): JsonSchemaAnyBuilder<T, JsonSchemaOneOf<T>>;
38
- allOf<T = unknown>(items: JsonSchemaAnyBuilder[]): JsonSchemaAnyBuilder<T, JsonSchemaAllOf<T>>;
37
+ oneOf<Builders extends JsonSchemaAnyBuilder<any, any, any>[]>(items: [...Builders]): JsonSchemaAnyBuilder<Builders[number] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never, JsonSchemaOneOf<Builders[number] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never>>;
38
+ allOf<T = unknown>(items: JsonSchemaAnyBuilder[]): JsonSchemaAnyBuilder<T, JsonSchemaAllOf<T>, false>;
39
39
  };
40
- export declare class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T> = JsonSchema<T>> implements JsonSchemaBuilder<T> {
40
+ export declare class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T> = JsonSchema<T>, Opt extends boolean = false> implements JsonSchemaBuilder<T> {
41
41
  protected schema: SCHEMA_TYPE;
42
42
  constructor(schema: SCHEMA_TYPE);
43
43
  /**
@@ -52,24 +52,23 @@ export declare class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonS
52
52
  deprecated(deprecated?: boolean): this;
53
53
  type(type: string): this;
54
54
  default(v: any): this;
55
- oneOf(schemas: JsonSchema[]): this;
56
- allOf(schemas: JsonSchema[]): this;
57
55
  instanceof(of: string): this;
58
- optional(): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>;
59
- optional(optional: true): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>;
60
- optional(optional: false): JsonSchemaAnyBuilder<Exclude<T, undefined>, JsonSchema<Exclude<T, undefined>>>;
56
+ optional(): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>, true>;
57
+ optional(optional: true): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>, true>;
58
+ optional(optional: false): JsonSchemaAnyBuilder<Exclude<T, undefined>, JsonSchema<Exclude<T, undefined>>, false>;
59
+ nullable(): JsonSchemaAnyBuilder<T | null, JsonSchema<T | null>, Opt>;
61
60
  /**
62
61
  * Produces a "clean schema object" without methods.
63
62
  * Same as if it would be JSON.stringified.
64
63
  */
65
64
  build(): SCHEMA_TYPE;
66
- clone(): JsonSchemaAnyBuilder<T, SCHEMA_TYPE>;
65
+ clone(): JsonSchemaAnyBuilder<T, SCHEMA_TYPE, Opt>;
67
66
  /**
68
67
  * @experimental
69
68
  */
70
69
  infer: T;
71
70
  }
72
- export declare class JsonSchemaNumberBuilder<T extends number = number> extends JsonSchemaAnyBuilder<T, JsonSchemaNumber<T>> {
71
+ export declare class JsonSchemaNumberBuilder<T extends number = number, Opt extends boolean = false> extends JsonSchemaAnyBuilder<T, JsonSchemaNumber<T>, Opt> {
73
72
  constructor();
74
73
  integer(): this;
75
74
  multipleOf(multipleOf: number): this;
@@ -94,7 +93,7 @@ export declare class JsonSchemaNumberBuilder<T extends number = number> extends
94
93
  utcOffsetHours: () => this;
95
94
  branded<B extends number>(): JsonSchemaNumberBuilder<B>;
96
95
  }
97
- export declare class JsonSchemaStringBuilder<T extends string = string> extends JsonSchemaAnyBuilder<T, JsonSchemaString<T>> {
96
+ export declare class JsonSchemaStringBuilder<T extends string = string, Opt extends boolean = false> extends JsonSchemaAnyBuilder<T, JsonSchemaString<T>, Opt> {
98
97
  constructor();
99
98
  regex(pattern: RegExp): this;
100
99
  pattern(pattern: string): this;
@@ -128,7 +127,7 @@ export declare class JsonSchemaStringBuilder<T extends string = string> extends
128
127
  isoDateTime(): JsonSchemaStringBuilder<IsoDateTime>;
129
128
  private transformModify;
130
129
  }
131
- export declare class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyBuilder<T, JsonSchemaObject<T>> {
130
+ export declare class JsonSchemaObjectBuilder<T extends AnyObject, Opt extends boolean = false> extends JsonSchemaAnyBuilder<T, JsonSchemaObject<T>, Opt> {
132
131
  constructor();
133
132
  addProperties(props: {
134
133
  [k in keyof T]: JsonSchemaBuilder<T[k]>;
@@ -142,9 +141,11 @@ export declare class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSc
142
141
  maxProps(maxProperties: number): this;
143
142
  additionalProps(additionalProperties: boolean): this;
144
143
  baseDBEntity(): JsonSchemaObjectBuilder<T & BaseDBEntity>;
145
- extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2>;
144
+ extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2 extends infer O ? {
145
+ [K in keyof O]: O[K];
146
+ } : never>;
146
147
  }
147
- export declare class JsonSchemaArrayBuilder<ITEM> extends JsonSchemaAnyBuilder<ITEM[], JsonSchemaArray<ITEM>> {
148
+ export declare class JsonSchemaArrayBuilder<ITEM, Opt extends boolean = false> extends JsonSchemaAnyBuilder<ITEM[], JsonSchemaArray<ITEM>, Opt> {
148
149
  constructor(itemsSchema: JsonSchemaBuilder<ITEM>);
149
150
  min(minItems: number): this;
150
151
  max(maxItems: number): this;
@@ -153,9 +154,13 @@ export declare class JsonSchemaArrayBuilder<ITEM> extends JsonSchemaAnyBuilder<I
153
154
  export declare class JsonSchemaTupleBuilder<T extends any[]> extends JsonSchemaAnyBuilder<T, JsonSchemaTuple<T>> {
154
155
  constructor(items: JsonSchemaBuilder[]);
155
156
  }
156
- declare function object<P extends Record<string, JsonSchemaAnyBuilder<any, any>>>(props: P): JsonSchemaObjectBuilder<{
157
- [K in keyof P]: P[K] extends JsonSchemaAnyBuilder<infer U, any> ? U : never;
158
- }>;
157
+ declare function object<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(props: P): JsonSchemaObjectBuilder<{
158
+ [K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer Opt> ? Opt extends true ? never : K : never]: P[K] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never;
159
+ } & {
160
+ [K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer Opt> ? Opt extends true ? K : never : never]?: P[K] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never;
161
+ } extends infer O ? {
162
+ [K in keyof O]: O[K];
163
+ } : never>;
159
164
  declare function object<T extends AnyObject>(props: {
160
165
  [K in keyof T]: JsonSchemaAnyBuilder<T[K]>;
161
166
  }): JsonSchemaObjectBuilder<T>;
@@ -144,14 +144,6 @@ export class JsonSchemaAnyBuilder {
144
144
  Object.assign(this.schema, { default: v });
145
145
  return this;
146
146
  }
147
- oneOf(schemas) {
148
- Object.assign(this.schema, { oneOf: schemas });
149
- return this;
150
- }
151
- allOf(schemas) {
152
- Object.assign(this.schema, { allOf: schemas });
153
- return this;
154
- }
155
147
  instanceof(of) {
156
148
  this.schema.instanceof = of;
157
149
  return this;
@@ -165,6 +157,11 @@ export class JsonSchemaAnyBuilder {
165
157
  }
166
158
  return this;
167
159
  }
160
+ nullable() {
161
+ return new JsonSchemaAnyBuilder({
162
+ anyOf: [this.build(), { type: 'null' }],
163
+ });
164
+ }
168
165
  /**
169
166
  * Produces a "clean schema object" without methods.
170
167
  * Same as if it would be JSON.stringified.
@@ -1,2 +1,2 @@
1
1
  import type { BaseDBEntity } from '../types.js';
2
- export declare const baseDBEntityJsonSchema: import("./jsonSchemaBuilder.js").JsonSchemaObjectBuilder<BaseDBEntity>;
2
+ export declare const baseDBEntityJsonSchema: import("./jsonSchemaBuilder.js").JsonSchemaObjectBuilder<BaseDBEntity, false>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.35.0",
4
+ "version": "15.36.0",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "undici": "^7",
@@ -13,7 +13,7 @@ export type JsonSchema<T = unknown> =
13
13
  | JsonSchemaNumber
14
14
  | JsonSchemaBoolean
15
15
  | JsonSchemaNull
16
- | JsonSchemaObject // cannot use <T>, because T needs to extend AnyObject
16
+ | JsonSchemaObject<T extends AnyObject ? T : AnyObject>
17
17
  | JsonSchemaArray<T>
18
18
  | JsonSchemaTuple<T>
19
19
 
@@ -28,7 +28,7 @@ export interface JsonSchemaAny<T = unknown> {
28
28
  readOnly?: boolean
29
29
  writeOnly?: boolean
30
30
 
31
- type?: string
31
+ type?: string | string[]
32
32
 
33
33
  default?: T
34
34
 
@@ -122,10 +122,15 @@ export const j = {
122
122
  tuple<T extends any[] = unknown[]>(items: JsonSchemaAnyBuilder[]) {
123
123
  return new JsonSchemaTupleBuilder<T>(items)
124
124
  },
125
- oneOf<T = unknown>(items: JsonSchemaAnyBuilder[]) {
126
- return new JsonSchemaAnyBuilder<T, JsonSchemaOneOf<T>>({
125
+ oneOf<Builders extends JsonSchemaAnyBuilder<any, any, any>[]>(
126
+ items: [...Builders],
127
+ ): JsonSchemaAnyBuilder<
128
+ Builders[number] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never,
129
+ JsonSchemaOneOf<Builders[number] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never>
130
+ > {
131
+ return new JsonSchemaAnyBuilder({
127
132
  oneOf: items.map(b => b.build()),
128
- })
133
+ }) as any
129
134
  },
130
135
  allOf<T = unknown>(items: JsonSchemaAnyBuilder[]) {
131
136
  return new JsonSchemaAnyBuilder<T, JsonSchemaAllOf<T>>({
@@ -134,8 +139,11 @@ export const j = {
134
139
  },
135
140
  }
136
141
 
137
- export class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T> = JsonSchema<T>>
138
- implements JsonSchemaBuilder<T>
142
+ export class JsonSchemaAnyBuilder<
143
+ T = unknown,
144
+ SCHEMA_TYPE extends JsonSchema<T> = JsonSchema<T>,
145
+ Opt extends boolean = false,
146
+ > implements JsonSchemaBuilder<T>
139
147
  {
140
148
  constructor(protected schema: SCHEMA_TYPE) {}
141
149
 
@@ -186,27 +194,17 @@ export class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T>
186
194
  return this
187
195
  }
188
196
 
189
- oneOf(schemas: JsonSchema[]): this {
190
- Object.assign(this.schema, { oneOf: schemas })
191
- return this
192
- }
193
-
194
- allOf(schemas: JsonSchema[]): this {
195
- Object.assign(this.schema, { allOf: schemas })
196
- return this
197
- }
198
-
199
197
  instanceof(of: string): this {
200
198
  this.schema.instanceof = of
201
199
  return this
202
200
  }
203
201
 
204
- optional(): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>
205
- optional(optional: true): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>>
202
+ optional(): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>, true>
203
+ optional(optional: true): JsonSchemaAnyBuilder<T | undefined, JsonSchema<T | undefined>, true>
206
204
  optional(
207
205
  optional: false,
208
- ): JsonSchemaAnyBuilder<Exclude<T, undefined>, JsonSchema<Exclude<T, undefined>>>
209
- optional(optional = true): JsonSchemaAnyBuilder<any, JsonSchema<any>> {
206
+ ): JsonSchemaAnyBuilder<Exclude<T, undefined>, JsonSchema<Exclude<T, undefined>>, false>
207
+ optional(optional = true): JsonSchemaAnyBuilder<any, JsonSchema<any>, false> {
210
208
  if (optional) {
211
209
  this.schema.optionalField = true
212
210
  } else {
@@ -215,6 +213,12 @@ export class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T>
215
213
  return this
216
214
  }
217
215
 
216
+ nullable(): JsonSchemaAnyBuilder<T | null, JsonSchema<T | null>, Opt> {
217
+ return new JsonSchemaAnyBuilder<T | null, JsonSchema<T | null>, Opt>({
218
+ anyOf: [this.build(), { type: 'null' }],
219
+ })
220
+ }
221
+
218
222
  /**
219
223
  * Produces a "clean schema object" without methods.
220
224
  * Same as if it would be JSON.stringified.
@@ -223,8 +227,8 @@ export class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T>
223
227
  return _sortObject(JSON.parse(JSON.stringify(this.schema)), JSON_SCHEMA_ORDER)
224
228
  }
225
229
 
226
- clone(): JsonSchemaAnyBuilder<T, SCHEMA_TYPE> {
227
- return new JsonSchemaAnyBuilder<T, SCHEMA_TYPE>(_deepCopy(this.schema))
230
+ clone(): JsonSchemaAnyBuilder<T, SCHEMA_TYPE, Opt> {
231
+ return new JsonSchemaAnyBuilder<T, SCHEMA_TYPE, Opt>(_deepCopy(this.schema))
228
232
  }
229
233
 
230
234
  /**
@@ -233,10 +237,10 @@ export class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T>
233
237
  infer!: T
234
238
  }
235
239
 
236
- export class JsonSchemaNumberBuilder<T extends number = number> extends JsonSchemaAnyBuilder<
237
- T,
238
- JsonSchemaNumber<T>
239
- > {
240
+ export class JsonSchemaNumberBuilder<
241
+ T extends number = number,
242
+ Opt extends boolean = false,
243
+ > extends JsonSchemaAnyBuilder<T, JsonSchemaNumber<T>, Opt> {
240
244
  constructor() {
241
245
  super({
242
246
  type: 'number',
@@ -306,10 +310,10 @@ export class JsonSchemaNumberBuilder<T extends number = number> extends JsonSche
306
310
  }
307
311
  }
308
312
 
309
- export class JsonSchemaStringBuilder<T extends string = string> extends JsonSchemaAnyBuilder<
310
- T,
311
- JsonSchemaString<T>
312
- > {
313
+ export class JsonSchemaStringBuilder<
314
+ T extends string = string,
315
+ Opt extends boolean = false,
316
+ > extends JsonSchemaAnyBuilder<T, JsonSchemaString<T>, Opt> {
313
317
  constructor() {
314
318
  super({
315
319
  type: 'string',
@@ -393,10 +397,10 @@ export class JsonSchemaStringBuilder<T extends string = string> extends JsonSche
393
397
  // contentEncoding?: string
394
398
  }
395
399
 
396
- export class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyBuilder<
397
- T,
398
- JsonSchemaObject<T>
399
- > {
400
+ export class JsonSchemaObjectBuilder<
401
+ T extends AnyObject,
402
+ Opt extends boolean = false,
403
+ > extends JsonSchemaAnyBuilder<T, JsonSchemaObject<T>, Opt> {
400
404
  constructor() {
401
405
  super({
402
406
  type: 'object',
@@ -460,17 +464,20 @@ export class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyB
460
464
  return this.addRequired(['id', 'created', 'updated']) as any
461
465
  }
462
466
 
463
- extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2> {
464
- const builder = new JsonSchemaObjectBuilder<T & T2>()
467
+ extend<T2 extends AnyObject>(
468
+ s2: JsonSchemaObjectBuilder<T2>,
469
+ ): JsonSchemaObjectBuilder<T & T2 extends infer O ? { [K in keyof O]: O[K] } : never> {
470
+ const builder = new JsonSchemaObjectBuilder<any>()
465
471
  Object.assign(builder.schema, _deepCopy(this.schema))
466
472
  mergeJsonSchemaObjects(builder.schema, s2.schema)
467
473
  return builder
468
474
  }
469
475
  }
470
476
 
471
- export class JsonSchemaArrayBuilder<ITEM> extends JsonSchemaAnyBuilder<
477
+ export class JsonSchemaArrayBuilder<ITEM, Opt extends boolean = false> extends JsonSchemaAnyBuilder<
472
478
  ITEM[],
473
- JsonSchemaArray<ITEM>
479
+ JsonSchemaArray<ITEM>,
480
+ Opt
474
481
  > {
475
482
  constructor(itemsSchema: JsonSchemaBuilder<ITEM>) {
476
483
  super({
@@ -509,16 +516,25 @@ export class JsonSchemaTupleBuilder<T extends any[]> extends JsonSchemaAnyBuilde
509
516
  }
510
517
  }
511
518
 
512
- // TODO and Notes
513
- // The issue is that in `j` we mix two approaches:
514
- // 1) the builder driven approach
515
- // 2) the type driven approach.
516
-
517
- function object<P extends Record<string, JsonSchemaAnyBuilder<any, any>>>(
519
+ function object<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(
518
520
  props: P,
519
- ): JsonSchemaObjectBuilder<{
520
- [K in keyof P]: P[K] extends JsonSchemaAnyBuilder<infer U, any> ? U : never
521
- }>
521
+ ): JsonSchemaObjectBuilder<
522
+ {
523
+ [K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer Opt>
524
+ ? Opt extends true
525
+ ? never
526
+ : K
527
+ : never]: P[K] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never
528
+ } & {
529
+ [K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer Opt>
530
+ ? Opt extends true
531
+ ? K
532
+ : never
533
+ : never]?: P[K] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never
534
+ } extends infer O
535
+ ? { [K in keyof O]: O[K] }
536
+ : never
537
+ >
522
538
  function object<T extends AnyObject>(props: {
523
539
  [K in keyof T]: JsonSchemaAnyBuilder<T[K]>
524
540
  }): JsonSchemaObjectBuilder<T>