@naturalcycles/nodejs-lib 15.40.0 → 15.41.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.
@@ -4,7 +4,8 @@ export declare const j: {
4
4
  string(): JsonSchemaStringBuilder<string, string, false>;
5
5
  number(): JsonSchemaNumberBuilder<number, number, false>;
6
6
  boolean(): JsonSchemaBooleanBuilder<boolean, boolean, false>;
7
- object<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(props: P): JsonSchemaObjectBuilder<P, false>;
7
+ object: typeof object;
8
+ objectInfer<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(props: P): JsonSchemaObjectInferringBuilder<P, false>;
8
9
  array<IN, OUT, Opt>(itemSchema: JsonSchemaAnyBuilder<IN, OUT, Opt>): JsonSchemaArrayBuilder<IN, OUT, Opt>;
9
10
  set<IN, OUT, Opt>(itemSchema: JsonSchemaAnyBuilder<IN, OUT, Opt>): JsonSchemaSet2Builder<IN, OUT, Opt>;
10
11
  buffer(): JsonSchemaBufferBuilder;
@@ -118,7 +119,20 @@ export declare class JsonSchemaNumberBuilder<IN extends number = number, OUT = I
118
119
  export declare class JsonSchemaBooleanBuilder<IN extends boolean = boolean, OUT = IN, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
119
120
  constructor();
120
121
  }
121
- export declare class JsonSchemaObjectBuilder<PROPS extends Record<string, JsonSchemaAnyBuilder<any, any, any>>, Opt extends boolean = false> extends JsonSchemaAnyBuilder<Expand<{
122
+ export declare class JsonSchemaObjectBuilder<IN extends AnyObject, OUT extends AnyObject, Opt extends boolean = false> extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
123
+ constructor(props?: AnyObject);
124
+ addProperties(props: AnyObject): this;
125
+ /**
126
+ * When set, the validation will not strip away properties that are not specified explicitly in the schema.
127
+ */
128
+ allowAdditionalProperties(): this;
129
+ extend<IN2 extends AnyObject>(props: AnyObject): JsonSchemaObjectBuilder<IN & IN2, OUT & IN2, Opt>;
130
+ /**
131
+ * Extends the current schema with `id`, `created` and `updated` according to NC DB conventions.
132
+ */
133
+ dbEntity(): JsonSchemaObjectBuilder<any, any, Opt>;
134
+ }
135
+ export declare class JsonSchemaObjectInferringBuilder<PROPS extends Record<string, JsonSchemaAnyBuilder<any, any, any>>, Opt extends boolean = false> extends JsonSchemaAnyBuilder<Expand<{
122
136
  [K in keyof PROPS as PROPS[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt> ? IsOpt extends true ? never : K : never]: PROPS[K] extends JsonSchemaAnyBuilder<infer IN, any, any> ? IN : never;
123
137
  } & {
124
138
  [K in keyof PROPS as PROPS[K] extends JsonSchemaAnyBuilder<any, any, infer IsOpt> ? IsOpt extends true ? K : never : never]?: PROPS[K] extends JsonSchemaAnyBuilder<infer IN, any, any> ? IN : never;
@@ -133,13 +147,13 @@ export declare class JsonSchemaObjectBuilder<PROPS extends Record<string, JsonSc
133
147
  * When set, the validation will not strip away properties that are not specified explicitly in the schema.
134
148
  */
135
149
  allowAdditionalProperties(): this;
136
- extend<NEW_PROPS extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(props: NEW_PROPS): JsonSchemaObjectBuilder<{
150
+ extend<NEW_PROPS extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(props: NEW_PROPS): JsonSchemaObjectInferringBuilder<{
137
151
  [K in keyof PROPS | keyof NEW_PROPS]: K extends keyof NEW_PROPS ? NEW_PROPS[K] : K extends keyof PROPS ? PROPS[K] : never;
138
152
  }, Opt>;
139
153
  /**
140
154
  * Extends the current schema with `id`, `created` and `updated` according to NC DB conventions.
141
155
  */
142
- dbEntity(): JsonSchemaObjectBuilder<{ [K in keyof PROPS | "id" | "created" | "updated"]: K extends "id" | "created" | "updated" ? {
156
+ dbEntity(): JsonSchemaObjectInferringBuilder<{ [K in keyof PROPS | "id" | "created" | "updated"]: K extends "id" | "created" | "updated" ? {
143
157
  id: JsonSchemaStringBuilder<string, string, false>;
144
158
  created: JsonSchemaNumberBuilder<UnixTimestamp, UnixTimestamp, false>;
145
159
  updated: JsonSchemaNumberBuilder<UnixTimestamp, UnixTimestamp, false>;
@@ -218,6 +232,10 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
218
232
  errorMessages?: StringMap<string>;
219
233
  hasIsOfTypeCheck?: boolean;
220
234
  }
235
+ declare function object(props: AnyObject): never;
236
+ declare function object<IN extends AnyObject>(props: {
237
+ [key in keyof IN]: JsonSchemaAnyBuilder<any, IN[key], any>;
238
+ }): JsonSchemaObjectBuilder<IN, IN, false>;
221
239
  type Expand<T> = T extends infer O ? {
222
240
  [K in keyof O]: O[K];
223
241
  } : never;
@@ -16,8 +16,9 @@ export const j = {
16
16
  boolean() {
17
17
  return new JsonSchemaBooleanBuilder();
18
18
  },
19
- object(props) {
20
- return new JsonSchemaObjectBuilder(props);
19
+ object,
20
+ objectInfer(props) {
21
+ return new JsonSchemaObjectInferringBuilder(props);
21
22
  },
22
23
  array(itemSchema) {
23
24
  return new JsonSchemaArrayBuilder(itemSchema);
@@ -370,6 +371,7 @@ export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
370
371
  properties: {},
371
372
  required: [],
372
373
  additionalProperties: false,
374
+ hasIsOfTypeCheck: true,
373
375
  });
374
376
  if (props)
375
377
  this.addProperties(props);
@@ -417,6 +419,60 @@ export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
417
419
  });
418
420
  }
419
421
  }
422
+ export class JsonSchemaObjectInferringBuilder extends JsonSchemaAnyBuilder {
423
+ constructor(props) {
424
+ super({
425
+ type: 'object',
426
+ properties: {},
427
+ required: [],
428
+ additionalProperties: false,
429
+ });
430
+ if (props)
431
+ this.addProperties(props);
432
+ }
433
+ addProperties(props) {
434
+ const properties = {};
435
+ const required = [];
436
+ for (const [key, builder] of Object.entries(props)) {
437
+ const schema = builder.build();
438
+ if (!schema.optionalField) {
439
+ required.push(key);
440
+ }
441
+ else {
442
+ schema.optionalField = undefined;
443
+ }
444
+ properties[key] = schema;
445
+ }
446
+ this.schema.properties = properties;
447
+ this.schema.required = _uniq(required).sort();
448
+ return this;
449
+ }
450
+ /**
451
+ * When set, the validation will not strip away properties that are not specified explicitly in the schema.
452
+ */
453
+ allowAdditionalProperties() {
454
+ Object.assign(this.schema, { additionalProperties: true });
455
+ return this;
456
+ }
457
+ extend(props) {
458
+ const newBuilder = new JsonSchemaObjectInferringBuilder();
459
+ Object.assign(newBuilder.schema, _deepCopy(this.schema));
460
+ const incomingSchemaBuilder = new JsonSchemaObjectInferringBuilder(props);
461
+ mergeJsonSchemaObjects(newBuilder.schema, incomingSchemaBuilder.schema);
462
+ return newBuilder;
463
+ }
464
+ /**
465
+ * Extends the current schema with `id`, `created` and `updated` according to NC DB conventions.
466
+ */
467
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types
468
+ dbEntity() {
469
+ return this.extend({
470
+ id: j.string(),
471
+ created: j.number().unixTimestamp2000(),
472
+ updated: j.number().unixTimestamp2000(),
473
+ });
474
+ }
475
+ }
420
476
  export class JsonSchemaArrayBuilder extends JsonSchemaAnyBuilder {
421
477
  constructor(itemsSchema) {
422
478
  super({
@@ -465,3 +521,6 @@ export class JsonSchemaEnumBuilder extends JsonSchemaAnyBuilder {
465
521
  super({ enum: enumValues });
466
522
  }
467
523
  }
524
+ function object(props) {
525
+ return new JsonSchemaObjectBuilder(props);
526
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.40.0",
4
+ "version": "15.41.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@types/js-yaml": "^4",
@@ -37,10 +37,12 @@ export const j = {
37
37
  return new JsonSchemaBooleanBuilder()
38
38
  },
39
39
 
40
- object<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(
40
+ object,
41
+
42
+ objectInfer<P extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(
41
43
  props: P,
42
- ): JsonSchemaObjectBuilder<P, false> {
43
- return new JsonSchemaObjectBuilder<P, false>(props)
44
+ ): JsonSchemaObjectInferringBuilder<P, false> {
45
+ return new JsonSchemaObjectInferringBuilder<P, false>(props)
44
46
  },
45
47
 
46
48
  array<IN, OUT, Opt>(
@@ -497,6 +499,76 @@ export class JsonSchemaBooleanBuilder<
497
499
  }
498
500
 
499
501
  export class JsonSchemaObjectBuilder<
502
+ IN extends AnyObject,
503
+ OUT extends AnyObject,
504
+ Opt extends boolean = false,
505
+ > extends JsonSchemaAnyBuilder<IN, OUT, Opt> {
506
+ constructor(props?: AnyObject) {
507
+ super({
508
+ type: 'object',
509
+ properties: {},
510
+ required: [],
511
+ additionalProperties: false,
512
+ hasIsOfTypeCheck: true,
513
+ })
514
+
515
+ if (props) this.addProperties(props)
516
+ }
517
+
518
+ addProperties(props: AnyObject): this {
519
+ const properties: Record<string, JsonSchema> = {}
520
+ const required: string[] = []
521
+
522
+ for (const [key, builder] of Object.entries(props)) {
523
+ const schema = builder.build()
524
+ if (!schema.optionalField) {
525
+ required.push(key)
526
+ } else {
527
+ schema.optionalField = undefined
528
+ }
529
+ properties[key] = schema
530
+ }
531
+
532
+ this.schema.properties = properties
533
+ this.schema.required = _uniq(required).sort()
534
+
535
+ return this
536
+ }
537
+
538
+ /**
539
+ * When set, the validation will not strip away properties that are not specified explicitly in the schema.
540
+ */
541
+ allowAdditionalProperties(): this {
542
+ Object.assign(this.schema, { additionalProperties: true })
543
+ return this
544
+ }
545
+
546
+ extend<IN2 extends AnyObject>(
547
+ props: AnyObject,
548
+ ): JsonSchemaObjectBuilder<IN & IN2, OUT & IN2, Opt> {
549
+ const newBuilder = new JsonSchemaObjectBuilder<IN & IN2, OUT & IN2, Opt>()
550
+ Object.assign(newBuilder.schema, _deepCopy(this.schema))
551
+
552
+ const incomingSchemaBuilder = new JsonSchemaObjectBuilder<IN2, IN2, false>(props)
553
+ mergeJsonSchemaObjects(newBuilder.schema as any, incomingSchemaBuilder.schema as any)
554
+
555
+ return newBuilder
556
+ }
557
+
558
+ /**
559
+ * Extends the current schema with `id`, `created` and `updated` according to NC DB conventions.
560
+ */
561
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types
562
+ dbEntity() {
563
+ return this.extend({
564
+ id: j.string(),
565
+ created: j.number().unixTimestamp2000(),
566
+ updated: j.number().unixTimestamp2000(),
567
+ })
568
+ }
569
+ }
570
+
571
+ export class JsonSchemaObjectInferringBuilder<
500
572
  PROPS extends Record<string, JsonSchemaAnyBuilder<any, any, any>>,
501
573
  Opt extends boolean = false,
502
574
  > extends JsonSchemaAnyBuilder<
@@ -573,7 +645,7 @@ export class JsonSchemaObjectBuilder<
573
645
 
574
646
  extend<NEW_PROPS extends Record<string, JsonSchemaAnyBuilder<any, any, any>>>(
575
647
  props: NEW_PROPS,
576
- ): JsonSchemaObjectBuilder<
648
+ ): JsonSchemaObjectInferringBuilder<
577
649
  {
578
650
  [K in keyof PROPS | keyof NEW_PROPS]: K extends keyof NEW_PROPS
579
651
  ? NEW_PROPS[K]
@@ -583,13 +655,13 @@ export class JsonSchemaObjectBuilder<
583
655
  },
584
656
  Opt
585
657
  > {
586
- const newBuilder = new JsonSchemaObjectBuilder<PROPS, Opt>()
658
+ const newBuilder = new JsonSchemaObjectInferringBuilder<PROPS, Opt>()
587
659
  Object.assign(newBuilder.schema, _deepCopy(this.schema))
588
660
 
589
- const incomingSchemaBuilder = new JsonSchemaObjectBuilder<NEW_PROPS, false>(props)
661
+ const incomingSchemaBuilder = new JsonSchemaObjectInferringBuilder<NEW_PROPS, false>(props)
590
662
  mergeJsonSchemaObjects(newBuilder.schema as any, incomingSchemaBuilder.schema as any)
591
663
 
592
- return newBuilder as JsonSchemaObjectBuilder<
664
+ return newBuilder as JsonSchemaObjectInferringBuilder<
593
665
  {
594
666
  [K in keyof PROPS | keyof NEW_PROPS]: K extends keyof NEW_PROPS
595
667
  ? NEW_PROPS[K]
@@ -750,6 +822,17 @@ export interface JsonSchema<IN = unknown, OUT = IN> {
750
822
  hasIsOfTypeCheck?: boolean
751
823
  }
752
824
 
825
+ function object(props: AnyObject): never
826
+ function object<IN extends AnyObject>(props: {
827
+ [key in keyof IN]: JsonSchemaAnyBuilder<any, IN[key], any>
828
+ }): JsonSchemaObjectBuilder<IN, IN, false>
829
+
830
+ function object<IN extends AnyObject>(props: {
831
+ [key in keyof IN]: JsonSchemaAnyBuilder<any, IN[key], any>
832
+ }): JsonSchemaObjectBuilder<IN, IN, false> {
833
+ return new JsonSchemaObjectBuilder<IN, IN, false>(props)
834
+ }
835
+
753
836
  type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
754
837
 
755
838
  type ExactMatch<A, B> =