badmfck-api-server 3.8.8 → 3.9.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.
@@ -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.8.8";
96
+ version = "3.9.0";
97
97
  options;
98
98
  monitor = null;
99
99
  started = new Date();
@@ -242,7 +242,6 @@ class MysqlAdapter {
242
242
  }
243
243
  if (this.options.debug)
244
244
  (0, LogService_1.logDB)("Commit transaction:", trx.id);
245
- this.transactions = this.transactions.filter(i => i.id !== trxid);
246
245
  if (this.options.debug)
247
246
  (0, LogService_1.logDB)("Transaction pool:", this.transactions);
248
247
  const err = await this.commit(trx);
@@ -439,6 +438,9 @@ class MysqlAdapter {
439
438
  };
440
439
  }
441
440
  }
441
+ let trx = null;
442
+ if (request.transactionID)
443
+ trx = this.transactions.find(i => i.id === request.transactionID);
442
444
  try {
443
445
  let result = null;
444
446
  if (this.options.maxQueryTimeout && this.options.maxQueryTimeout > 0)
@@ -448,6 +450,8 @@ class MysqlAdapter {
448
450
  this.lastSuccessQueryTime = +new Date();
449
451
  if (!request.transactionID && doCloseConnection)
450
452
  this.finalizeConnection(conn);
453
+ if (trx)
454
+ trx.queries.push({ sql: query, status: "ok" });
451
455
  return {
452
456
  data: result[0],
453
457
  error: null,
@@ -458,11 +462,6 @@ class MysqlAdapter {
458
462
  };
459
463
  }
460
464
  catch (e) {
461
- if (request.transactionID) {
462
- const trx = this.transactions.find(i => i.id === request.transactionID);
463
- if (trx)
464
- this.storeTransactionAsProblem(trx, query);
465
- }
466
465
  if (!request.transactionID && doCloseConnection)
467
466
  this.finalizeConnection(conn);
468
467
  else if (request.transactionID && request.throwable) {
@@ -474,10 +473,14 @@ class MysqlAdapter {
474
473
  this.finalizeConnection(conn);
475
474
  }
476
475
  const error = this.createMysqlQueryError(e);
476
+ if (trx)
477
+ trx.queries.push({ sql: query, status: error.code });
477
478
  if (`${e}`.indexOf('ECONNREFUSED') !== -1 || `${e}`.indexOf("PROTOCOL_") !== -1 || error.message.includes("closed state")) {
478
479
  (0, LogService_1.logError)("Connection looks dead, recreating pool 1");
479
480
  this.recreatePool();
480
481
  }
482
+ if (trx)
483
+ this.storeTransactionAsProblem(trx, "error:" + error.errno);
481
484
  if (request.throwable)
482
485
  throw { ...DefaultErrors_1.default.DB_ERROR, details: error.message, stack: error };
483
486
  return {
@@ -641,10 +644,14 @@ class MysqlAdapter {
641
644
  await trx.conn.commit();
642
645
  trx.conn.removeAllListeners();
643
646
  trx.conn.release();
647
+ const trxIndex = this.transactions.indexOf(trx);
648
+ this.transactions.splice(trxIndex, 1);
644
649
  }
645
650
  catch (e) {
651
+ const err = this.createMysqlQueryError(e);
652
+ trx.queries.push({ sql: "COMMIT", status: err.code });
646
653
  await this.rollbackTransaction(trx);
647
- return this.createMysqlQueryError(e);
654
+ return err;
648
655
  }
649
656
  return null;
650
657
  }
@@ -660,12 +667,13 @@ class MysqlAdapter {
660
667
  this.transactions = this.transactions.filter(i => trx && i && i.id !== trx.id);
661
668
  if (this.options.debug)
662
669
  (0, LogService_1.logDB)("Rollback complete", trx.conn.threadId);
670
+ trx.queries.push({ sql: "ROLLBACK", status: "ok" });
663
671
  }
664
672
  catch (e) {
665
673
  (0, LogService_1.logCrit)("MysqlAdapter", "Can't rollback transaction", trx.queries);
666
674
  err = this.createMysqlQueryError(e);
675
+ trx.queries.push({ sql: "ROLLBACK", status: "fail" });
667
676
  }
668
- this.storeTransactionAsProblem(trx, "rollback");
669
677
  return err;
670
678
  }
671
679
  async finish() {
@@ -1,4 +1,14 @@
1
1
  export type TValidatorType = "string" | "number" | "boolean" | "date" | "array" | "object" | "email" | "phone";
2
+ export interface IStructureOptions {
3
+ optional?: boolean;
4
+ skip_validation?: boolean;
5
+ default?: any;
6
+ values?: any;
7
+ regex?: string;
8
+ min?: number;
9
+ max?: number;
10
+ details?: string;
11
+ }
2
12
  export interface IValidatorOptions {
3
13
  min?: number;
4
14
  max?: number;
@@ -47,6 +57,7 @@ export type ValidationModel<T> = DeepMutable<{
47
57
  export declare class Validator {
48
58
  static validateObject(fields: string[], object: any): boolean;
49
59
  static documentStructure(structure: any): Record<string, any> | undefined;
60
+ static parseStructureOptions(key: string, structure: Record<string, any>): IStructureOptions;
50
61
  static validateStructure(structure: any, object: any, level?: number, parentPath?: string): Promise<string[] | undefined>;
51
62
  static filterStructure(structure: any, object: any): void;
52
63
  static syncStructure(structure: any, object: any): any;
@@ -60,6 +60,33 @@ class Validator {
60
60
  }
61
61
  return params;
62
62
  }
63
+ static parseStructureOptions(key, structure) {
64
+ let k = '$__' + key;
65
+ let s_options = structure[k];
66
+ if (s_options === null)
67
+ s_options = {};
68
+ if (typeof s_options === "string")
69
+ s_options = { details: s_options };
70
+ k = k + "_";
71
+ if (s_options.min == undefined || isNaN(s_options.min)) {
72
+ if (structure[key + "min"] && !isNaN(structure[key + "min"]))
73
+ s_options.min = parseInt(structure[key + "min"]);
74
+ }
75
+ if (s_options.min && isNaN(s_options.min))
76
+ s_options.min = undefined;
77
+ if (s_options.max == undefined || isNaN(s_options.max)) {
78
+ if (structure[key + "max"] && !isNaN(structure[key + "max"]))
79
+ s_options.min = parseInt(structure[key + "max"]);
80
+ }
81
+ if (s_options.max && isNaN(s_options.max))
82
+ s_options.max = undefined;
83
+ return {
84
+ ...s_options,
85
+ optional: s_options.optional === undefined ? structure[k + 'optional'] ?? false : s_options.optional,
86
+ default: s_options.default === undefined ? structure[k + 'default'] ?? undefined : s_options.default,
87
+ regex: s_options.regex === undefined ? structure[k + 'regex'] ?? undefined : s_options.regex,
88
+ };
89
+ }
63
90
  static async validateStructure(structure, object, level = 0, parentPath = "") {
64
91
  if (!structure)
65
92
  return;
@@ -91,13 +118,21 @@ class Validator {
91
118
  foundKeys.push(i);
92
119
  continue;
93
120
  }
94
- let optional = structure['$__' + i + "_optional"] || false;
95
- if (!(i in object)) {
96
- if (structure["$__" + i + "_default"]) {
97
- object[i] = structure["$__" + i + "_default"];
121
+ let structureOptions = Validator.parseStructureOptions(i, structure);
122
+ if (structureOptions.skip_validation) {
123
+ foundKeys.push(i);
124
+ continue;
125
+ }
126
+ if ((object[i] === null || object[i] === undefined || !(i in object)) && structure[i] !== null && structure[i] !== undefined) {
127
+ if (structureOptions.default) {
128
+ object[i] = structureOptions.default;
98
129
  }
99
130
  else {
100
- if (!optional) {
131
+ if (structureOptions.optional) {
132
+ foundKeys.push(i);
133
+ continue;
134
+ }
135
+ else {
101
136
  if (Array.isArray(object) && !isNaN(parseInt(`${i}`))) {
102
137
  const p = parentPath.length > 0 ? parentPath.slice(0, -1) : parentPath;
103
138
  errors.push("no item for '" + p + "[" + i + "]'");
@@ -107,19 +142,17 @@ class Validator {
107
142
  }
108
143
  continue;
109
144
  }
110
- else {
111
- foundKeys.push(i);
112
- continue;
113
- }
114
145
  }
115
146
  }
116
- if (object[i] === null || object[i] === undefined) {
117
- if (!optional)
118
- errors.push("no value for field '" + parentPath + i + "'");
119
- else {
147
+ if ((object[i] === null || object[i] === undefined)) {
148
+ if (structure[i] === null || structure[i] === undefined) {
120
149
  foundKeys.push(i);
121
150
  continue;
122
151
  }
152
+ else {
153
+ errors.push("no field '" + parentPath + i + "'");
154
+ continue;
155
+ }
123
156
  }
124
157
  if (typeof structure[i] === "number" && typeof object[i] === "string") {
125
158
  let num = parseInt(object[i]);
@@ -159,25 +192,23 @@ class Validator {
159
192
  errors.push("wrong value for field '" + parentPath + i + "', expected " + expected.join(", ") + " got: " + value);
160
193
  }
161
194
  }
162
- if (structure['$__' + i + "_values"]) {
163
- const values = structure['$__' + i + "_values"];
164
- if (Array.isArray(values) && values.length) {
165
- if (!values.includes(object[i])) {
166
- let caseValue = null;
167
- for (let i of values) {
168
- const v = i.toLowerCase();
169
- if (v === (object[i] + "").toLowerCase()) {
170
- caseValue = object[i];
171
- break;
172
- }
195
+ if (structure['$__' + i + "_values"])
196
+ structureOptions.values = structure['$__' + i + "_values"];
197
+ if (Array.isArray(structureOptions.values) && structureOptions.values.length) {
198
+ if (!structureOptions.values.includes(object[i])) {
199
+ let caseValue = null;
200
+ for (let i of structureOptions.values) {
201
+ const v = i.toLowerCase();
202
+ if (v === (object[i] + "").toLowerCase()) {
203
+ caseValue = object[i];
204
+ break;
173
205
  }
174
- errors.push("wrong value for field '" + parentPath + i + "'" + (caseValue ? ", check case for: " + caseValue : ""));
175
206
  }
207
+ errors.push("wrong value for field '" + parentPath + i + "'" + (caseValue ? ", check case for: " + caseValue : ""));
176
208
  }
177
209
  }
178
- if (typeof structure[i] === "string" && structure["$__" + i + "_regex"]) {
179
- const regex = structure["$__" + i + "_regex"];
180
- const reg = new RegExp(regex);
210
+ if (typeof structure[i] === "string" && structureOptions.regex) {
211
+ const reg = new RegExp(structureOptions.regex);
181
212
  if (reg.test(object[i]) === false)
182
213
  errors.push("wrong value for field '" + parentPath + i + "', false mask for: >" + object[i] + "<");
183
214
  }
@@ -215,25 +246,21 @@ class Validator {
215
246
  }
216
247
  }
217
248
  }
218
- if (typeof structure[i] === "number" && structure["$__" + i + "_min"]) {
219
- const min = structure["$__" + i + "_min"];
220
- if (object[i] < min)
221
- errors.push("value for field '" + parentPath + i + "' is too small, expected more than " + min + " got: " + object[i]);
249
+ if (typeof structure[i] === "number" && structureOptions.min && !isNaN(structureOptions.min)) {
250
+ if (object[i] < structureOptions.min)
251
+ errors.push("value for field '" + parentPath + i + "' is too small, expected more than " + structureOptions.min + " got: " + object[i]);
222
252
  }
223
- if (typeof structure[i] === "number" && structure["$__" + i + "_max"]) {
224
- const max = structure["$__" + i + "_max"];
225
- if (object[i] > max)
226
- errors.push("value for field '" + parentPath + i + "' is too big, expected less than " + max + " got: " + object[i]);
253
+ if (typeof structure[i] === "number" && structureOptions.max && !isNaN(structureOptions.max)) {
254
+ if (object[i] > structureOptions.max)
255
+ errors.push("value for field '" + parentPath + i + "' is too big, expected less than " + structureOptions.max + " got: " + object[i]);
227
256
  }
228
- if (typeof object[i] === "string" && structure["$__" + i + "_min"]) {
229
- const min = structure["$__" + i + "_min"];
230
- if (object[i].length < min)
231
- errors.push("value length for field '" + parentPath + i + "' is too small, expected more than " + min + " got: " + object[i].length);
257
+ if (typeof object[i] === "string" && structureOptions.min && !isNaN(structureOptions.min)) {
258
+ if (object[i].length < structureOptions.min)
259
+ errors.push("value length for field '" + parentPath + i + "' is too small, expected more than " + structureOptions.min + " got: " + object[i].length);
232
260
  }
233
- if (typeof object[i] === "string" && structure["$__" + i + "_max"]) {
234
- const max = structure["$__" + i + "_max"];
235
- if (object[i].length > max)
236
- errors.push("value length for field '" + parentPath + i + "' is too big, expected less than " + max + " got: " + object[i].length);
261
+ if (typeof object[i] === "string" && structureOptions.max && !isNaN(structureOptions.max)) {
262
+ if (object[i].length > structureOptions.max)
263
+ errors.push("value length for field '" + parentPath + i + "' is too big, expected less than " + structureOptions.max + " got: " + object[i].length);
237
264
  }
238
265
  foundKeys.push(i);
239
266
  }
@@ -281,10 +308,16 @@ class Validator {
281
308
  object[key] = structureValue;
282
309
  continue;
283
310
  }
311
+ const options = Validator.parseStructureOptions(key, structure);
284
312
  if (objectValue === null && structureValue !== null) {
285
- if (!structure["$__" + key + "_optional"])
313
+ if (!options.optional) {
286
314
  object[key] = structureValue;
287
- continue;
315
+ continue;
316
+ }
317
+ if (!options.skip_validation) {
318
+ object[key] = structureValue;
319
+ continue;
320
+ }
288
321
  }
289
322
  if (key.startsWith("$__")) {
290
323
  object[key] = structure[key];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "3.8.8",
3
+ "version": "3.9.0",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",