@naturalcycles/nodejs-lib 15.96.1 → 15.97.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.
@@ -184,7 +184,18 @@ export declare class JBuilder<OUT, Opt> extends JSchema<OUT, Opt> {
184
184
  type(type: string): this;
185
185
  default(v: any): this;
186
186
  instanceof(of: string): this;
187
- optional(): JBuilder<OUT | undefined, true>;
187
+ /**
188
+ * @param optionalValues List of values that should be considered/converted as `undefined`.
189
+ *
190
+ * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
191
+ * due to how mutability works in Ajv.
192
+ *
193
+ * Make sure this `optional()` call is at the end of your call chain.
194
+ *
195
+ * When `null` is included in optionalValues, the return type becomes `JSchema`
196
+ * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
197
+ */
198
+ optional<T extends readonly (string | number | boolean | null)[] | undefined = undefined>(optionalValues?: T): T extends readonly (string | number | boolean | null)[] ? JSchema<OUT | undefined, true> : JBuilder<OUT | undefined, true>;
188
199
  nullable(): JBuilder<OUT | null, Opt>;
189
200
  /**
190
201
  * @deprecated
@@ -216,18 +227,6 @@ export declare class JBuilder<OUT, Opt> extends JSchema<OUT, Opt> {
216
227
  }
217
228
  export declare class JString<OUT extends string | undefined = string, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
218
229
  constructor();
219
- /**
220
- * @param optionalValues List of values that should be considered/converted as `undefined`.
221
- *
222
- * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
223
- * due to how mutability works in Ajv.
224
- *
225
- * Make sure this `optional()` call is at the end of your call chain.
226
- *
227
- * When `null` is included in optionalValues, the return type becomes `JSchema`
228
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
229
- */
230
- optional<T extends readonly (string | null)[] | undefined = undefined>(optionalValues?: T): T extends readonly (infer U)[] ? null extends U ? JSchema<OUT | undefined, true> : JString<OUT | undefined, true> : JString<OUT | undefined, true>;
231
230
  regex(pattern: RegExp, opt?: JsonBuilderRuleOpt): this;
232
231
  pattern(pattern: string, opt?: JsonBuilderRuleOpt): this;
233
232
  minLength(minLength: number): this;
@@ -277,16 +276,6 @@ export interface JsonSchemaStringEmailOptions {
277
276
  }
278
277
  export declare class JIsoDate<Opt extends boolean = false> extends JBuilder<IsoDate, Opt> {
279
278
  constructor();
280
- /**
281
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
282
- *
283
- * This `null` feature only works when the current schema is nested in an object or array schema,
284
- * due to how mutability works in Ajv.
285
- *
286
- * When `null` is passed, the return type becomes `JSchema`
287
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
288
- */
289
- optional<N extends null | undefined = undefined>(nullValue?: N): N extends null ? JSchema<IsoDate | undefined, true> : JBuilder<IsoDate | undefined, true>;
290
279
  before(date: string): this;
291
280
  sameOrBefore(date: string): this;
292
281
  after(date: string): this;
@@ -303,18 +292,6 @@ export interface JsonSchemaIsoMonthOptions {
303
292
  }
304
293
  export declare class JNumber<OUT extends number | undefined = number, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
305
294
  constructor();
306
- /**
307
- * @param optionalValues List of values that should be considered/converted as `undefined`.
308
- *
309
- * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
310
- * due to how mutability works in Ajv.
311
- *
312
- * Make sure this `optional()` call is at the end of your call chain.
313
- *
314
- * When `null` is included in optionalValues, the return type becomes `JSchema`
315
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
316
- */
317
- optional<T extends readonly (number | null)[] | undefined = undefined>(optionalValues?: T): T extends readonly (infer U)[] ? null extends U ? JSchema<OUT | undefined, true> : JNumber<OUT | undefined, true> : JNumber<OUT | undefined, true>;
318
295
  integer(): this;
319
296
  branded<B extends number>(): JNumber<B, Opt>;
320
297
  multipleOf(multipleOf: number): this;
@@ -347,26 +324,9 @@ export declare class JNumber<OUT extends number | undefined = number, Opt extend
347
324
  }
348
325
  export declare class JBoolean<OUT extends boolean | undefined = boolean, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
349
326
  constructor();
350
- /**
351
- * @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
352
- *
353
- * This `optionalValue` feature only works when the current schema is nested in an object or array schema,
354
- * due to how mutability works in Ajv.
355
- */
356
- optional(optionalValue?: boolean): JBoolean<OUT | undefined, true>;
357
327
  }
358
328
  export declare class JObject<OUT extends AnyObject, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
359
329
  constructor(props?: AnyObject, opt?: JObjectOpts);
360
- /**
361
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
362
- *
363
- * This `null` feature only works when the current schema is nested in an object or array schema,
364
- * due to how mutability works in Ajv.
365
- *
366
- * When `null` is passed, the return type becomes `JSchema`
367
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
368
- */
369
- optional<N extends null | undefined = undefined>(nullValue?: N): N extends null ? JSchema<OUT | undefined, true> : JBuilder<OUT | undefined, true>;
370
330
  /**
371
331
  * When set, the validation will not strip away properties that are not specified explicitly in the schema.
372
332
  */
@@ -407,24 +367,6 @@ export declare class JObjectInfer<PROPS extends Record<string, JBuilder<any, any
407
367
  [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt> ? IsOpt extends true ? K : never : never]?: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never;
408
368
  }>, Opt> {
409
369
  constructor(props?: PROPS);
410
- /**
411
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
412
- *
413
- * This `null` feature only works when the current schema is nested in an object or array schema,
414
- * due to how mutability works in Ajv.
415
- *
416
- * When `null` is passed, the return type becomes `JSchema`
417
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
418
- */
419
- optional<N extends null | undefined = undefined>(nullValue?: N): N extends null ? JSchema<Expand<{
420
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt> ? IsOpt extends true ? never : K : never]: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never;
421
- } & {
422
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt> ? IsOpt extends true ? K : never : never]?: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never;
423
- }> | undefined, true> : JBuilder<Expand<{
424
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt> ? IsOpt extends true ? never : K : never]: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never;
425
- } & {
426
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt> ? IsOpt extends true ? K : never : never]?: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never;
427
- }> | undefined, true>;
428
370
  /**
429
371
  * When set, the validation will not strip away properties that are not specified explicitly in the schema.
430
372
  */
@@ -405,9 +405,58 @@ export class JBuilder extends JSchema {
405
405
  instanceof(of) {
406
406
  return this.cloneAndUpdateSchema({ type: 'object', instanceof: of });
407
407
  }
408
- optional() {
409
- const clone = this.cloneAndUpdateSchema({ optionalField: true });
410
- return clone;
408
+ /**
409
+ * @param optionalValues List of values that should be considered/converted as `undefined`.
410
+ *
411
+ * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
412
+ * due to how mutability works in Ajv.
413
+ *
414
+ * Make sure this `optional()` call is at the end of your call chain.
415
+ *
416
+ * When `null` is included in optionalValues, the return type becomes `JSchema`
417
+ * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
418
+ */
419
+ optional(optionalValues) {
420
+ if (!optionalValues?.length) {
421
+ const clone = this.cloneAndUpdateSchema({ optionalField: true });
422
+ return clone;
423
+ }
424
+ const builtSchema = this.build();
425
+ // When optionalValues is just [null], use a simple null-wrapping structure.
426
+ // If the schema already has anyOf with a null branch (from nullable()),
427
+ // inject optionalValues directly into it.
428
+ if (optionalValues.length === 1 && optionalValues[0] === null) {
429
+ if (builtSchema.anyOf) {
430
+ const nullBranch = builtSchema.anyOf.find(b => b.type === 'null');
431
+ if (nullBranch) {
432
+ nullBranch.optionalValues = [null];
433
+ return new JSchema({ ...builtSchema, optionalField: true });
434
+ }
435
+ }
436
+ // Wrap with null type branch
437
+ return new JSchema({
438
+ anyOf: [{ type: 'null', optionalValues: [null] }, builtSchema],
439
+ optionalField: true,
440
+ });
441
+ }
442
+ // General case: create anyOf with current schema + alternatives.
443
+ // Preserve the original type for Ajv strict mode (optionalValues keyword requires a type).
444
+ const alternativesSchema = j.enum(optionalValues).build();
445
+ const innerSchema = {
446
+ ...(builtSchema.type ? { type: builtSchema.type } : {}),
447
+ anyOf: [builtSchema, alternativesSchema],
448
+ optionalValues: [...optionalValues],
449
+ };
450
+ // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
451
+ // so we must allow `null` values to be parsed by Ajv,
452
+ // but the typing should not reflect that.
453
+ if (optionalValues.includes(null)) {
454
+ return new JSchema({
455
+ anyOf: [{ type: 'null', optionalValues: [...optionalValues] }, innerSchema],
456
+ optionalField: true,
457
+ });
458
+ }
459
+ return new JSchema({ ...innerSchema, optionalField: true });
411
460
  }
412
461
  nullable() {
413
462
  return new JBuilder({
@@ -468,40 +517,6 @@ export class JString extends JBuilder {
468
517
  type: 'string',
469
518
  });
470
519
  }
471
- /**
472
- * @param optionalValues List of values that should be considered/converted as `undefined`.
473
- *
474
- * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
475
- * due to how mutability works in Ajv.
476
- *
477
- * Make sure this `optional()` call is at the end of your call chain.
478
- *
479
- * When `null` is included in optionalValues, the return type becomes `JSchema`
480
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
481
- */
482
- optional(optionalValues) {
483
- if (!optionalValues) {
484
- return super.optional();
485
- }
486
- _typeCast(optionalValues);
487
- let newBuilder = new JString().optional();
488
- const alternativesSchema = j.enum(optionalValues);
489
- Object.assign(newBuilder.getSchema(), {
490
- anyOf: [this.build(), alternativesSchema.build()],
491
- optionalValues,
492
- });
493
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
494
- // so we must allow `null` values to be parsed by Ajv,
495
- // but the typing should not reflect that.
496
- // We also cannot accept more rules attached, since we're not building a StringSchema anymore.
497
- if (optionalValues.includes(null)) {
498
- newBuilder = new JSchema({
499
- anyOf: [{ type: 'null', optionalValues }, newBuilder.build()],
500
- optionalField: true,
501
- });
502
- }
503
- return newBuilder;
504
- }
505
520
  regex(pattern, opt) {
506
521
  _assert(!pattern.flags, `Regex flags are not supported by JSON Schema. Received: /${pattern.source}/${pattern.flags}`);
507
522
  return this.pattern(pattern.source, opt);
@@ -626,28 +641,6 @@ export class JIsoDate extends JBuilder {
626
641
  IsoDate: {},
627
642
  });
628
643
  }
629
- /**
630
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
631
- *
632
- * This `null` feature only works when the current schema is nested in an object or array schema,
633
- * due to how mutability works in Ajv.
634
- *
635
- * When `null` is passed, the return type becomes `JSchema`
636
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
637
- */
638
- optional(nullValue) {
639
- if (nullValue === undefined) {
640
- return super.optional();
641
- }
642
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
643
- // so we must allow `null` values to be parsed by Ajv,
644
- // but the typing should not reflect that.
645
- // We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
646
- return new JSchema({
647
- anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
648
- optionalField: true,
649
- });
650
- }
651
644
  before(date) {
652
645
  return this.cloneAndUpdateSchema({ IsoDate: { before: date } });
653
646
  }
@@ -677,40 +670,6 @@ export class JNumber extends JBuilder {
677
670
  type: 'number',
678
671
  });
679
672
  }
680
- /**
681
- * @param optionalValues List of values that should be considered/converted as `undefined`.
682
- *
683
- * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
684
- * due to how mutability works in Ajv.
685
- *
686
- * Make sure this `optional()` call is at the end of your call chain.
687
- *
688
- * When `null` is included in optionalValues, the return type becomes `JSchema`
689
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
690
- */
691
- optional(optionalValues) {
692
- if (!optionalValues) {
693
- return super.optional();
694
- }
695
- _typeCast(optionalValues);
696
- let newBuilder = new JNumber().optional();
697
- const alternativesSchema = j.enum(optionalValues);
698
- Object.assign(newBuilder.getSchema(), {
699
- anyOf: [this.build(), alternativesSchema.build()],
700
- optionalValues,
701
- });
702
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
703
- // so we must allow `null` values to be parsed by Ajv,
704
- // but the typing should not reflect that.
705
- // We also cannot accept more rules attached, since we're not building a NumberSchema anymore.
706
- if (optionalValues.includes(null)) {
707
- newBuilder = new JSchema({
708
- anyOf: [{ type: 'null', optionalValues }, newBuilder.build()],
709
- optionalField: true,
710
- });
711
- }
712
- return newBuilder;
713
- }
714
673
  integer() {
715
674
  return this.cloneAndUpdateSchema({ type: 'integer' });
716
675
  }
@@ -811,24 +770,6 @@ export class JBoolean extends JBuilder {
811
770
  type: 'boolean',
812
771
  });
813
772
  }
814
- /**
815
- * @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
816
- *
817
- * This `optionalValue` feature only works when the current schema is nested in an object or array schema,
818
- * due to how mutability works in Ajv.
819
- */
820
- optional(optionalValue) {
821
- if (typeof optionalValue === 'undefined') {
822
- return super.optional();
823
- }
824
- const newBuilder = new JBoolean().optional();
825
- const alternativesSchema = j.enum([optionalValue]);
826
- Object.assign(newBuilder.getSchema(), {
827
- anyOf: [this.build(), alternativesSchema.build()],
828
- optionalValues: [optionalValue],
829
- });
830
- return newBuilder;
831
- }
832
773
  }
833
774
  export class JObject extends JBuilder {
834
775
  constructor(props, opt) {
@@ -844,28 +785,6 @@ export class JObject extends JBuilder {
844
785
  if (props)
845
786
  addPropertiesToSchema(this.schema, props);
846
787
  }
847
- /**
848
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
849
- *
850
- * This `null` feature only works when the current schema is nested in an object or array schema,
851
- * due to how mutability works in Ajv.
852
- *
853
- * When `null` is passed, the return type becomes `JSchema`
854
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
855
- */
856
- optional(nullValue) {
857
- if (nullValue === undefined) {
858
- return super.optional();
859
- }
860
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
861
- // so we must allow `null` values to be parsed by Ajv,
862
- // but the typing should not reflect that.
863
- // We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
864
- return new JSchema({
865
- anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
866
- optionalField: true,
867
- });
868
- }
869
788
  /**
870
789
  * When set, the validation will not strip away properties that are not specified explicitly in the schema.
871
790
  */
@@ -926,29 +845,6 @@ export class JObjectInfer extends JBuilder {
926
845
  if (props)
927
846
  addPropertiesToSchema(this.schema, props);
928
847
  }
929
- /**
930
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
931
- *
932
- * This `null` feature only works when the current schema is nested in an object or array schema,
933
- * due to how mutability works in Ajv.
934
- *
935
- * When `null` is passed, the return type becomes `JSchema`
936
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
937
- */
938
- // @ts-expect-error override adds optional parameter which is compatible but TS can't verify complex mapped types
939
- optional(nullValue) {
940
- if (nullValue === undefined) {
941
- return super.optional();
942
- }
943
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
944
- // so we must allow `null` values to be parsed by Ajv,
945
- // but the typing should not reflect that.
946
- // We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
947
- return new JSchema({
948
- anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
949
- optionalField: true,
950
- });
951
- }
952
848
  /**
953
849
  * When set, the validation will not strip away properties that are not specified explicitly in the schema.
954
850
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.96.1",
4
+ "version": "15.97.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@standard-schema/spec": "^1",
@@ -567,9 +567,68 @@ export class JBuilder<OUT, Opt> extends JSchema<OUT, Opt> {
567
567
  return this.cloneAndUpdateSchema({ type: 'object', instanceof: of })
568
568
  }
569
569
 
570
- optional(): JBuilder<OUT | undefined, true> {
571
- const clone = this.cloneAndUpdateSchema({ optionalField: true })
572
- return clone as unknown as JBuilder<OUT | undefined, true>
570
+ /**
571
+ * @param optionalValues List of values that should be considered/converted as `undefined`.
572
+ *
573
+ * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
574
+ * due to how mutability works in Ajv.
575
+ *
576
+ * Make sure this `optional()` call is at the end of your call chain.
577
+ *
578
+ * When `null` is included in optionalValues, the return type becomes `JSchema`
579
+ * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
580
+ */
581
+ optional<T extends readonly (string | number | boolean | null)[] | undefined = undefined>(
582
+ optionalValues?: T,
583
+ ): T extends readonly (string | number | boolean | null)[]
584
+ ? JSchema<OUT | undefined, true>
585
+ : JBuilder<OUT | undefined, true> {
586
+ if (!optionalValues?.length) {
587
+ const clone = this.cloneAndUpdateSchema({ optionalField: true })
588
+ return clone as any
589
+ }
590
+
591
+ const builtSchema = this.build()
592
+
593
+ // When optionalValues is just [null], use a simple null-wrapping structure.
594
+ // If the schema already has anyOf with a null branch (from nullable()),
595
+ // inject optionalValues directly into it.
596
+ if (optionalValues.length === 1 && optionalValues[0] === null) {
597
+ if (builtSchema.anyOf) {
598
+ const nullBranch = builtSchema.anyOf.find(b => b.type === 'null')
599
+ if (nullBranch) {
600
+ nullBranch.optionalValues = [null]
601
+ return new JSchema({ ...builtSchema, optionalField: true }) as any
602
+ }
603
+ }
604
+
605
+ // Wrap with null type branch
606
+ return new JSchema({
607
+ anyOf: [{ type: 'null', optionalValues: [null] }, builtSchema],
608
+ optionalField: true,
609
+ }) as any
610
+ }
611
+
612
+ // General case: create anyOf with current schema + alternatives.
613
+ // Preserve the original type for Ajv strict mode (optionalValues keyword requires a type).
614
+ const alternativesSchema = j.enum(optionalValues).build()
615
+ const innerSchema: JsonSchema = {
616
+ ...(builtSchema.type ? { type: builtSchema.type } : {}),
617
+ anyOf: [builtSchema, alternativesSchema],
618
+ optionalValues: [...optionalValues],
619
+ }
620
+
621
+ // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
622
+ // so we must allow `null` values to be parsed by Ajv,
623
+ // but the typing should not reflect that.
624
+ if (optionalValues.includes(null)) {
625
+ return new JSchema({
626
+ anyOf: [{ type: 'null', optionalValues: [...optionalValues] }, innerSchema],
627
+ optionalField: true,
628
+ }) as any
629
+ }
630
+
631
+ return new JSchema({ ...innerSchema, optionalField: true }) as any
573
632
  }
574
633
 
575
634
  nullable(): JBuilder<OUT | null, Opt> {
@@ -643,51 +702,6 @@ export class JString<
643
702
  })
644
703
  }
645
704
 
646
- /**
647
- * @param optionalValues List of values that should be considered/converted as `undefined`.
648
- *
649
- * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
650
- * due to how mutability works in Ajv.
651
- *
652
- * Make sure this `optional()` call is at the end of your call chain.
653
- *
654
- * When `null` is included in optionalValues, the return type becomes `JSchema`
655
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
656
- */
657
- override optional<T extends readonly (string | null)[] | undefined = undefined>(
658
- optionalValues?: T,
659
- ): T extends readonly (infer U)[]
660
- ? null extends U
661
- ? JSchema<OUT | undefined, true>
662
- : JString<OUT | undefined, true>
663
- : JString<OUT | undefined, true> {
664
- if (!optionalValues) {
665
- return super.optional() as any
666
- }
667
-
668
- _typeCast<(string | null)[]>(optionalValues)
669
-
670
- let newBuilder: JSchema<OUT | undefined, true> = new JString<OUT, Opt>().optional()
671
- const alternativesSchema = j.enum(optionalValues)
672
- Object.assign(newBuilder.getSchema(), {
673
- anyOf: [this.build(), alternativesSchema.build()],
674
- optionalValues,
675
- })
676
-
677
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
678
- // so we must allow `null` values to be parsed by Ajv,
679
- // but the typing should not reflect that.
680
- // We also cannot accept more rules attached, since we're not building a StringSchema anymore.
681
- if (optionalValues.includes(null)) {
682
- newBuilder = new JSchema({
683
- anyOf: [{ type: 'null', optionalValues }, newBuilder.build()],
684
- optionalField: true,
685
- })
686
- }
687
-
688
- return newBuilder as any
689
- }
690
-
691
705
  regex(pattern: RegExp, opt?: JsonBuilderRuleOpt): this {
692
706
  _assert(
693
707
  !pattern.flags,
@@ -846,32 +860,6 @@ export class JIsoDate<Opt extends boolean = false> extends JBuilder<IsoDate, Opt
846
860
  })
847
861
  }
848
862
 
849
- /**
850
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
851
- *
852
- * This `null` feature only works when the current schema is nested in an object or array schema,
853
- * due to how mutability works in Ajv.
854
- *
855
- * When `null` is passed, the return type becomes `JSchema`
856
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
857
- */
858
- override optional<N extends null | undefined = undefined>(
859
- nullValue?: N,
860
- ): N extends null ? JSchema<IsoDate | undefined, true> : JBuilder<IsoDate | undefined, true> {
861
- if (nullValue === undefined) {
862
- return super.optional() as any
863
- }
864
-
865
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
866
- // so we must allow `null` values to be parsed by Ajv,
867
- // but the typing should not reflect that.
868
- // We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
869
- return new JSchema({
870
- anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
871
- optionalField: true,
872
- }) as any
873
- }
874
-
875
863
  before(date: string): this {
876
864
  return this.cloneAndUpdateSchema({ IsoDate: { before: date } })
877
865
  }
@@ -920,51 +908,6 @@ export class JNumber<
920
908
  })
921
909
  }
922
910
 
923
- /**
924
- * @param optionalValues List of values that should be considered/converted as `undefined`.
925
- *
926
- * This `optionalValues` feature only works when the current schema is nested in an object or array schema,
927
- * due to how mutability works in Ajv.
928
- *
929
- * Make sure this `optional()` call is at the end of your call chain.
930
- *
931
- * When `null` is included in optionalValues, the return type becomes `JSchema`
932
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
933
- */
934
- override optional<T extends readonly (number | null)[] | undefined = undefined>(
935
- optionalValues?: T,
936
- ): T extends readonly (infer U)[]
937
- ? null extends U
938
- ? JSchema<OUT | undefined, true>
939
- : JNumber<OUT | undefined, true>
940
- : JNumber<OUT | undefined, true> {
941
- if (!optionalValues) {
942
- return super.optional() as any
943
- }
944
-
945
- _typeCast<(number | null)[]>(optionalValues)
946
-
947
- let newBuilder: JSchema<OUT | undefined, true> = new JNumber<OUT, Opt>().optional()
948
- const alternativesSchema = j.enum(optionalValues)
949
- Object.assign(newBuilder.getSchema(), {
950
- anyOf: [this.build(), alternativesSchema.build()],
951
- optionalValues,
952
- })
953
-
954
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
955
- // so we must allow `null` values to be parsed by Ajv,
956
- // but the typing should not reflect that.
957
- // We also cannot accept more rules attached, since we're not building a NumberSchema anymore.
958
- if (optionalValues.includes(null)) {
959
- newBuilder = new JSchema({
960
- anyOf: [{ type: 'null', optionalValues }, newBuilder.build()],
961
- optionalField: true,
962
- })
963
- }
964
-
965
- return newBuilder as any
966
- }
967
-
968
911
  integer(): this {
969
912
  return this.cloneAndUpdateSchema({ type: 'integer' })
970
913
  }
@@ -1092,27 +1035,6 @@ export class JBoolean<
1092
1035
  type: 'boolean',
1093
1036
  })
1094
1037
  }
1095
-
1096
- /**
1097
- * @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
1098
- *
1099
- * This `optionalValue` feature only works when the current schema is nested in an object or array schema,
1100
- * due to how mutability works in Ajv.
1101
- */
1102
- override optional(optionalValue?: boolean): JBoolean<OUT | undefined, true> {
1103
- if (typeof optionalValue === 'undefined') {
1104
- return super.optional() as unknown as JBoolean<OUT | undefined, true>
1105
- }
1106
-
1107
- const newBuilder = new JBoolean<OUT, Opt>().optional()
1108
- const alternativesSchema = j.enum([optionalValue])
1109
- Object.assign(newBuilder.getSchema(), {
1110
- anyOf: [this.build(), alternativesSchema.build()],
1111
- optionalValues: [optionalValue],
1112
- })
1113
-
1114
- return newBuilder
1115
- }
1116
1038
  }
1117
1039
 
1118
1040
  export class JObject<OUT extends AnyObject, Opt extends boolean = false> extends JBuilder<
@@ -1133,32 +1055,6 @@ export class JObject<OUT extends AnyObject, Opt extends boolean = false> extends
1133
1055
  if (props) addPropertiesToSchema(this.schema, props)
1134
1056
  }
1135
1057
 
1136
- /**
1137
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
1138
- *
1139
- * This `null` feature only works when the current schema is nested in an object or array schema,
1140
- * due to how mutability works in Ajv.
1141
- *
1142
- * When `null` is passed, the return type becomes `JSchema`
1143
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
1144
- */
1145
- override optional<N extends null | undefined = undefined>(
1146
- nullValue?: N,
1147
- ): N extends null ? JSchema<OUT | undefined, true> : JBuilder<OUT | undefined, true> {
1148
- if (nullValue === undefined) {
1149
- return super.optional() as any
1150
- }
1151
-
1152
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
1153
- // so we must allow `null` values to be parsed by Ajv,
1154
- // but the typing should not reflect that.
1155
- // We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
1156
- return new JSchema({
1157
- anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
1158
- optionalField: true,
1159
- }) as any
1160
- }
1161
-
1162
1058
  /**
1163
1059
  * When set, the validation will not strip away properties that are not specified explicitly in the schema.
1164
1060
  */
@@ -1279,71 +1175,6 @@ export class JObjectInfer<
1279
1175
  if (props) addPropertiesToSchema(this.schema, props)
1280
1176
  }
1281
1177
 
1282
- /**
1283
- * @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
1284
- *
1285
- * This `null` feature only works when the current schema is nested in an object or array schema,
1286
- * due to how mutability works in Ajv.
1287
- *
1288
- * When `null` is passed, the return type becomes `JSchema`
1289
- * (no further chaining allowed) because the schema is wrapped in an anyOf structure.
1290
- */
1291
- // @ts-expect-error override adds optional parameter which is compatible but TS can't verify complex mapped types
1292
- override optional<N extends null | undefined = undefined>(
1293
- nullValue?: N,
1294
- ): N extends null
1295
- ? JSchema<
1296
- | Expand<
1297
- {
1298
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
1299
- ? IsOpt extends true
1300
- ? never
1301
- : K
1302
- : never]: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
1303
- } & {
1304
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
1305
- ? IsOpt extends true
1306
- ? K
1307
- : never
1308
- : never]?: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
1309
- }
1310
- >
1311
- | undefined,
1312
- true
1313
- >
1314
- : JBuilder<
1315
- | Expand<
1316
- {
1317
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
1318
- ? IsOpt extends true
1319
- ? never
1320
- : K
1321
- : never]: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
1322
- } & {
1323
- [K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
1324
- ? IsOpt extends true
1325
- ? K
1326
- : never
1327
- : never]?: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
1328
- }
1329
- >
1330
- | undefined,
1331
- true
1332
- > {
1333
- if (nullValue === undefined) {
1334
- return super.optional() as any
1335
- }
1336
-
1337
- // When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
1338
- // so we must allow `null` values to be parsed by Ajv,
1339
- // but the typing should not reflect that.
1340
- // We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
1341
- return new JSchema({
1342
- anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
1343
- optionalField: true,
1344
- }) as any
1345
- }
1346
-
1347
1178
  /**
1348
1179
  * When set, the validation will not strip away properties that are not specified explicitly in the schema.
1349
1180
  */