badmfck-api-server 3.9.5 → 3.9.7

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.
@@ -93,7 +93,7 @@ async function Initializer(services) {
93
93
  }
94
94
  exports.Initializer = Initializer;
95
95
  class APIService extends BaseService_1.BaseService {
96
- version = "3.9.5";
96
+ version = "3.9.7";
97
97
  options;
98
98
  monitor = null;
99
99
  started = new Date();
@@ -1,9 +1,3 @@
1
- type SyncOptions = {
2
- fillOnlyWhenNull?: boolean;
3
- resetOnTypeMismatch?: boolean;
4
- repairArrayItems?: "coerce";
5
- coerceArrayFromObject?: "values" | "numericKeys" | "wrap" | "off";
6
- };
7
1
  export type TValidatorType = "string" | "number" | "boolean" | "date" | "array" | "object" | "email" | "phone";
8
2
  export interface IStructureOptions {
9
3
  optional?: boolean;
@@ -39,9 +33,9 @@ type WidenLiteral<T> = T extends string ? string : T extends number ? number : T
39
33
  type WidenLiterals<T> = {
40
34
  [K in keyof T]: T[K] extends readonly (infer R)[] ? readonly WidenLiteral<R>[] : T[K] extends (infer R)[] ? WidenLiteral<R>[] : T[K] extends object ? WidenLiterals<T[K]> : WidenLiteral<T[K]>;
41
35
  };
42
- type DeepMutable<T> = {
43
- -readonly [K in keyof T]: T[K] extends object ? T[K] extends (...args: any[]) => any ? T[K] : DeepMutable<T[K]> : T[K];
44
- };
36
+ type DeepMutable<T> = T extends ReadonlyArray<infer U> ? DeepMutable<U>[] : T extends Array<infer U> ? DeepMutable<U>[] : T extends (...args: any[]) => any ? T : T extends object ? {
37
+ -readonly [K in keyof T]: DeepMutable<T[K]>;
38
+ } : T;
45
39
  type IsNever<T> = [T] extends [never] ? true : false;
46
40
  type Or<A, B> = A extends true ? true : (B extends true ? true : false);
47
41
  type CleanFields<T> = WidenLiterals<{
@@ -62,7 +56,7 @@ type ExtractEnumValues<T> = {
62
56
  };
63
57
  type EnumFieldNames<T> = keyof ExtractEnumValues<T> & string;
64
58
  type EnumFieldValues<T> = ExtractEnumValues<T>;
65
- type ProcessField<F, Meta> = F extends readonly (infer Item)[] ? Item extends object ? ValidationModel<Item>[] : F : F extends (infer Item)[] ? Item extends object ? ValidationModel<Item>[] : F : F extends object ? ValidationModel<F> : F;
59
+ type ProcessField<F, Meta> = F extends ReadonlyArray<infer Item> ? Item extends object ? ValidationModel<Item>[] : WidenLiteral<Item>[] : F extends Array<infer Item> ? Item extends object ? ValidationModel<Item>[] : WidenLiteral<Item>[] : F extends object ? ValidationModel<F> : WidenLiteral<F>;
66
60
  export type ValidationModel<T> = DeepMutable<{
67
61
  [K in keyof CleanFields<T> as K extends OptionalFields<T> ? K : never]?: K extends EnumFieldNames<T> ? EnumFieldValues<T>[K] : ProcessField<CleanFields<T>[K], T>;
68
62
  } & {
@@ -76,7 +70,7 @@ export declare class Validator {
76
70
  static filterStructure(structure: any, object: any): void;
77
71
  static isPlainObject(v: any): boolean;
78
72
  static clone<T>(v: T): T;
79
- static syncStructure(structure: any, object: any, opts?: SyncOptions): any;
73
+ static syncStructure(structure: any, node: any): any;
80
74
  static convertToType<T>(value: any, type: "string" | "number" | "boolean" | "date"): T | null;
81
75
  static validateValue(value: string | number | boolean, opt?: IValidatorOptions): ValidationReport;
82
76
  }
@@ -301,114 +301,85 @@ class Validator {
301
301
  return structuredClone(v);
302
302
  return JSON.parse(JSON.stringify(v));
303
303
  }
304
- static syncStructure(structure, object, opts = {
305
- fillOnlyWhenNull: true,
306
- resetOnTypeMismatch: true,
307
- repairArrayItems: "coerce",
308
- coerceArrayFromObject: "values"
309
- }) {
304
+ static syncStructure(structure, node) {
310
305
  if (structure === null || typeof structure !== "object")
311
- return object;
306
+ return node;
312
307
  if (Array.isArray(structure)) {
313
308
  const tmpl = structure[0];
314
- if (!Array.isArray(object) && this.isPlainObject(object)) {
315
- const mode = opts.coerceArrayFromObject ?? "values";
316
- if (mode === "numericKeys") {
317
- const numeric = Object.keys(object).filter(k => String(+k) === k).map(k => +k).sort((a, b) => a - b);
318
- object = numeric.map(i => object[String(i)]);
319
- }
320
- else if (mode === "wrap" && this.isPlainObject(tmpl)) {
321
- object = [object];
322
- }
323
- else if (mode === "values") {
324
- object = Object.values(object);
325
- }
326
- else {
327
- return object;
328
- }
309
+ if (!Array.isArray(node) && this.isPlainObject(node)) {
310
+ const numericKeys = Object.keys(node)
311
+ .filter((k) => String(+k) === k)
312
+ .map((k) => +k)
313
+ .sort((a, b) => a - b);
314
+ const items = numericKeys.length > 0
315
+ ? numericKeys.map((i) => node[String(i)])
316
+ : Object.values(node);
317
+ node = items.map((it) => this.syncStructure(tmpl, it));
318
+ return node;
329
319
  }
330
- if (!Array.isArray(object))
331
- return object;
320
+ if (!Array.isArray(node))
321
+ return node;
332
322
  if (tmpl !== undefined) {
333
- for (let i = 0; i < object.length; i++) {
334
- let item = object[i];
323
+ for (let i = 0; i < node.length; i++) {
324
+ const item = node[i];
335
325
  if (item === null || item === undefined) {
336
- object[i] = this.clone(tmpl);
337
- this.syncStructure(tmpl, object[i], opts);
326
+ node[i] = this.clone(tmpl);
327
+ node[i] = this.syncStructure(tmpl, node[i]);
338
328
  continue;
339
329
  }
340
330
  if (this.isPlainObject(tmpl) && this.isPlainObject(item)) {
341
- this.syncStructure(tmpl, item, opts);
331
+ node[i] = this.syncStructure(tmpl, item);
342
332
  continue;
343
333
  }
344
334
  if (Array.isArray(tmpl) && Array.isArray(item)) {
345
- this.syncStructure(tmpl, item, opts);
335
+ node[i] = this.syncStructure(tmpl, item);
346
336
  continue;
347
337
  }
348
- if (opts.repairArrayItems === "coerce") {
349
- object[i] = this.clone(tmpl);
350
- this.syncStructure(tmpl, object[i], opts);
351
- }
338
+ node[i] = this.clone(tmpl);
339
+ node[i] = this.syncStructure(tmpl, node[i]);
352
340
  }
353
341
  }
354
- return object;
342
+ return node;
355
343
  }
356
- if (!this.isPlainObject(object))
357
- return object;
358
- for (const key in object) {
359
- if (!(key in structure))
360
- delete object[key];
344
+ if (!this.isPlainObject(node))
345
+ return node;
346
+ for (const k of Object.keys(node)) {
347
+ if (!(k in structure))
348
+ delete node[k];
361
349
  }
362
- for (const key in structure) {
363
- const structureValue = structure[key];
364
- const hasKey = Object.prototype.hasOwnProperty.call(object, key);
365
- const { optional = false, skip_validation = false } = (Validator.parseStructureOptions(key, structure) || {});
366
- const objectValue = object[key];
367
- if (!hasKey) {
368
- object[key] = this.clone(structureValue);
350
+ for (const k of Object.keys(structure)) {
351
+ const sv = structure[k];
352
+ if (k.startsWith("$__")) {
353
+ node[k] = this.clone(sv);
369
354
  continue;
370
355
  }
371
- if (key.startsWith("$__")) {
372
- object[key] = this.clone(structureValue);
373
- continue;
374
- }
375
- if ((objectValue === null || objectValue === undefined) && structureValue !== null) {
376
- if (!optional || skip_validation) {
377
- object[key] = this.clone(structureValue);
378
- }
356
+ const has = Object.prototype.hasOwnProperty.call(node, k);
357
+ const ov = has ? node[k] : undefined;
358
+ if (!has) {
359
+ node[k] = this.clone(sv);
360
+ if (sv && typeof sv === "object")
361
+ node[k] = this.syncStructure(sv, node[k]);
379
362
  continue;
380
363
  }
381
- const svIsObj = this.isPlainObject(structureValue);
382
- const ovIsObj = this.isPlainObject(objectValue);
383
- const svIsArr = Array.isArray(structureValue);
384
- const ovIsArr = Array.isArray(objectValue);
385
- if (svIsObj || svIsArr) {
386
- if ((svIsObj && !ovIsObj) || (svIsArr && !ovIsArr)) {
387
- if (opts.resetOnTypeMismatch && svIsObj) {
388
- const base = this.clone(structureValue);
389
- if (this.isPlainObject(objectValue)) {
390
- for (const k in objectValue)
391
- base[k] = objectValue[k];
392
- this.syncStructure(structureValue, base, opts);
393
- object[key] = base;
394
- }
395
- else {
396
- object[key] = base;
397
- }
398
- }
364
+ const { optional, default: def } = this.parseStructureOptions(k, structure);
365
+ if (ov === null || ov === undefined) {
366
+ if (def !== undefined && !optional) {
367
+ node[k] = this.clone(def);
368
+ continue;
399
369
  }
400
- else {
401
- this.syncStructure(structureValue, objectValue, opts);
370
+ if (!optional) {
371
+ node[k] = this.clone(sv);
372
+ if (sv && typeof sv === "object")
373
+ node[k] = this.syncStructure(sv, node[k]);
374
+ continue;
402
375
  }
403
- continue;
404
376
  }
405
- if (typeof objectValue !== typeof structureValue) {
406
- if (opts.resetOnTypeMismatch) {
407
- object[key] = this.clone(structureValue);
408
- }
377
+ if (sv && typeof sv === "object") {
378
+ node[k] = this.syncStructure(sv, ov);
379
+ continue;
409
380
  }
410
381
  }
411
- return object;
382
+ return node;
412
383
  }
413
384
  static convertToType(value, type) {
414
385
  if (value === null || value === undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "3.9.5",
3
+ "version": "3.9.7",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",