@naturalcycles/nodejs-lib 15.76.0 → 15.77.1
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.
|
@@ -448,6 +448,35 @@ export function createAjv(opt) {
|
|
|
448
448
|
return isValid;
|
|
449
449
|
},
|
|
450
450
|
});
|
|
451
|
+
ajv.addKeyword({
|
|
452
|
+
keyword: 'exclusiveProperties',
|
|
453
|
+
type: 'object',
|
|
454
|
+
modifying: false,
|
|
455
|
+
errors: true,
|
|
456
|
+
schemaType: 'array',
|
|
457
|
+
validate: function validate(exclusiveProperties, data, _schema, ctx) {
|
|
458
|
+
if (typeof data !== 'object')
|
|
459
|
+
return true;
|
|
460
|
+
for (const props of exclusiveProperties) {
|
|
461
|
+
let numberOfDefinedProperties = 0;
|
|
462
|
+
for (const prop of props) {
|
|
463
|
+
if (data[prop] !== undefined)
|
|
464
|
+
numberOfDefinedProperties++;
|
|
465
|
+
if (numberOfDefinedProperties > 1) {
|
|
466
|
+
;
|
|
467
|
+
validate.errors = [
|
|
468
|
+
{
|
|
469
|
+
instancePath: ctx?.instancePath ?? '',
|
|
470
|
+
message: `must have only one of the "${props.join(', ')}" properties`,
|
|
471
|
+
},
|
|
472
|
+
];
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return true;
|
|
478
|
+
},
|
|
479
|
+
});
|
|
451
480
|
return ajv;
|
|
452
481
|
}
|
|
453
482
|
const monthLengths = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
@@ -248,15 +248,13 @@ export declare class JsonSchemaObjectBuilder<IN extends AnyObject, OUT extends A
|
|
|
248
248
|
* When set, the validation will not strip away properties that are not specified explicitly in the schema.
|
|
249
249
|
*/
|
|
250
250
|
allowAdditionalProperties(): this;
|
|
251
|
-
extend<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(props: P): JsonSchemaObjectBuilder<IN & {
|
|
252
|
-
[K in keyof P
|
|
253
|
-
} & {
|
|
254
|
-
[K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt> ? IsOpt extends true ? K : never : never]?: P[K] extends JsonSchemaAnyBuilder<infer IN2, any, any> ? IN2 : never;
|
|
255
|
-
}, OUT & {
|
|
251
|
+
extend<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(props: P): JsonSchemaObjectBuilder<RelaxIndexSignature<IN & {
|
|
252
|
+
[K in keyof P]?: P[K] extends JsonSchemaAnyBuilder<infer IN2, any, any> ? IN2 : never;
|
|
253
|
+
}>, AllowExtraKeys<RelaxIndexSignature<OUT & {
|
|
256
254
|
[K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt> ? IsOpt extends true ? never : K : never]: P[K] extends JsonSchemaAnyBuilder<any, infer OUT2, any> ? OUT2 : never;
|
|
257
255
|
} & {
|
|
258
256
|
[K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt> ? IsOpt extends true ? K : never : never]?: P[K] extends JsonSchemaAnyBuilder<any, infer OUT2, any> ? OUT2 : never;
|
|
259
|
-
}
|
|
257
|
+
}>>, false>;
|
|
260
258
|
/**
|
|
261
259
|
* Concatenates another schema to the current schema.
|
|
262
260
|
*
|
|
@@ -279,17 +277,18 @@ export declare class JsonSchemaObjectBuilder<IN extends AnyObject, OUT extends A
|
|
|
279
277
|
/**
|
|
280
278
|
* Extends the current schema with `id`, `created` and `updated` according to NC DB conventions.
|
|
281
279
|
*/
|
|
282
|
-
dbEntity(): JsonSchemaObjectBuilder<IN & {
|
|
280
|
+
dbEntity(): JsonSchemaObjectBuilder<RelaxIndexSignature<IN & {
|
|
281
|
+
id?: string | undefined;
|
|
282
|
+
created?: any;
|
|
283
|
+
updated?: any;
|
|
284
|
+
}>, AllowExtraKeys<RelaxIndexSignature<OUT & {
|
|
283
285
|
id: string;
|
|
284
286
|
created: any;
|
|
285
287
|
updated: any;
|
|
286
|
-
} & {}
|
|
287
|
-
id: string;
|
|
288
|
-
created: any;
|
|
289
|
-
updated: any;
|
|
290
|
-
} & {}, false>;
|
|
288
|
+
} & {}>>, false>;
|
|
291
289
|
minProperties(minProperties: number): this;
|
|
292
290
|
maxProperties(maxProperties: number): this;
|
|
291
|
+
exclusiveProperties(propNames: readonly (keyof IN & string)[]): this;
|
|
293
292
|
}
|
|
294
293
|
interface JsonSchemaObjectBuilderOpts {
|
|
295
294
|
hasIsOfTypeCheck?: false;
|
|
@@ -414,6 +413,7 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
|
|
|
414
413
|
optionalValues?: (string | number | boolean)[];
|
|
415
414
|
keySchema?: JsonSchema;
|
|
416
415
|
minProperties2?: number;
|
|
416
|
+
exclusiveProperties?: (readonly string[])[];
|
|
417
417
|
}
|
|
418
418
|
declare function object(props: AnyObject): never;
|
|
419
419
|
declare function object<IN extends AnyObject>(props: {
|
|
@@ -453,7 +453,22 @@ declare function withEnumKeys<const T extends readonly (string | number)[] | Str
|
|
|
453
453
|
type Expand<T> = {
|
|
454
454
|
[K in keyof T]: T[K];
|
|
455
455
|
};
|
|
456
|
-
type
|
|
456
|
+
type StripIndexSignatureDeep<T> = T extends readonly unknown[] ? T : T extends Record<string, any> ? {
|
|
457
|
+
[K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: StripIndexSignatureDeep<T[K]>;
|
|
458
|
+
} : T;
|
|
459
|
+
type RelaxIndexSignature<T> = T extends readonly unknown[] ? T : T extends AnyObject ? string extends keyof T ? any : {
|
|
460
|
+
[K in keyof T]: RelaxIndexSignature<T[K]>;
|
|
461
|
+
} : T;
|
|
462
|
+
declare const allowExtraKeysSymbol: unique symbol;
|
|
463
|
+
type AllowExtraKeys<T> = T & {
|
|
464
|
+
readonly [allowExtraKeysSymbol]?: true;
|
|
465
|
+
};
|
|
466
|
+
type HasAllowExtraKeys<T> = T extends {
|
|
467
|
+
readonly [allowExtraKeysSymbol]?: true;
|
|
468
|
+
} ? true : false;
|
|
469
|
+
type IsAssignableRelaxed<A, B> = [RelaxIndexSignature<A>] extends [B] ? true : false;
|
|
470
|
+
type ExactMatchBase<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? (<T>() => T extends B ? 1 : 2) extends <T>() => T extends A ? 1 : 2 ? true : false : false;
|
|
471
|
+
type ExactMatch<A, B> = HasAllowExtraKeys<B> extends true ? IsAssignableRelaxed<B, A> : ExactMatchBase<Expand<A>, Expand<B>> extends true ? true : ExactMatchBase<Expand<StripIndexSignatureDeep<A>>, Expand<StripIndexSignatureDeep<B>>>;
|
|
457
472
|
type BuilderOutUnion<B extends readonly JsonSchemaAnyBuilder<any, any, any>[]> = {
|
|
458
473
|
[K in keyof B]: B[K] extends JsonSchemaAnyBuilder<any, infer O, any> ? O : never;
|
|
459
474
|
}[number];
|
|
@@ -656,6 +656,10 @@ export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
|
|
|
656
656
|
maxProperties(maxProperties) {
|
|
657
657
|
return this.cloneAndUpdateSchema({ maxProperties });
|
|
658
658
|
}
|
|
659
|
+
exclusiveProperties(propNames) {
|
|
660
|
+
const exclusiveProperties = this.schema.exclusiveProperties ?? [];
|
|
661
|
+
return this.cloneAndUpdateSchema({ exclusiveProperties: [...exclusiveProperties, propNames] });
|
|
662
|
+
}
|
|
659
663
|
}
|
|
660
664
|
export class JsonSchemaObjectInferringBuilder extends JsonSchemaAnyBuilder {
|
|
661
665
|
constructor(props) {
|
package/package.json
CHANGED
|
@@ -513,6 +513,35 @@ export function createAjv(opt?: Options): Ajv2020 {
|
|
|
513
513
|
},
|
|
514
514
|
})
|
|
515
515
|
|
|
516
|
+
ajv.addKeyword({
|
|
517
|
+
keyword: 'exclusiveProperties',
|
|
518
|
+
type: 'object',
|
|
519
|
+
modifying: false,
|
|
520
|
+
errors: true,
|
|
521
|
+
schemaType: 'array',
|
|
522
|
+
validate: function validate(exclusiveProperties: string[][], data: AnyObject, _schema, ctx) {
|
|
523
|
+
if (typeof data !== 'object') return true
|
|
524
|
+
|
|
525
|
+
for (const props of exclusiveProperties) {
|
|
526
|
+
let numberOfDefinedProperties = 0
|
|
527
|
+
for (const prop of props) {
|
|
528
|
+
if (data[prop] !== undefined) numberOfDefinedProperties++
|
|
529
|
+
if (numberOfDefinedProperties > 1) {
|
|
530
|
+
;(validate as any).errors = [
|
|
531
|
+
{
|
|
532
|
+
instancePath: ctx?.instancePath ?? '',
|
|
533
|
+
message: `must have only one of the "${props.join(', ')}" properties`,
|
|
534
|
+
},
|
|
535
|
+
]
|
|
536
|
+
return false
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return true
|
|
542
|
+
},
|
|
543
|
+
})
|
|
544
|
+
|
|
516
545
|
return ajv
|
|
517
546
|
}
|
|
518
547
|
|
|
@@ -869,36 +869,30 @@ export class JsonSchemaObjectBuilder<
|
|
|
869
869
|
extend<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(
|
|
870
870
|
props: P,
|
|
871
871
|
): JsonSchemaObjectBuilder<
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
[K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt>
|
|
897
|
-
? IsOpt extends true
|
|
898
|
-
? K
|
|
899
|
-
: never
|
|
900
|
-
: never]?: P[K] extends JsonSchemaAnyBuilder<any, infer OUT2, any> ? OUT2 : never
|
|
901
|
-
},
|
|
872
|
+
RelaxIndexSignature<
|
|
873
|
+
IN & {
|
|
874
|
+
[K in keyof P]?: P[K] extends JsonSchemaAnyBuilder<infer IN2, any, any> ? IN2 : never
|
|
875
|
+
}
|
|
876
|
+
>,
|
|
877
|
+
AllowExtraKeys<
|
|
878
|
+
RelaxIndexSignature<
|
|
879
|
+
OUT & {
|
|
880
|
+
// required keys
|
|
881
|
+
[K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt>
|
|
882
|
+
? IsOpt extends true
|
|
883
|
+
? never
|
|
884
|
+
: K
|
|
885
|
+
: never]: P[K] extends JsonSchemaAnyBuilder<any, infer OUT2, any> ? OUT2 : never
|
|
886
|
+
} & {
|
|
887
|
+
// optional keys
|
|
888
|
+
[K in keyof P as P[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt>
|
|
889
|
+
? IsOpt extends true
|
|
890
|
+
? K
|
|
891
|
+
: never
|
|
892
|
+
: never]?: P[K] extends JsonSchemaAnyBuilder<any, infer OUT2, any> ? OUT2 : never
|
|
893
|
+
}
|
|
894
|
+
>
|
|
895
|
+
>,
|
|
902
896
|
false
|
|
903
897
|
> {
|
|
904
898
|
const newBuilder = new JsonSchemaObjectBuilder()
|
|
@@ -958,6 +952,11 @@ export class JsonSchemaObjectBuilder<
|
|
|
958
952
|
maxProperties(maxProperties: number): this {
|
|
959
953
|
return this.cloneAndUpdateSchema({ maxProperties })
|
|
960
954
|
}
|
|
955
|
+
|
|
956
|
+
exclusiveProperties(propNames: readonly (keyof IN & string)[]): this {
|
|
957
|
+
const exclusiveProperties = this.schema.exclusiveProperties ?? []
|
|
958
|
+
return this.cloneAndUpdateSchema({ exclusiveProperties: [...exclusiveProperties, propNames] })
|
|
959
|
+
}
|
|
961
960
|
}
|
|
962
961
|
|
|
963
962
|
interface JsonSchemaObjectBuilderOpts {
|
|
@@ -1272,6 +1271,7 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
|
|
|
1272
1271
|
optionalValues?: (string | number | boolean)[]
|
|
1273
1272
|
keySchema?: JsonSchema
|
|
1274
1273
|
minProperties2?: number
|
|
1274
|
+
exclusiveProperties?: (readonly string[])[]
|
|
1275
1275
|
}
|
|
1276
1276
|
|
|
1277
1277
|
function object(props: AnyObject): never
|
|
@@ -1439,13 +1439,50 @@ function withEnumKeys<
|
|
|
1439
1439
|
|
|
1440
1440
|
type Expand<T> = { [K in keyof T]: T[K] }
|
|
1441
1441
|
|
|
1442
|
-
type
|
|
1443
|
-
|
|
1444
|
-
|
|
1442
|
+
type StripIndexSignatureDeep<T> = T extends readonly unknown[]
|
|
1443
|
+
? T
|
|
1444
|
+
: T extends Record<string, any>
|
|
1445
|
+
? {
|
|
1446
|
+
[K in keyof T as string extends K
|
|
1447
|
+
? never
|
|
1448
|
+
: number extends K
|
|
1449
|
+
? never
|
|
1450
|
+
: symbol extends K
|
|
1451
|
+
? never
|
|
1452
|
+
: K]: StripIndexSignatureDeep<T[K]>
|
|
1453
|
+
}
|
|
1454
|
+
: T
|
|
1455
|
+
|
|
1456
|
+
type RelaxIndexSignature<T> = T extends readonly unknown[]
|
|
1457
|
+
? T
|
|
1458
|
+
: T extends AnyObject
|
|
1459
|
+
? string extends keyof T
|
|
1460
|
+
? any
|
|
1461
|
+
: { [K in keyof T]: RelaxIndexSignature<T[K]> }
|
|
1462
|
+
: T
|
|
1463
|
+
|
|
1464
|
+
declare const allowExtraKeysSymbol: unique symbol
|
|
1465
|
+
|
|
1466
|
+
type AllowExtraKeys<T> = T & { readonly [allowExtraKeysSymbol]?: true }
|
|
1467
|
+
|
|
1468
|
+
type HasAllowExtraKeys<T> = T extends { readonly [allowExtraKeysSymbol]?: true } ? true : false
|
|
1469
|
+
|
|
1470
|
+
type IsAssignableRelaxed<A, B> = [RelaxIndexSignature<A>] extends [B] ? true : false
|
|
1471
|
+
|
|
1472
|
+
type ExactMatchBase<A, B> =
|
|
1473
|
+
(<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2
|
|
1474
|
+
? (<T>() => T extends B ? 1 : 2) extends <T>() => T extends A ? 1 : 2
|
|
1445
1475
|
? true
|
|
1446
1476
|
: false
|
|
1447
1477
|
: false
|
|
1448
1478
|
|
|
1479
|
+
type ExactMatch<A, B> =
|
|
1480
|
+
HasAllowExtraKeys<B> extends true
|
|
1481
|
+
? IsAssignableRelaxed<B, A>
|
|
1482
|
+
: ExactMatchBase<Expand<A>, Expand<B>> extends true
|
|
1483
|
+
? true
|
|
1484
|
+
: ExactMatchBase<Expand<StripIndexSignatureDeep<A>>, Expand<StripIndexSignatureDeep<B>>>
|
|
1485
|
+
|
|
1449
1486
|
type BuilderOutUnion<B extends readonly JsonSchemaAnyBuilder<any, any, any>[]> = {
|
|
1450
1487
|
[K in keyof B]: B[K] extends JsonSchemaAnyBuilder<any, infer O, any> ? O : never
|
|
1451
1488
|
}[number]
|