badmfck-api-server 3.0.1 → 3.0.3

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.
@@ -43,10 +43,10 @@ const os_1 = __importDefault(require("os"));
43
43
  const Liveness_1 = require("./routes/Liveness");
44
44
  const Readiness_1 = require("./routes/Readiness");
45
45
  const http_1 = __importDefault(require("http"));
46
- const MysqlService_1 = require("./MysqlService");
47
46
  const StatService_1 = require("./StatService");
48
47
  const ExternalServiceEndpoint_1 = require("./external/ExternalServiceEndpoint");
49
48
  const MonitorService_1 = require("./MonitorService");
49
+ const MysqlAdapter_1 = require("./db/MysqlAdapter");
50
50
  function getDefaultOptions() {
51
51
  return {
52
52
  port: 8091,
@@ -57,7 +57,7 @@ function getDefaultOptions() {
57
57
  endpoints: [],
58
58
  jsonLimit: "10mb",
59
59
  onNetworkLog: function (log) {
60
- (0, LogService_1.logInfo)("${APIService.js}", log);
60
+ (0, LogService_1.logAPI)("${APIService.js}", log);
61
61
  },
62
62
  onError: function (err) {
63
63
  (0, LogService_1.logError)("${APIService.js}", err);
@@ -89,7 +89,7 @@ async function Initializer(services) {
89
89
  exports.Initializer = Initializer;
90
90
  class APIService extends BaseService_1.BaseService {
91
91
  static nextLogID = 0;
92
- version = "3.0.1";
92
+ version = "3.0.3";
93
93
  options;
94
94
  monitor = null;
95
95
  monitorIndexFile;
@@ -252,8 +252,10 @@ class APIService extends BaseService_1.BaseService {
252
252
  details = e.message;
253
253
  stack = [e];
254
254
  }
255
- if ((0, MysqlService_1.isMysqlError)(e))
256
- details = e.message;
255
+ if ((0, MysqlAdapter_1.isError)(e)) {
256
+ this.sendResponse(req.get("Referer") ?? "", res, { error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message } }, tme, ep, log, httpRequest);
257
+ return;
258
+ }
257
259
  this.sendResponse(req.get("Referer") ?? "", res, { error: { code: 10002, message: "Internal server error", stack: stack, details: details }, data: null, httpStatus: 500 }, tme, ep, log, httpRequest);
258
260
  return;
259
261
  }
@@ -308,6 +310,11 @@ class APIService extends BaseService_1.BaseService {
308
310
  };
309
311
  if (DefaultErrors_1.ErrorUtils.isError(e))
310
312
  data = { error: e };
313
+ if ((0, MysqlAdapter_1.isError)(e)) {
314
+ data = {
315
+ error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message }
316
+ };
317
+ }
311
318
  this.sendResponse(req.get("Referer") ?? "", res, data, tme, ep, log, httpRequest);
312
319
  return;
313
320
  }
@@ -21,16 +21,17 @@ export interface IDBQuery {
21
21
  calculateCount?: boolean;
22
22
  parseQueryOnly?: boolean;
23
23
  }
24
+ export interface IDBBulkQueryItem {
25
+ query: string;
26
+ fields: {
27
+ [key: string]: IDBQueryField | null | string | number | boolean;
28
+ };
29
+ throwable?: boolean;
30
+ calculateCount?: boolean;
31
+ }
24
32
  export interface IDBBulkQuery {
25
33
  dbid?: string;
26
- bulk: {
27
- query: string;
28
- fields: {
29
- [key: string]: IDBQueryField | null | string | number | boolean;
30
- };
31
- throwable?: boolean;
32
- calculateCount?: boolean;
33
- }[];
34
+ bulk: IDBBulkQueryItem[];
34
35
  queued?: boolean;
35
36
  }
36
37
  export interface IDBError {
@@ -65,12 +66,24 @@ export interface DBAdapterOptions {
65
66
  }
66
67
  export declare const REQ_DB: Req<IDBQuery, IDBResult>;
67
68
  export declare const REQ_DBX: Req<IDBBulkQuery, IDBResult[]>;
69
+ export declare const REQ_DB_TBEGIN: Req<{
70
+ dbid: string;
71
+ }, IDBResult>;
72
+ export declare const REQ_DB_TCOMMIT: Req<{
73
+ dbid: string;
74
+ trxid: number;
75
+ }, IDBResult>;
76
+ export declare const REQ_DB_TROLLBACK: Req<{
77
+ dbid: string;
78
+ trxid: number;
79
+ }, IDBResult>;
68
80
  export declare class DBService extends BaseService {
69
81
  static allInstances: DBService[];
70
82
  options: IDBSericeOptions;
71
83
  adapter: IDBAdapter | null;
72
84
  constructor(options: IDBSericeOptions);
73
85
  init(): Promise<void>;
86
+ getAdapter(dbid?: string | null): IDBAdapter | IDBError;
74
87
  finishService(): Promise<void>;
75
88
  createMysqlDatabase(): Promise<void>;
76
89
  }
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DBService = exports.REQ_DBX = exports.REQ_DB = void 0;
3
+ exports.DBService = exports.REQ_DB_TROLLBACK = exports.REQ_DB_TCOMMIT = exports.REQ_DB_TBEGIN = exports.REQ_DBX = exports.REQ_DB = void 0;
4
4
  const badmfck_signal_1 = require("badmfck-signal");
5
5
  const BaseService_1 = require("./BaseService");
6
6
  const MysqlAdapter_1 = require("./db/MysqlAdapter");
7
7
  exports.REQ_DB = new badmfck_signal_1.Req(undefined, "REQ_DB");
8
8
  exports.REQ_DBX = new badmfck_signal_1.Req(undefined, "REQ_DBX");
9
+ exports.REQ_DB_TBEGIN = new badmfck_signal_1.Req(undefined, "REQ_DB_TBEGIN");
10
+ exports.REQ_DB_TCOMMIT = new badmfck_signal_1.Req(undefined, "REQ_DB_TBEGIN");
11
+ exports.REQ_DB_TROLLBACK = new badmfck_signal_1.Req(undefined, "REQ_DB_TBEGIN");
9
12
  class DBService extends BaseService_1.BaseService {
10
13
  static allInstances = [];
11
14
  options;
@@ -49,6 +52,66 @@ class DBService extends BaseService_1.BaseService {
49
52
  }
50
53
  return result;
51
54
  };
55
+ exports.REQ_DB_TBEGIN.listener = async (req) => {
56
+ const adapter = this.getAdapter(req.dbid);
57
+ if ("errno" in adapter) {
58
+ return {
59
+ error: adapter
60
+ };
61
+ }
62
+ if (adapter.tBegin && typeof adapter.tBegin === "function")
63
+ return await adapter.tBegin();
64
+ return {
65
+ error: {
66
+ errno: -10,
67
+ code: "TRX_NOT_SUPPORTED",
68
+ fatal: true,
69
+ sql: "START TRANSACTION",
70
+ name: "TRX_NOT_SUPPORTED",
71
+ message: "Transactions not supported on selected adapter"
72
+ }
73
+ };
74
+ };
75
+ exports.REQ_DB_TCOMMIT.listener = async (req) => {
76
+ const adapter = this.getAdapter(req.dbid);
77
+ if ("errno" in adapter) {
78
+ return {
79
+ error: adapter
80
+ };
81
+ }
82
+ if (adapter.tCommit && typeof adapter.tCommit === "function")
83
+ return await adapter.tCommit(req.trxid);
84
+ return {
85
+ error: {
86
+ errno: -10,
87
+ code: "TRX_NOT_SUPPORTED",
88
+ fatal: true,
89
+ sql: "COMMIT",
90
+ name: "TRX_NOT_SUPPORTED",
91
+ message: "Transactions not supported on selected adapter"
92
+ }
93
+ };
94
+ };
95
+ exports.REQ_DB_TROLLBACK.listener = async (req) => {
96
+ const adapter = this.getAdapter(req.dbid);
97
+ if ("errno" in adapter) {
98
+ return {
99
+ error: adapter
100
+ };
101
+ }
102
+ if (adapter.tRollback && typeof adapter.tRollback === "function")
103
+ return await adapter.tRollback(req.trxid);
104
+ return {
105
+ error: {
106
+ errno: -10,
107
+ code: "TRX_NOT_SUPPORTED",
108
+ fatal: true,
109
+ sql: "ROLLBACK",
110
+ name: "TRX_NOT_SUPPORTED",
111
+ message: "Transactions not supported on selected adapter"
112
+ }
113
+ };
114
+ };
52
115
  exports.REQ_DB.listener = async (req) => {
53
116
  if (!req.dbid && DBService.allInstances.length === 1 && DBService.allInstances[0].adapter)
54
117
  return DBService.allInstances[0].adapter.query(req);
@@ -69,6 +132,23 @@ class DBService extends BaseService_1.BaseService {
69
132
  return { error: error };
70
133
  };
71
134
  }
135
+ getAdapter(dbid) {
136
+ if (!dbid && DBService.allInstances.length === 1 && DBService.allInstances[0].adapter)
137
+ return DBService.allInstances[0].adapter;
138
+ for (let i of DBService.allInstances) {
139
+ if (i.options.id === dbid && i.adapter)
140
+ return i.adapter;
141
+ }
142
+ const error = {
143
+ code: "DB_NOT_FOUND",
144
+ errno: -1,
145
+ fatal: true,
146
+ sql: "",
147
+ name: "DB_NOT_FOUND",
148
+ message: "DB not found: " + dbid
149
+ };
150
+ return error;
151
+ }
72
152
  async finishService() {
73
153
  await this.adapter?.finish();
74
154
  }
@@ -1,11 +1,13 @@
1
1
  import Signal, { Req } from "badmfck-signal";
2
2
  import { BaseService } from "./BaseService";
3
3
  export declare enum LOG_LEVEL {
4
- ALL = 0,
5
- INFO = 1,
6
- WARN = 2,
7
- ERROR = 3,
8
- CRIT = 4
4
+ ALL = 10,
5
+ API = 19,
6
+ INFO = 20,
7
+ DB = 25,
8
+ WARN = 30,
9
+ ERROR = 40,
10
+ CRIT = 50
9
11
  }
10
12
  export interface ILogItem {
11
13
  id: number;
@@ -27,6 +29,8 @@ export declare const logInfo: (message: any, ...optional: any[]) => void;
27
29
  export declare const logWarn: (message: any, ...optional: any[]) => void;
28
30
  export declare const logCrit: (message: any, ...optional: any[]) => void;
29
31
  export declare const logError: (message: any, ...optional: any[]) => void;
32
+ export declare const logDB: (message: any, ...optional: any[]) => void;
33
+ export declare const logAPI: (message: any, ...optional: any[]) => void;
30
34
  export declare const S_LOG: Signal<{
31
35
  level: LOG_LEVEL;
32
36
  data: any[];
@@ -23,16 +23,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.LogService = exports.REQ_LOG_UNIQUE_SERVICES = exports.REQ_LOG = exports.S_LOG_SET_TEXT_LIMIT = exports.S_LOG_REMOVE_SERVICE_FROM_WATCH = exports.S_LOG_ADD_SERVICE_TO_WATCH = exports.S_LOG_FLUSH = exports.S_LOG_CHANGE_LEVEL = exports.S_LOG_CREATED = exports.S_LOG = exports.logError = exports.logCrit = exports.logWarn = exports.logInfo = exports.getDefaultLogOptions = exports.LOG_LEVEL = void 0;
26
+ exports.LogService = exports.REQ_LOG_UNIQUE_SERVICES = exports.REQ_LOG = exports.S_LOG_SET_TEXT_LIMIT = exports.S_LOG_REMOVE_SERVICE_FROM_WATCH = exports.S_LOG_ADD_SERVICE_TO_WATCH = exports.S_LOG_FLUSH = exports.S_LOG_CHANGE_LEVEL = exports.S_LOG_CREATED = exports.S_LOG = exports.logAPI = exports.logDB = exports.logError = exports.logCrit = exports.logWarn = exports.logInfo = exports.getDefaultLogOptions = exports.LOG_LEVEL = void 0;
27
27
  const badmfck_signal_1 = __importStar(require("badmfck-signal"));
28
28
  const BaseService_1 = require("./BaseService");
29
29
  var LOG_LEVEL;
30
30
  (function (LOG_LEVEL) {
31
- LOG_LEVEL[LOG_LEVEL["ALL"] = 0] = "ALL";
32
- LOG_LEVEL[LOG_LEVEL["INFO"] = 1] = "INFO";
33
- LOG_LEVEL[LOG_LEVEL["WARN"] = 2] = "WARN";
34
- LOG_LEVEL[LOG_LEVEL["ERROR"] = 3] = "ERROR";
35
- LOG_LEVEL[LOG_LEVEL["CRIT"] = 4] = "CRIT";
31
+ LOG_LEVEL[LOG_LEVEL["ALL"] = 10] = "ALL";
32
+ LOG_LEVEL[LOG_LEVEL["API"] = 19] = "API";
33
+ LOG_LEVEL[LOG_LEVEL["INFO"] = 20] = "INFO";
34
+ LOG_LEVEL[LOG_LEVEL["DB"] = 25] = "DB";
35
+ LOG_LEVEL[LOG_LEVEL["WARN"] = 30] = "WARN";
36
+ LOG_LEVEL[LOG_LEVEL["ERROR"] = 40] = "ERROR";
37
+ LOG_LEVEL[LOG_LEVEL["CRIT"] = 50] = "CRIT";
36
38
  })(LOG_LEVEL || (exports.LOG_LEVEL = LOG_LEVEL = {}));
37
39
  const getDefaultLogOptions = () => {
38
40
  return {
@@ -50,6 +52,10 @@ const logCrit = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LE
50
52
  exports.logCrit = logCrit;
51
53
  const logError = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.ERROR, data: [message, optional] }); };
52
54
  exports.logError = logError;
55
+ const logDB = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.DB, data: [message, optional] }); };
56
+ exports.logDB = logDB;
57
+ const logAPI = (message, ...optional) => { exports.S_LOG.invoke({ level: LOG_LEVEL.API, data: [message, optional] }); };
58
+ exports.logAPI = logAPI;
53
59
  exports.S_LOG = new badmfck_signal_1.default();
54
60
  exports.S_LOG_CREATED = new badmfck_signal_1.default();
55
61
  exports.S_LOG_CHANGE_LEVEL = new badmfck_signal_1.default();
@@ -2,6 +2,9 @@ import { IDBBulkQuery, IDBQuery, IDBResult } from "../DBService";
2
2
  export interface IDBAdapter {
3
3
  init(): Promise<void>;
4
4
  finish(): Promise<void>;
5
+ tBegin?(): Promise<IDBResult>;
6
+ tCommit?(trxid: number): Promise<IDBResult>;
7
+ tRollback?(trxid: number): Promise<IDBResult>;
5
8
  prepareQuery(request: IDBQuery): string;
6
9
  query(request: IDBQuery): Promise<IDBResult>;
7
10
  bulk(request: IDBBulkQuery): Promise<IDBResult[]>;
@@ -34,6 +34,9 @@ export declare class MysqlAdapter implements IDBAdapter {
34
34
  init(): Promise<void>;
35
35
  setupTimers(): void;
36
36
  recreatePool(): Promise<boolean>;
37
+ tBegin(): Promise<IDBResult>;
38
+ tCommit(trxid: number): Promise<IDBResult>;
39
+ tRollback(trxid: number): Promise<IDBResult>;
37
40
  bulk(request: IDBBulkQuery): Promise<IDBResult[]>;
38
41
  getConnection(transactionId?: number): Promise<mysql.PoolConnection | IDBError>;
39
42
  query(request: IDBQuery, conn?: mysql.PoolConnection): Promise<IDBResult>;
@@ -46,6 +49,6 @@ export declare class MysqlAdapter implements IDBAdapter {
46
49
  finish(): Promise<void>;
47
50
  createMysqlQueryError(err: any, throwable?: boolean): IDBError;
48
51
  storeTransactionAsProblem(trx: ITransaction, message: string): Promise<void>;
49
- isError(obj: any): obj is IDBError;
50
52
  }
53
+ export declare function isError(obj: any): obj is IDBError;
51
54
  export {};
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MysqlAdapter = void 0;
6
+ exports.isError = exports.MysqlAdapter = void 0;
7
7
  const promise_1 = __importDefault(require("mysql2/promise"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const LogService_1 = require("../LogService");
@@ -107,7 +107,7 @@ class MysqlAdapter {
107
107
  keepAliveInitialDelay: 3 * 1000,
108
108
  idleTimeout: 1000 * 60 * 5
109
109
  };
110
- (0, LogService_1.logInfo)("${MysqlAdapter.js}", "Connecting to mysql: \n " + JSON.stringify({ ...opt, password: "****" }, null, "\t"));
110
+ (0, LogService_1.logDB)("${MysqlAdapter.js}", "Connecting to mysql: \n " + JSON.stringify({ ...opt, password: "****" }, null, "\t"));
111
111
  if (this.pool) {
112
112
  this.pool.removeAllListeners();
113
113
  try {
@@ -129,21 +129,21 @@ class MysqlAdapter {
129
129
  this.acquiredPoolConnections = 0;
130
130
  this.pool?.on('connection', (connection) => {
131
131
  if (this.options.debug)
132
- (0, LogService_1.logInfo)("MysqlAdapter", "pool -> connection created, total:" + this.poolConnections++);
132
+ (0, LogService_1.logDB)("MysqlAdapter", "pool -> connection created, total:" + this.poolConnections++);
133
133
  });
134
134
  this.pool?.on('acquire', (connection) => {
135
135
  this.acquiredPoolConnections++;
136
136
  if (this.options.debug)
137
- (0, LogService_1.logInfo)("MysqlAdapter", "pool -> connection acquire, busy:" + this.acquiredPoolConnections);
137
+ (0, LogService_1.logDB)("MysqlAdapter", "pool -> connection acquire, busy:" + this.acquiredPoolConnections);
138
138
  });
139
139
  this.pool?.on('release', (connection) => {
140
140
  this.acquiredPoolConnections--;
141
141
  if (this.options.debug)
142
- (0, LogService_1.logInfo)("MysqlAdapter", "pool -> connection release, busy:" + this.acquiredPoolConnections);
142
+ (0, LogService_1.logDB)("MysqlAdapter", "pool -> connection release, busy:" + this.acquiredPoolConnections);
143
143
  });
144
144
  this.pool?.on('enqueue', () => {
145
145
  if (this.options.debug)
146
- (0, LogService_1.logInfo)("MysqlAdapter", "pool -> waiting for available connection");
146
+ (0, LogService_1.logDB)("MysqlAdapter", "pool -> waiting for available connection");
147
147
  });
148
148
  if (this.options.debug)
149
149
  console.log("Check mysql connection");
@@ -154,13 +154,92 @@ class MysqlAdapter {
154
154
  }
155
155
  return true;
156
156
  }
157
+ async tBegin() {
158
+ const conn = await this.getConnection();
159
+ if (isError(conn))
160
+ return { error: conn };
161
+ for (let i of this.transactions) {
162
+ if (i.conn === conn) {
163
+ (0, LogService_1.logError)("Selected connection is in transaction");
164
+ return {
165
+ error: {
166
+ errno: 100005,
167
+ code: "CONN_IN_TRX",
168
+ fatal: true,
169
+ sql: "START TRANSACTION",
170
+ name: "CONN_IN_TRX",
171
+ message: "Selected connection already in transaction"
172
+ }
173
+ };
174
+ }
175
+ }
176
+ const trxid = MysqlAdapter.nextTransactionID++;
177
+ if (this.options.debug)
178
+ (0, LogService_1.logDB)("Begin transaction with id ", trxid);
179
+ const result = await this.query({ query: "START TRANSACTIONS" }, conn);
180
+ const trxRequest = {
181
+ id: trxid,
182
+ timestamp: Date.now(),
183
+ conn: conn,
184
+ queries: []
185
+ };
186
+ if (result.error) {
187
+ trxRequest.queries.push({ sql: "START TRANSACTION", status: "error" });
188
+ this.rollbackTransaction(trxRequest);
189
+ return result;
190
+ }
191
+ trxRequest.queries.push({ sql: "START TRANSACTION", status: "ok" });
192
+ this.transactions.push(trxRequest);
193
+ if (this.options.debug)
194
+ console.log("Transactions pool: ", this.transactions);
195
+ return { data: { transactionId: trxid } };
196
+ }
197
+ async tCommit(trxid) {
198
+ const trx = this.transactions.find(i => i.id === trxid);
199
+ if (!trx) {
200
+ return {
201
+ error: {
202
+ code: "NO_TRX",
203
+ errno: 100004,
204
+ fatal: true,
205
+ sql: "",
206
+ name: "NO_TRX",
207
+ message: "Transaction not found",
208
+ }
209
+ };
210
+ }
211
+ if (this.options.debug)
212
+ (0, LogService_1.logDB)("Commit transaction:", trx.id);
213
+ this.transactions = this.transactions.filter(i => i.id !== trxid);
214
+ if (this.options.debug)
215
+ (0, LogService_1.logDB)("Transaction pool:", this.transactions);
216
+ const err = await this.commit(trx);
217
+ if (err)
218
+ return { error: err };
219
+ return { data: true };
220
+ }
221
+ async tRollback(trxid) {
222
+ const trx = this.transactions.find(i => i.id === trxid);
223
+ if (!trx) {
224
+ return { error: {
225
+ code: "NO_TRX",
226
+ errno: 100004,
227
+ fatal: true,
228
+ sql: "",
229
+ name: "NO_TRX",
230
+ message: "Transaction not found"
231
+ } };
232
+ }
233
+ await this.rollbackTransaction(trx);
234
+ return { data: true };
235
+ }
157
236
  async bulk(request) {
158
237
  const results = [];
159
238
  let queries = [];
160
239
  let conn = null;
161
240
  if (request.queued) {
162
241
  conn = await this.getConnection();
163
- if (this.isError(conn)) {
242
+ if (isError(conn)) {
164
243
  for (let i of request.bulk)
165
244
  results.push({ data: null, error: conn });
166
245
  return results;
@@ -210,15 +289,15 @@ class MysqlAdapter {
210
289
  if (transactionId && transactionId > 0) {
211
290
  conn = this.transactions.find(i => i.id === transactionId)?.conn ?? null;
212
291
  if (this.options.debug)
213
- console.log("Execute query on transaction: ", conn?.threadId);
292
+ (0, LogService_1.logDB)("Execute query on transaction: ", conn?.threadId);
214
293
  }
215
294
  else
216
295
  conn = await this.pool.getConnection();
217
296
  if (this.options.debug) {
218
- console.log("Pool status: ", this.poolConnections, this.acquiredPoolConnections);
297
+ (0, LogService_1.logDB)("Pool status: ", this.poolConnections, this.acquiredPoolConnections);
219
298
  }
220
299
  if (this.options.debug)
221
- console.log("Execute query", conn?.threadId);
300
+ (0, LogService_1.logDB)("Execute query", conn?.threadId);
222
301
  if (conn)
223
302
  return conn;
224
303
  }
@@ -248,7 +327,7 @@ class MysqlAdapter {
248
327
  if (!conn) {
249
328
  doCloseConnection = true;
250
329
  conn = await this.getConnection(request.transactionID ?? -1);
251
- if (this.isError(conn)) {
330
+ if (isError(conn)) {
252
331
  return {
253
332
  data: null,
254
333
  error: conn,
@@ -478,25 +557,26 @@ class MysqlAdapter {
478
557
  this.failReportFileStreamName = file;
479
558
  }
480
559
  if (this.options.debug)
481
- console.log("Store transaction fail report: ", file, trx.queries, message);
560
+ (0, LogService_1.logDB)("Store transaction fail report: ", file, trx.queries, message);
482
561
  if (!this.failReportFileStream)
483
562
  this.failReportFileStream = fs_1.default.createWriteStream(file, { flags: 'a' });
484
563
  this.failReportFileStream.write(JSON.stringify({ queries: trx.queries, time: trx.timestamp, date, message }) + "\n}EOB{\n", err => {
485
564
  if (err)
486
565
  (0, LogService_1.logCrit)("MysqlAdapter", "Can't write to transaction fail report file");
487
566
  else
488
- (0, LogService_1.logInfo)("MysqlAdapter", "Transaction fail report stored");
567
+ (0, LogService_1.logDB)("MysqlAdapter", "Transaction fail report stored");
489
568
  });
490
569
  this.failReportLastAccessTime = Date.now();
491
570
  }
492
571
  if (this.options.transactionFailReport)
493
572
  this.options.transactionFailReport(trx, message);
494
573
  }
495
- isError(obj) {
496
- return obj && "code" in obj && "errno" in obj && "name" in obj && "message" in obj;
497
- }
498
574
  }
499
575
  exports.MysqlAdapter = MysqlAdapter;
576
+ function isError(obj) {
577
+ return obj && "code" in obj && "errno" in obj && "name" in obj && "message" in obj;
578
+ }
579
+ exports.isError = isError;
500
580
  const secret_key = "AKLWkajw%^&dgwqhw#98453i23bfk23rn2knknglrgjeit";
501
581
  const secret_iv = "rthadrfk23rn2kn#*FNKA@gt44df3tslrgj##!it";
502
582
  const key = (0, crypto_1.createHash)('sha512').update(secret_key).digest('hex').substring(0, 32);
@@ -45,7 +45,7 @@ exports.REQ_XT.listener = async ({ id, req }) => {
45
45
  if (i.options.id === id)
46
46
  return await i.onExternalCall(req);
47
47
  }
48
- return { error: { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found" } };
48
+ return { error: { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found: " + id } };
49
49
  };
50
50
  exports.REQ_EXTERNAL_CALL.listener = async ({ id, requestName, requestData }) => {
51
51
  if (ExternalService.allInstances.length === 0) {
@@ -56,7 +56,7 @@ exports.REQ_EXTERNAL_CALL.listener = async ({ id, requestName, requestData }) =>
56
56
  if (i.options.id === id)
57
57
  return await i.requestExternalCall({ id, requestName, requestData });
58
58
  }
59
- return { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found" };
59
+ return { ...DefaultErrors_1.default.BAD_REQUEST, details: "no external service found: " + id + ", requestName:" + requestName, stack: [requestData] };
60
60
  };
61
61
  class ExternalService extends BaseService_1.BaseService {
62
62
  static allInstances = [];
@@ -65,7 +65,7 @@ class ExternalService extends BaseService_1.BaseService {
65
65
  super("ExternalService-" + opt.id);
66
66
  for (let i of ExternalService.allInstances) {
67
67
  if (i.options.id === opt.id)
68
- throw { code: -1, message: "duplicate id" };
68
+ throw { code: -1, message: "ExternalService, duplicate id: " + i.options.id };
69
69
  }
70
70
  ExternalService.allInstances.push(this);
71
71
  this.options = opt;
@@ -45,7 +45,12 @@ class Validator {
45
45
  return result;
46
46
  }
47
47
  let errors = [];
48
+ let foundKeys = [];
48
49
  for (let i in structure) {
50
+ if (structure[i] === null) {
51
+ foundKeys.push(i);
52
+ continue;
53
+ }
49
54
  if (!(i in object))
50
55
  errors.push("no field '" + i + "'");
51
56
  if (typeof structure[i] === "number" && typeof object[i] === "string") {
@@ -110,6 +115,7 @@ class Validator {
110
115
  }
111
116
  }
112
117
  }
118
+ foundKeys.push(i);
113
119
  }
114
120
  if (errors.length > 0)
115
121
  return errors;
@@ -14,7 +14,7 @@ class DefaultErrors {
14
14
  static SERVICE_NOT_WORKING = { code: 8, message: "Service not working" };
15
15
  static TIMEOUT = { code: 9, message: "Timeout" };
16
16
  static METHOD_NOT_ALLOWED = { code: 10, message: "Method not allowed", httpStatus: 405 };
17
- static DB_ERROR = { code: 11, message: "DB error" };
17
+ static DB_ERROR = { code: 11, message: "DB error", httpStatus: 500 };
18
18
  }
19
19
  class ErrorUtils {
20
20
  static isError(obj) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",