@naturalcycles/nodejs-lib 15.96.0 → 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.
- package/dist/validation/ajv/jSchema.d.ts +14 -70
- package/dist/validation/ajv/jSchema.js +52 -156
- package/package.json +1 -1
- package/src/validation/ajv/jSchema.ts +65 -231
|
@@ -163,6 +163,8 @@ export declare class JSchema<OUT, Opt> implements StandardSchemaV1<unknown, OUT>
|
|
|
163
163
|
*/
|
|
164
164
|
out: OUT;
|
|
165
165
|
opt: Opt;
|
|
166
|
+
/** Forces OUT to be invariant (prevents covariant subtype matching in object property constraints). */
|
|
167
|
+
protected _invariantOut: (x: OUT) => void;
|
|
166
168
|
}
|
|
167
169
|
export declare class JBuilder<OUT, Opt> extends JSchema<OUT, Opt> {
|
|
168
170
|
protected setErrorMessage(ruleName: string, errorMessage: string | undefined): void;
|
|
@@ -182,7 +184,18 @@ export declare class JBuilder<OUT, Opt> extends JSchema<OUT, Opt> {
|
|
|
182
184
|
type(type: string): this;
|
|
183
185
|
default(v: any): this;
|
|
184
186
|
instanceof(of: string): this;
|
|
185
|
-
|
|
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>;
|
|
186
199
|
nullable(): JBuilder<OUT | null, Opt>;
|
|
187
200
|
/**
|
|
188
201
|
* @deprecated
|
|
@@ -214,18 +227,6 @@ export declare class JBuilder<OUT, Opt> extends JSchema<OUT, Opt> {
|
|
|
214
227
|
}
|
|
215
228
|
export declare class JString<OUT extends string | undefined = string, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
|
|
216
229
|
constructor();
|
|
217
|
-
/**
|
|
218
|
-
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
219
|
-
*
|
|
220
|
-
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
221
|
-
* due to how mutability works in Ajv.
|
|
222
|
-
*
|
|
223
|
-
* Make sure this `optional()` call is at the end of your call chain.
|
|
224
|
-
*
|
|
225
|
-
* When `null` is included in optionalValues, the return type becomes `JSchema`
|
|
226
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
227
|
-
*/
|
|
228
|
-
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>;
|
|
229
230
|
regex(pattern: RegExp, opt?: JsonBuilderRuleOpt): this;
|
|
230
231
|
pattern(pattern: string, opt?: JsonBuilderRuleOpt): this;
|
|
231
232
|
minLength(minLength: number): this;
|
|
@@ -275,16 +276,6 @@ export interface JsonSchemaStringEmailOptions {
|
|
|
275
276
|
}
|
|
276
277
|
export declare class JIsoDate<Opt extends boolean = false> extends JBuilder<IsoDate, Opt> {
|
|
277
278
|
constructor();
|
|
278
|
-
/**
|
|
279
|
-
* @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
|
|
280
|
-
*
|
|
281
|
-
* This `null` feature only works when the current schema is nested in an object or array schema,
|
|
282
|
-
* due to how mutability works in Ajv.
|
|
283
|
-
*
|
|
284
|
-
* When `null` is passed, the return type becomes `JSchema`
|
|
285
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
286
|
-
*/
|
|
287
|
-
optional<N extends null | undefined = undefined>(nullValue?: N): N extends null ? JSchema<IsoDate | undefined, true> : JBuilder<IsoDate | undefined, true>;
|
|
288
279
|
before(date: string): this;
|
|
289
280
|
sameOrBefore(date: string): this;
|
|
290
281
|
after(date: string): this;
|
|
@@ -301,18 +292,6 @@ export interface JsonSchemaIsoMonthOptions {
|
|
|
301
292
|
}
|
|
302
293
|
export declare class JNumber<OUT extends number | undefined = number, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
|
|
303
294
|
constructor();
|
|
304
|
-
/**
|
|
305
|
-
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
306
|
-
*
|
|
307
|
-
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
308
|
-
* due to how mutability works in Ajv.
|
|
309
|
-
*
|
|
310
|
-
* Make sure this `optional()` call is at the end of your call chain.
|
|
311
|
-
*
|
|
312
|
-
* When `null` is included in optionalValues, the return type becomes `JSchema`
|
|
313
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
314
|
-
*/
|
|
315
|
-
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>;
|
|
316
295
|
integer(): this;
|
|
317
296
|
branded<B extends number>(): JNumber<B, Opt>;
|
|
318
297
|
multipleOf(multipleOf: number): this;
|
|
@@ -345,26 +324,9 @@ export declare class JNumber<OUT extends number | undefined = number, Opt extend
|
|
|
345
324
|
}
|
|
346
325
|
export declare class JBoolean<OUT extends boolean | undefined = boolean, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
|
|
347
326
|
constructor();
|
|
348
|
-
/**
|
|
349
|
-
* @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
|
|
350
|
-
*
|
|
351
|
-
* This `optionalValue` feature only works when the current schema is nested in an object or array schema,
|
|
352
|
-
* due to how mutability works in Ajv.
|
|
353
|
-
*/
|
|
354
|
-
optional(optionalValue?: boolean): JBoolean<OUT | undefined, true>;
|
|
355
327
|
}
|
|
356
328
|
export declare class JObject<OUT extends AnyObject, Opt extends boolean = false> extends JBuilder<OUT, Opt> {
|
|
357
329
|
constructor(props?: AnyObject, opt?: JObjectOpts);
|
|
358
|
-
/**
|
|
359
|
-
* @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
|
|
360
|
-
*
|
|
361
|
-
* This `null` feature only works when the current schema is nested in an object or array schema,
|
|
362
|
-
* due to how mutability works in Ajv.
|
|
363
|
-
*
|
|
364
|
-
* When `null` is passed, the return type becomes `JSchema`
|
|
365
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
366
|
-
*/
|
|
367
|
-
optional<N extends null | undefined = undefined>(nullValue?: N): N extends null ? JSchema<OUT | undefined, true> : JBuilder<OUT | undefined, true>;
|
|
368
330
|
/**
|
|
369
331
|
* When set, the validation will not strip away properties that are not specified explicitly in the schema.
|
|
370
332
|
*/
|
|
@@ -405,24 +367,6 @@ export declare class JObjectInfer<PROPS extends Record<string, JBuilder<any, any
|
|
|
405
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;
|
|
406
368
|
}>, Opt> {
|
|
407
369
|
constructor(props?: PROPS);
|
|
408
|
-
/**
|
|
409
|
-
* @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
|
|
410
|
-
*
|
|
411
|
-
* This `null` 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
|
-
* When `null` is passed, the return type becomes `JSchema`
|
|
415
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
416
|
-
*/
|
|
417
|
-
optional<N extends null | undefined = undefined>(nullValue?: N): N extends null ? JSchema<Expand<{
|
|
418
|
-
[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;
|
|
419
|
-
} & {
|
|
420
|
-
[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;
|
|
421
|
-
}> | undefined, true> : JBuilder<Expand<{
|
|
422
|
-
[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;
|
|
423
|
-
} & {
|
|
424
|
-
[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;
|
|
425
|
-
}> | undefined, true>;
|
|
426
370
|
/**
|
|
427
371
|
* When set, the validation will not strip away properties that are not specified explicitly in the schema.
|
|
428
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
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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
|
@@ -506,6 +506,9 @@ export class JSchema<OUT, Opt>
|
|
|
506
506
|
*/
|
|
507
507
|
out!: OUT
|
|
508
508
|
opt!: Opt
|
|
509
|
+
|
|
510
|
+
/** Forces OUT to be invariant (prevents covariant subtype matching in object property constraints). */
|
|
511
|
+
declare protected _invariantOut: (x: OUT) => void
|
|
509
512
|
}
|
|
510
513
|
|
|
511
514
|
// ==== JBuilder (chainable base) ====
|
|
@@ -564,9 +567,68 @@ export class JBuilder<OUT, Opt> extends JSchema<OUT, Opt> {
|
|
|
564
567
|
return this.cloneAndUpdateSchema({ type: 'object', instanceof: of })
|
|
565
568
|
}
|
|
566
569
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
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
|
|
570
632
|
}
|
|
571
633
|
|
|
572
634
|
nullable(): JBuilder<OUT | null, Opt> {
|
|
@@ -640,51 +702,6 @@ export class JString<
|
|
|
640
702
|
})
|
|
641
703
|
}
|
|
642
704
|
|
|
643
|
-
/**
|
|
644
|
-
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
645
|
-
*
|
|
646
|
-
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
647
|
-
* due to how mutability works in Ajv.
|
|
648
|
-
*
|
|
649
|
-
* Make sure this `optional()` call is at the end of your call chain.
|
|
650
|
-
*
|
|
651
|
-
* When `null` is included in optionalValues, the return type becomes `JSchema`
|
|
652
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
653
|
-
*/
|
|
654
|
-
override optional<T extends readonly (string | null)[] | undefined = undefined>(
|
|
655
|
-
optionalValues?: T,
|
|
656
|
-
): T extends readonly (infer U)[]
|
|
657
|
-
? null extends U
|
|
658
|
-
? JSchema<OUT | undefined, true>
|
|
659
|
-
: JString<OUT | undefined, true>
|
|
660
|
-
: JString<OUT | undefined, true> {
|
|
661
|
-
if (!optionalValues) {
|
|
662
|
-
return super.optional() as any
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
_typeCast<(string | null)[]>(optionalValues)
|
|
666
|
-
|
|
667
|
-
let newBuilder: JSchema<OUT | undefined, true> = new JString<OUT, Opt>().optional()
|
|
668
|
-
const alternativesSchema = j.enum(optionalValues)
|
|
669
|
-
Object.assign(newBuilder.getSchema(), {
|
|
670
|
-
anyOf: [this.build(), alternativesSchema.build()],
|
|
671
|
-
optionalValues,
|
|
672
|
-
})
|
|
673
|
-
|
|
674
|
-
// When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
|
|
675
|
-
// so we must allow `null` values to be parsed by Ajv,
|
|
676
|
-
// but the typing should not reflect that.
|
|
677
|
-
// We also cannot accept more rules attached, since we're not building a StringSchema anymore.
|
|
678
|
-
if (optionalValues.includes(null)) {
|
|
679
|
-
newBuilder = new JSchema({
|
|
680
|
-
anyOf: [{ type: 'null', optionalValues }, newBuilder.build()],
|
|
681
|
-
optionalField: true,
|
|
682
|
-
})
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
return newBuilder as any
|
|
686
|
-
}
|
|
687
|
-
|
|
688
705
|
regex(pattern: RegExp, opt?: JsonBuilderRuleOpt): this {
|
|
689
706
|
_assert(
|
|
690
707
|
!pattern.flags,
|
|
@@ -843,32 +860,6 @@ export class JIsoDate<Opt extends boolean = false> extends JBuilder<IsoDate, Opt
|
|
|
843
860
|
})
|
|
844
861
|
}
|
|
845
862
|
|
|
846
|
-
/**
|
|
847
|
-
* @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
|
|
848
|
-
*
|
|
849
|
-
* This `null` feature only works when the current schema is nested in an object or array schema,
|
|
850
|
-
* due to how mutability works in Ajv.
|
|
851
|
-
*
|
|
852
|
-
* When `null` is passed, the return type becomes `JSchema`
|
|
853
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
854
|
-
*/
|
|
855
|
-
override optional<N extends null | undefined = undefined>(
|
|
856
|
-
nullValue?: N,
|
|
857
|
-
): N extends null ? JSchema<IsoDate | undefined, true> : JBuilder<IsoDate | undefined, true> {
|
|
858
|
-
if (nullValue === undefined) {
|
|
859
|
-
return super.optional() as any
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
// When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
|
|
863
|
-
// so we must allow `null` values to be parsed by Ajv,
|
|
864
|
-
// but the typing should not reflect that.
|
|
865
|
-
// We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
|
|
866
|
-
return new JSchema({
|
|
867
|
-
anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
|
|
868
|
-
optionalField: true,
|
|
869
|
-
}) as any
|
|
870
|
-
}
|
|
871
|
-
|
|
872
863
|
before(date: string): this {
|
|
873
864
|
return this.cloneAndUpdateSchema({ IsoDate: { before: date } })
|
|
874
865
|
}
|
|
@@ -917,51 +908,6 @@ export class JNumber<
|
|
|
917
908
|
})
|
|
918
909
|
}
|
|
919
910
|
|
|
920
|
-
/**
|
|
921
|
-
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
922
|
-
*
|
|
923
|
-
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
924
|
-
* due to how mutability works in Ajv.
|
|
925
|
-
*
|
|
926
|
-
* Make sure this `optional()` call is at the end of your call chain.
|
|
927
|
-
*
|
|
928
|
-
* When `null` is included in optionalValues, the return type becomes `JSchema`
|
|
929
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
930
|
-
*/
|
|
931
|
-
override optional<T extends readonly (number | null)[] | undefined = undefined>(
|
|
932
|
-
optionalValues?: T,
|
|
933
|
-
): T extends readonly (infer U)[]
|
|
934
|
-
? null extends U
|
|
935
|
-
? JSchema<OUT | undefined, true>
|
|
936
|
-
: JNumber<OUT | undefined, true>
|
|
937
|
-
: JNumber<OUT | undefined, true> {
|
|
938
|
-
if (!optionalValues) {
|
|
939
|
-
return super.optional() as any
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
_typeCast<(number | null)[]>(optionalValues)
|
|
943
|
-
|
|
944
|
-
let newBuilder: JSchema<OUT | undefined, true> = new JNumber<OUT, Opt>().optional()
|
|
945
|
-
const alternativesSchema = j.enum(optionalValues)
|
|
946
|
-
Object.assign(newBuilder.getSchema(), {
|
|
947
|
-
anyOf: [this.build(), alternativesSchema.build()],
|
|
948
|
-
optionalValues,
|
|
949
|
-
})
|
|
950
|
-
|
|
951
|
-
// When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
|
|
952
|
-
// so we must allow `null` values to be parsed by Ajv,
|
|
953
|
-
// but the typing should not reflect that.
|
|
954
|
-
// We also cannot accept more rules attached, since we're not building a NumberSchema anymore.
|
|
955
|
-
if (optionalValues.includes(null)) {
|
|
956
|
-
newBuilder = new JSchema({
|
|
957
|
-
anyOf: [{ type: 'null', optionalValues }, newBuilder.build()],
|
|
958
|
-
optionalField: true,
|
|
959
|
-
})
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
return newBuilder as any
|
|
963
|
-
}
|
|
964
|
-
|
|
965
911
|
integer(): this {
|
|
966
912
|
return this.cloneAndUpdateSchema({ type: 'integer' })
|
|
967
913
|
}
|
|
@@ -1089,27 +1035,6 @@ export class JBoolean<
|
|
|
1089
1035
|
type: 'boolean',
|
|
1090
1036
|
})
|
|
1091
1037
|
}
|
|
1092
|
-
|
|
1093
|
-
/**
|
|
1094
|
-
* @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
|
|
1095
|
-
*
|
|
1096
|
-
* This `optionalValue` feature only works when the current schema is nested in an object or array schema,
|
|
1097
|
-
* due to how mutability works in Ajv.
|
|
1098
|
-
*/
|
|
1099
|
-
override optional(optionalValue?: boolean): JBoolean<OUT | undefined, true> {
|
|
1100
|
-
if (typeof optionalValue === 'undefined') {
|
|
1101
|
-
return super.optional() as unknown as JBoolean<OUT | undefined, true>
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
const newBuilder = new JBoolean<OUT, Opt>().optional()
|
|
1105
|
-
const alternativesSchema = j.enum([optionalValue])
|
|
1106
|
-
Object.assign(newBuilder.getSchema(), {
|
|
1107
|
-
anyOf: [this.build(), alternativesSchema.build()],
|
|
1108
|
-
optionalValues: [optionalValue],
|
|
1109
|
-
})
|
|
1110
|
-
|
|
1111
|
-
return newBuilder
|
|
1112
|
-
}
|
|
1113
1038
|
}
|
|
1114
1039
|
|
|
1115
1040
|
export class JObject<OUT extends AnyObject, Opt extends boolean = false> extends JBuilder<
|
|
@@ -1130,32 +1055,6 @@ export class JObject<OUT extends AnyObject, Opt extends boolean = false> extends
|
|
|
1130
1055
|
if (props) addPropertiesToSchema(this.schema, props)
|
|
1131
1056
|
}
|
|
1132
1057
|
|
|
1133
|
-
/**
|
|
1134
|
-
* @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
|
|
1135
|
-
*
|
|
1136
|
-
* This `null` feature only works when the current schema is nested in an object or array schema,
|
|
1137
|
-
* due to how mutability works in Ajv.
|
|
1138
|
-
*
|
|
1139
|
-
* When `null` is passed, the return type becomes `JSchema`
|
|
1140
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
1141
|
-
*/
|
|
1142
|
-
override optional<N extends null | undefined = undefined>(
|
|
1143
|
-
nullValue?: N,
|
|
1144
|
-
): N extends null ? JSchema<OUT | undefined, true> : JBuilder<OUT | undefined, true> {
|
|
1145
|
-
if (nullValue === undefined) {
|
|
1146
|
-
return super.optional() as any
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
// When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
|
|
1150
|
-
// so we must allow `null` values to be parsed by Ajv,
|
|
1151
|
-
// but the typing should not reflect that.
|
|
1152
|
-
// We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
|
|
1153
|
-
return new JSchema({
|
|
1154
|
-
anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
|
|
1155
|
-
optionalField: true,
|
|
1156
|
-
}) as any
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
1058
|
/**
|
|
1160
1059
|
* When set, the validation will not strip away properties that are not specified explicitly in the schema.
|
|
1161
1060
|
*/
|
|
@@ -1276,71 +1175,6 @@ export class JObjectInfer<
|
|
|
1276
1175
|
if (props) addPropertiesToSchema(this.schema, props)
|
|
1277
1176
|
}
|
|
1278
1177
|
|
|
1279
|
-
/**
|
|
1280
|
-
* @param nullValue Pass `null` to have `null` values be considered/converted as `undefined`.
|
|
1281
|
-
*
|
|
1282
|
-
* This `null` feature only works when the current schema is nested in an object or array schema,
|
|
1283
|
-
* due to how mutability works in Ajv.
|
|
1284
|
-
*
|
|
1285
|
-
* When `null` is passed, the return type becomes `JSchema`
|
|
1286
|
-
* (no further chaining allowed) because the schema is wrapped in an anyOf structure.
|
|
1287
|
-
*/
|
|
1288
|
-
// @ts-expect-error override adds optional parameter which is compatible but TS can't verify complex mapped types
|
|
1289
|
-
override optional<N extends null | undefined = undefined>(
|
|
1290
|
-
nullValue?: N,
|
|
1291
|
-
): N extends null
|
|
1292
|
-
? JSchema<
|
|
1293
|
-
| Expand<
|
|
1294
|
-
{
|
|
1295
|
-
[K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
|
|
1296
|
-
? IsOpt extends true
|
|
1297
|
-
? never
|
|
1298
|
-
: K
|
|
1299
|
-
: never]: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
|
|
1300
|
-
} & {
|
|
1301
|
-
[K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
|
|
1302
|
-
? IsOpt extends true
|
|
1303
|
-
? K
|
|
1304
|
-
: never
|
|
1305
|
-
: never]?: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
|
|
1306
|
-
}
|
|
1307
|
-
>
|
|
1308
|
-
| undefined,
|
|
1309
|
-
true
|
|
1310
|
-
>
|
|
1311
|
-
: JBuilder<
|
|
1312
|
-
| Expand<
|
|
1313
|
-
{
|
|
1314
|
-
[K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
|
|
1315
|
-
? IsOpt extends true
|
|
1316
|
-
? never
|
|
1317
|
-
: K
|
|
1318
|
-
: never]: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
|
|
1319
|
-
} & {
|
|
1320
|
-
[K in keyof PROPS as PROPS[K] extends JBuilder<any, infer IsOpt>
|
|
1321
|
-
? IsOpt extends true
|
|
1322
|
-
? K
|
|
1323
|
-
: never
|
|
1324
|
-
: never]?: PROPS[K] extends JBuilder<infer OUT, any> ? OUT : never
|
|
1325
|
-
}
|
|
1326
|
-
>
|
|
1327
|
-
| undefined,
|
|
1328
|
-
true
|
|
1329
|
-
> {
|
|
1330
|
-
if (nullValue === undefined) {
|
|
1331
|
-
return super.optional() as any
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
// When `null` is specified, we want `null` to be stripped and the value to become `undefined`,
|
|
1335
|
-
// so we must allow `null` values to be parsed by Ajv,
|
|
1336
|
-
// but the typing should not reflect that.
|
|
1337
|
-
// We also cannot accept more rules attached, since we're not building an ObjectSchema anymore.
|
|
1338
|
-
return new JSchema({
|
|
1339
|
-
anyOf: [{ type: 'null', optionalValues: [null] }, this.build()],
|
|
1340
|
-
optionalField: true,
|
|
1341
|
-
}) as any
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
1178
|
/**
|
|
1345
1179
|
* When set, the validation will not strip away properties that are not specified explicitly in the schema.
|
|
1346
1180
|
*/
|