@naturalcycles/nodejs-lib 15.54.0 → 15.55.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/ajvSchema.js +6 -0
- package/dist/validation/ajv/getAjv.js +18 -1
- package/dist/validation/ajv/jsonSchemaBuilder.d.ts +29 -4
- package/dist/validation/ajv/jsonSchemaBuilder.js +39 -0
- package/package.json +1 -1
- package/src/validation/ajv/ajvSchema.ts +7 -0
- package/src/validation/ajv/getAjv.ts +25 -1
- package/src/validation/ajv/jsonSchemaBuilder.ts +68 -4
|
@@ -59,6 +59,12 @@ export class AjvSchema {
|
|
|
59
59
|
else {
|
|
60
60
|
jsonSchema = schema;
|
|
61
61
|
}
|
|
62
|
+
// This is our own helper which marks a schema as optional
|
|
63
|
+
// in case it is going to be used in an object schema,
|
|
64
|
+
// where we need to mark the given property as not-required.
|
|
65
|
+
// But once all compilation is done, the presence of this field
|
|
66
|
+
// really upsets Ajv.
|
|
67
|
+
delete jsonSchema.optionalField;
|
|
62
68
|
const ajvSchema = new AjvSchema(jsonSchema, cfg);
|
|
63
69
|
AjvSchema.cacheAjvSchema(schema, ajvSchema);
|
|
64
70
|
return ajvSchema;
|
|
@@ -91,7 +91,7 @@ export function createAjv(opt) {
|
|
|
91
91
|
});
|
|
92
92
|
ajv.addKeyword({
|
|
93
93
|
keyword: 'instanceof',
|
|
94
|
-
modifying:
|
|
94
|
+
modifying: false,
|
|
95
95
|
schemaType: 'string',
|
|
96
96
|
validate(instanceOf, data, _schema, _ctx) {
|
|
97
97
|
if (typeof data !== 'object')
|
|
@@ -354,6 +354,23 @@ export function createAjv(opt) {
|
|
|
354
354
|
keyword: 'hasIsOfTypeCheck',
|
|
355
355
|
schemaType: 'boolean',
|
|
356
356
|
});
|
|
357
|
+
ajv.addKeyword({
|
|
358
|
+
keyword: 'optionalValues',
|
|
359
|
+
type: ['string', 'number', 'boolean'],
|
|
360
|
+
modifying: true,
|
|
361
|
+
errors: false,
|
|
362
|
+
schemaType: 'array',
|
|
363
|
+
validate: function validate(optionalValues, data, _schema, ctx) {
|
|
364
|
+
if (!optionalValues)
|
|
365
|
+
return true;
|
|
366
|
+
if (!optionalValues.includes(data))
|
|
367
|
+
return true;
|
|
368
|
+
if (ctx?.parentData && ctx.parentDataProperty) {
|
|
369
|
+
ctx.parentData[ctx.parentDataProperty] = undefined;
|
|
370
|
+
}
|
|
371
|
+
return true;
|
|
372
|
+
},
|
|
373
|
+
});
|
|
357
374
|
return ajv;
|
|
358
375
|
}
|
|
359
376
|
const monthLengths = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
@@ -19,6 +19,9 @@ export declare const j: {
|
|
|
19
19
|
buffer(): JsonSchemaBufferBuilder;
|
|
20
20
|
enum<const T extends readonly (string | number | boolean | null)[] | StringEnum | NumberEnum>(input: T, opt?: JsonBuilderRuleOpt): JsonSchemaEnumBuilder<T extends readonly (infer U)[] ? U : T extends StringEnum ? T[keyof T] : T extends NumberEnum ? T[keyof T] : never>;
|
|
21
21
|
oneOf<B extends readonly JsonSchemaAnyBuilder<any, any, boolean>[], IN = BuilderInUnion<B>, OUT = BuilderOutUnion<B>>(items: [...B]): JsonSchemaAnyBuilder<IN, OUT, false>;
|
|
22
|
+
and(): {
|
|
23
|
+
silentBob: () => never;
|
|
24
|
+
};
|
|
22
25
|
};
|
|
23
26
|
export declare class JsonSchemaTerminal<IN, OUT, Opt> {
|
|
24
27
|
protected schema: JsonSchema;
|
|
@@ -73,8 +76,15 @@ export declare class JsonSchemaAnyBuilder<IN, OUT, Opt> extends JsonSchemaTermin
|
|
|
73
76
|
*/
|
|
74
77
|
final(): JsonSchemaTerminal<IN, OUT, Opt>;
|
|
75
78
|
}
|
|
76
|
-
export declare class JsonSchemaStringBuilder<IN extends string = string, OUT = IN, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
79
|
+
export declare class JsonSchemaStringBuilder<IN extends string | undefined = string, OUT = IN, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
77
80
|
constructor();
|
|
81
|
+
/**
|
|
82
|
+
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
83
|
+
*
|
|
84
|
+
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
85
|
+
* due to how mutability works in Ajv.
|
|
86
|
+
*/
|
|
87
|
+
optional(optionalValues?: string[]): JsonSchemaStringBuilder<IN | undefined, OUT | undefined, true>;
|
|
78
88
|
regex(pattern: RegExp, opt?: JsonBuilderRuleOpt): this;
|
|
79
89
|
pattern(pattern: string, opt?: JsonBuilderRuleOpt): this;
|
|
80
90
|
minLength(minLength: number): this;
|
|
@@ -134,8 +144,15 @@ export interface JsonSchemaIsoDateOptions {
|
|
|
134
144
|
after?: string;
|
|
135
145
|
sameOrAfter?: string;
|
|
136
146
|
}
|
|
137
|
-
export declare class JsonSchemaNumberBuilder<IN extends number = number, OUT = IN, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
147
|
+
export declare class JsonSchemaNumberBuilder<IN extends number | undefined = number, OUT = IN, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
138
148
|
constructor();
|
|
149
|
+
/**
|
|
150
|
+
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
151
|
+
*
|
|
152
|
+
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
153
|
+
* due to how mutability works in Ajv.
|
|
154
|
+
*/
|
|
155
|
+
optional(optionalValues?: number[]): JsonSchemaNumberBuilder<IN | undefined, OUT | undefined, true>;
|
|
139
156
|
integer(): this;
|
|
140
157
|
branded<B extends number>(): JsonSchemaNumberBuilder<B, B, Opt>;
|
|
141
158
|
multipleOf(multipleOf: number): this;
|
|
@@ -160,8 +177,15 @@ export declare class JsonSchemaNumberBuilder<IN extends number = number, OUT = I
|
|
|
160
177
|
utcOffset(): this;
|
|
161
178
|
utcOffsetHour(): this;
|
|
162
179
|
}
|
|
163
|
-
export declare class JsonSchemaBooleanBuilder<IN extends boolean = boolean, OUT = IN, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
180
|
+
export declare class JsonSchemaBooleanBuilder<IN extends boolean | undefined = boolean, OUT = IN, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
164
181
|
constructor();
|
|
182
|
+
/**
|
|
183
|
+
* @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
|
|
184
|
+
*
|
|
185
|
+
* This `optionalValue` feature only works when the current schema is nested in an object or array schema,
|
|
186
|
+
* due to how mutability works in Ajv.
|
|
187
|
+
*/
|
|
188
|
+
optional(optionalValue?: boolean): JsonSchemaBooleanBuilder<IN | undefined, OUT | undefined, true>;
|
|
165
189
|
}
|
|
166
190
|
export declare class JsonSchemaObjectBuilder<IN extends AnyObject, OUT extends AnyObject, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
167
191
|
constructor(props?: AnyObject, opt?: JsonSchemaObjectBuilderOpts);
|
|
@@ -276,6 +300,7 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
|
|
|
276
300
|
maxItems?: number;
|
|
277
301
|
uniqueItems?: boolean;
|
|
278
302
|
enum?: any;
|
|
303
|
+
hasIsOfTypeCheck?: boolean;
|
|
279
304
|
email?: JsonSchemaStringEmailOptions;
|
|
280
305
|
Set2?: JsonSchema;
|
|
281
306
|
Buffer?: true;
|
|
@@ -289,7 +314,7 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
|
|
|
289
314
|
truncate?: number;
|
|
290
315
|
};
|
|
291
316
|
errorMessages?: StringMap<string>;
|
|
292
|
-
|
|
317
|
+
optionalValues?: (string | number | boolean)[];
|
|
293
318
|
}
|
|
294
319
|
declare function object(props: AnyObject): never;
|
|
295
320
|
declare function object<IN extends AnyObject>(props: {
|
|
@@ -101,6 +101,13 @@ export const j = {
|
|
|
101
101
|
oneOf: schemas,
|
|
102
102
|
});
|
|
103
103
|
},
|
|
104
|
+
and() {
|
|
105
|
+
return {
|
|
106
|
+
silentBob: () => {
|
|
107
|
+
throw new Error('...strike back!');
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
},
|
|
104
111
|
};
|
|
105
112
|
const TS_2500 = 16725225600; // 2500-01-01
|
|
106
113
|
const TS_2500_MILLIS = TS_2500 * 1000;
|
|
@@ -227,6 +234,16 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
|
|
|
227
234
|
type: 'string',
|
|
228
235
|
});
|
|
229
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
239
|
+
*
|
|
240
|
+
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
241
|
+
* due to how mutability works in Ajv.
|
|
242
|
+
*/
|
|
243
|
+
optional(optionalValues) {
|
|
244
|
+
_objectAssign(this.schema, { optionalValues });
|
|
245
|
+
return super.optional();
|
|
246
|
+
}
|
|
230
247
|
regex(pattern, opt) {
|
|
231
248
|
return this.pattern(pattern.source, opt);
|
|
232
249
|
}
|
|
@@ -379,6 +396,16 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
|
|
|
379
396
|
type: 'number',
|
|
380
397
|
});
|
|
381
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
401
|
+
*
|
|
402
|
+
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
403
|
+
* due to how mutability works in Ajv.
|
|
404
|
+
*/
|
|
405
|
+
optional(optionalValues) {
|
|
406
|
+
_objectAssign(this.schema, { optionalValues });
|
|
407
|
+
return super.optional();
|
|
408
|
+
}
|
|
382
409
|
integer() {
|
|
383
410
|
_objectAssign(this.schema, { type: 'integer' });
|
|
384
411
|
return this;
|
|
@@ -477,6 +504,18 @@ export class JsonSchemaBooleanBuilder extends JsonSchemaAnyBuilder {
|
|
|
477
504
|
type: 'boolean',
|
|
478
505
|
});
|
|
479
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
|
|
509
|
+
*
|
|
510
|
+
* This `optionalValue` feature only works when the current schema is nested in an object or array schema,
|
|
511
|
+
* due to how mutability works in Ajv.
|
|
512
|
+
*/
|
|
513
|
+
optional(optionalValue) {
|
|
514
|
+
if (typeof optionalValue !== 'undefined') {
|
|
515
|
+
_objectAssign(this.schema, { optionalValues: [optionalValue] });
|
|
516
|
+
}
|
|
517
|
+
return super.optional();
|
|
518
|
+
}
|
|
480
519
|
}
|
|
481
520
|
export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
|
|
482
521
|
constructor(props, opt) {
|
package/package.json
CHANGED
|
@@ -79,6 +79,13 @@ export class AjvSchema<IN = unknown, OUT = IN> {
|
|
|
79
79
|
jsonSchema = schema
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// This is our own helper which marks a schema as optional
|
|
83
|
+
// in case it is going to be used in an object schema,
|
|
84
|
+
// where we need to mark the given property as not-required.
|
|
85
|
+
// But once all compilation is done, the presence of this field
|
|
86
|
+
// really upsets Ajv.
|
|
87
|
+
delete jsonSchema.optionalField
|
|
88
|
+
|
|
82
89
|
const ajvSchema = new AjvSchema<IN, OUT>(jsonSchema, cfg)
|
|
83
90
|
AjvSchema.cacheAjvSchema(schema, ajvSchema)
|
|
84
91
|
|
|
@@ -109,7 +109,7 @@ export function createAjv(opt?: Options): Ajv {
|
|
|
109
109
|
|
|
110
110
|
ajv.addKeyword({
|
|
111
111
|
keyword: 'instanceof',
|
|
112
|
-
modifying:
|
|
112
|
+
modifying: false,
|
|
113
113
|
schemaType: 'string',
|
|
114
114
|
validate(instanceOf: string, data: unknown, _schema, _ctx) {
|
|
115
115
|
if (typeof data !== 'object') return false
|
|
@@ -396,6 +396,30 @@ export function createAjv(opt?: Options): Ajv {
|
|
|
396
396
|
schemaType: 'boolean',
|
|
397
397
|
})
|
|
398
398
|
|
|
399
|
+
ajv.addKeyword({
|
|
400
|
+
keyword: 'optionalValues',
|
|
401
|
+
type: ['string', 'number', 'boolean'],
|
|
402
|
+
modifying: true,
|
|
403
|
+
errors: false,
|
|
404
|
+
schemaType: 'array',
|
|
405
|
+
validate: function validate(
|
|
406
|
+
optionalValues: (string | number | boolean)[],
|
|
407
|
+
data: string | number | boolean,
|
|
408
|
+
_schema,
|
|
409
|
+
ctx,
|
|
410
|
+
) {
|
|
411
|
+
if (!optionalValues) return true
|
|
412
|
+
|
|
413
|
+
if (!optionalValues.includes(data)) return true
|
|
414
|
+
|
|
415
|
+
if (ctx?.parentData && ctx.parentDataProperty) {
|
|
416
|
+
ctx.parentData[ctx.parentDataProperty] = undefined
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return true
|
|
420
|
+
},
|
|
421
|
+
})
|
|
422
|
+
|
|
399
423
|
return ajv
|
|
400
424
|
}
|
|
401
425
|
|
|
@@ -193,6 +193,14 @@ export const j = {
|
|
|
193
193
|
oneOf: schemas,
|
|
194
194
|
})
|
|
195
195
|
},
|
|
196
|
+
|
|
197
|
+
and() {
|
|
198
|
+
return {
|
|
199
|
+
silentBob: () => {
|
|
200
|
+
throw new Error('...strike back!')
|
|
201
|
+
},
|
|
202
|
+
}
|
|
203
|
+
},
|
|
196
204
|
}
|
|
197
205
|
|
|
198
206
|
const TS_2500 = 16725225600 // 2500-01-01
|
|
@@ -338,7 +346,7 @@ export class JsonSchemaAnyBuilder<IN, OUT, Opt> extends JsonSchemaTerminal<IN, O
|
|
|
338
346
|
}
|
|
339
347
|
|
|
340
348
|
export class JsonSchemaStringBuilder<
|
|
341
|
-
IN extends string = string,
|
|
349
|
+
IN extends string | undefined = string,
|
|
342
350
|
OUT = IN,
|
|
343
351
|
Opt extends boolean = false,
|
|
344
352
|
> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
@@ -348,6 +356,23 @@ export class JsonSchemaStringBuilder<
|
|
|
348
356
|
})
|
|
349
357
|
}
|
|
350
358
|
|
|
359
|
+
/**
|
|
360
|
+
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
361
|
+
*
|
|
362
|
+
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
363
|
+
* due to how mutability works in Ajv.
|
|
364
|
+
*/
|
|
365
|
+
override optional(
|
|
366
|
+
optionalValues?: string[],
|
|
367
|
+
): JsonSchemaStringBuilder<IN | undefined, OUT | undefined, true> {
|
|
368
|
+
_objectAssign(this.schema, { optionalValues })
|
|
369
|
+
return super.optional() as unknown as JsonSchemaStringBuilder<
|
|
370
|
+
IN | undefined,
|
|
371
|
+
OUT | undefined,
|
|
372
|
+
true
|
|
373
|
+
>
|
|
374
|
+
}
|
|
375
|
+
|
|
351
376
|
regex(pattern: RegExp, opt?: JsonBuilderRuleOpt): this {
|
|
352
377
|
return this.pattern(pattern.source, opt)
|
|
353
378
|
}
|
|
@@ -540,7 +565,7 @@ export interface JsonSchemaIsoDateOptions {
|
|
|
540
565
|
}
|
|
541
566
|
|
|
542
567
|
export class JsonSchemaNumberBuilder<
|
|
543
|
-
IN extends number = number,
|
|
568
|
+
IN extends number | undefined = number,
|
|
544
569
|
OUT = IN,
|
|
545
570
|
Opt extends boolean = false,
|
|
546
571
|
> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
@@ -550,6 +575,23 @@ export class JsonSchemaNumberBuilder<
|
|
|
550
575
|
})
|
|
551
576
|
}
|
|
552
577
|
|
|
578
|
+
/**
|
|
579
|
+
* @param optionalValues List of values that should be considered/converted as `undefined`.
|
|
580
|
+
*
|
|
581
|
+
* This `optionalValues` feature only works when the current schema is nested in an object or array schema,
|
|
582
|
+
* due to how mutability works in Ajv.
|
|
583
|
+
*/
|
|
584
|
+
override optional(
|
|
585
|
+
optionalValues?: number[],
|
|
586
|
+
): JsonSchemaNumberBuilder<IN | undefined, OUT | undefined, true> {
|
|
587
|
+
_objectAssign(this.schema, { optionalValues })
|
|
588
|
+
return super.optional() as unknown as JsonSchemaNumberBuilder<
|
|
589
|
+
IN | undefined,
|
|
590
|
+
OUT | undefined,
|
|
591
|
+
true
|
|
592
|
+
>
|
|
593
|
+
}
|
|
594
|
+
|
|
553
595
|
integer(): this {
|
|
554
596
|
_objectAssign(this.schema, { type: 'integer' })
|
|
555
597
|
return this
|
|
@@ -670,7 +712,7 @@ export class JsonSchemaNumberBuilder<
|
|
|
670
712
|
}
|
|
671
713
|
|
|
672
714
|
export class JsonSchemaBooleanBuilder<
|
|
673
|
-
IN extends boolean = boolean,
|
|
715
|
+
IN extends boolean | undefined = boolean,
|
|
674
716
|
OUT = IN,
|
|
675
717
|
Opt extends boolean = false,
|
|
676
718
|
> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
|
|
@@ -679,6 +721,26 @@ export class JsonSchemaBooleanBuilder<
|
|
|
679
721
|
type: 'boolean',
|
|
680
722
|
})
|
|
681
723
|
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* @param optionalValue One of the two possible boolean values that should be considered/converted as `undefined`.
|
|
727
|
+
*
|
|
728
|
+
* This `optionalValue` feature only works when the current schema is nested in an object or array schema,
|
|
729
|
+
* due to how mutability works in Ajv.
|
|
730
|
+
*/
|
|
731
|
+
override optional(
|
|
732
|
+
optionalValue?: boolean,
|
|
733
|
+
): JsonSchemaBooleanBuilder<IN | undefined, OUT | undefined, true> {
|
|
734
|
+
if (typeof optionalValue !== 'undefined') {
|
|
735
|
+
_objectAssign(this.schema, { optionalValues: [optionalValue] })
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
return super.optional() as unknown as JsonSchemaBooleanBuilder<
|
|
739
|
+
IN | undefined,
|
|
740
|
+
OUT | undefined,
|
|
741
|
+
true
|
|
742
|
+
>
|
|
743
|
+
}
|
|
682
744
|
}
|
|
683
745
|
|
|
684
746
|
export class JsonSchemaObjectBuilder<
|
|
@@ -1036,6 +1098,8 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
|
|
|
1036
1098
|
|
|
1037
1099
|
enum?: any
|
|
1038
1100
|
|
|
1101
|
+
hasIsOfTypeCheck?: boolean
|
|
1102
|
+
|
|
1039
1103
|
// Below we add custom Ajv keywords
|
|
1040
1104
|
|
|
1041
1105
|
email?: JsonSchemaStringEmailOptions
|
|
@@ -1046,7 +1110,7 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
|
|
|
1046
1110
|
instanceof?: string | string[]
|
|
1047
1111
|
transform?: { trim?: true; toLowerCase?: true; toUpperCase?: true; truncate?: number }
|
|
1048
1112
|
errorMessages?: StringMap<string>
|
|
1049
|
-
|
|
1113
|
+
optionalValues?: (string | number | boolean)[]
|
|
1050
1114
|
}
|
|
1051
1115
|
|
|
1052
1116
|
function object(props: AnyObject): never
|