badmfck-api-server 2.1.2 → 2.1.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.
@@ -9,6 +9,7 @@ export interface APIServiceNetworkLogItem {
9
9
  id: number;
10
10
  created: number;
11
11
  time: number;
12
+ referer?: string;
12
13
  request: {
13
14
  [key: string]: any;
14
15
  };
@@ -59,6 +60,6 @@ export declare class APIService extends BaseService {
59
60
  netLog: APIServiceNetworkLogItem[];
60
61
  constructor(options?: APIServiceOptions | null);
61
62
  init(): Promise<void>;
62
- sendResponse(res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, log?: APIServiceNetworkLogItem | null, req?: HTTPRequestVO): Promise<void>;
63
+ sendResponse(ref: string, res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, log?: APIServiceNetworkLogItem | null, req?: HTTPRequestVO): Promise<void>;
63
64
  checkDataLength(data: any, result?: any, lvl?: number): any;
64
65
  }
@@ -83,7 +83,7 @@ async function Initializer(services) {
83
83
  exports.Initializer = Initializer;
84
84
  class APIService extends BaseService_1.BaseService {
85
85
  static nextLogID = 0;
86
- version = "2.1.2";
86
+ version = "2.1.3";
87
87
  options;
88
88
  monitor;
89
89
  monitorIndexFile;
@@ -154,10 +154,10 @@ class APIService extends BaseService_1.BaseService {
154
154
  app.use(express_1.default.urlencoded({ limit: '10mb', extended: true }));
155
155
  app.use((0, express_fileupload_1.default)({
156
156
  limitHandler: (req, res, next) => {
157
- this.sendResponse(res, {
157
+ this.sendResponse(req.get("Referer") ?? "", res, {
158
158
  error: DefaultErrors_1.default.FILE_TOO_LARGE,
159
159
  data: null,
160
- httpStatus: 413
160
+ httpStatus: 413,
161
161
  }, +new Date(), req.path);
162
162
  },
163
163
  limits: { fileSize: this.options.fileLimit },
@@ -182,7 +182,7 @@ class APIService extends BaseService_1.BaseService {
182
182
  if (typeof err === "object" && err.status === 400 && 'body' in err && err.type === 'entity.parse.failed') {
183
183
  responseError = DefaultErrors_1.default.JSON_MALFORMED;
184
184
  }
185
- this.sendResponse(resp, {
185
+ this.sendResponse(req.get("Referer") ?? "", resp, {
186
186
  error: responseError,
187
187
  data: null,
188
188
  httpStatus: 400
@@ -231,7 +231,8 @@ class APIService extends BaseService_1.BaseService {
231
231
  params: req.params,
232
232
  headers: req.headers,
233
233
  endpoint: ep,
234
- files: req.files ?? null
234
+ files: req.files ?? null,
235
+ referer: req.get("Referer"),
235
236
  };
236
237
  if (this.options.preproducer) {
237
238
  try {
@@ -240,7 +241,7 @@ class APIService extends BaseService_1.BaseService {
240
241
  httpRequest.preproducerResult = preproducerResult;
241
242
  }
242
243
  catch (e) {
243
- this.sendResponse(res, { error: { code: 10002, message: "Internal server error", details: `${e}` }, data: null, httpStatus: 500 }, tme, ep, log, httpRequest);
244
+ this.sendResponse(req.get("Referer") ?? "", res, { error: { code: 10002, message: "Internal server error", details: `${e}` }, data: null, httpStatus: 500 }, tme, ep, log, httpRequest);
244
245
  return;
245
246
  }
246
247
  }
@@ -251,7 +252,7 @@ class APIService extends BaseService_1.BaseService {
251
252
  if (this.options.interceptor) {
252
253
  interceptorResult = await this.options.interceptor.execute(httpRequest);
253
254
  if (interceptorResult.error && !j.allowInterceptorError) {
254
- this.sendResponse(res, interceptorResult, tme, ep, log, httpRequest);
255
+ this.sendResponse(req.get("Referer") ?? "", res, interceptorResult, tme, ep, log, httpRequest);
255
256
  return;
256
257
  }
257
258
  httpRequest.interceptorResult = interceptorResult;
@@ -261,7 +262,7 @@ class APIService extends BaseService_1.BaseService {
261
262
  httpRequest.precheck = { data: this.options.monitor };
262
263
  const precheck = await i.precheck(httpRequest);
263
264
  if (precheck && precheck.error) {
264
- this.sendResponse(res, precheck, tme, ep, log, httpRequest);
265
+ this.sendResponse(req.get("Referer") ?? "", res, precheck, tme, ep, log, httpRequest);
265
266
  return;
266
267
  }
267
268
  httpRequest.precheck = precheck;
@@ -273,7 +274,7 @@ class APIService extends BaseService_1.BaseService {
273
274
  this.options.onError(e);
274
275
  if (this.monitor)
275
276
  this.monitor.registrateFatalError(ep);
276
- this.sendResponse(res, {
277
+ this.sendResponse(req.get("Referer") ?? "", res, {
277
278
  httpStatus: 500,
278
279
  error: {
279
280
  code: 10002,
@@ -283,7 +284,7 @@ class APIService extends BaseService_1.BaseService {
283
284
  }, tme, ep, log, httpRequest);
284
285
  return;
285
286
  }
286
- this.sendResponse(res, result, tme, ep, log, httpRequest);
287
+ this.sendResponse(req.get("Referer") ?? "", res, result, tme, ep, log, httpRequest);
287
288
  };
288
289
  execute();
289
290
  });
@@ -311,7 +312,7 @@ class APIService extends BaseService_1.BaseService {
311
312
  res.status(200).send(this.monitorIndexFile);
312
313
  }
313
314
  catch (e) {
314
- this.sendResponse(res, {
315
+ this.sendResponse(req.get("Referer") ?? "", res, {
315
316
  error: {
316
317
  code: 10002,
317
318
  message: "Internal server error",
@@ -325,7 +326,7 @@ class APIService extends BaseService_1.BaseService {
325
326
  }
326
327
  }
327
328
  }
328
- this.sendResponse(res, {
329
+ this.sendResponse(req.get("Referer") ?? "", res, {
329
330
  error: DefaultErrors_1.default.UNKNOWN_REQUEST,
330
331
  data: null,
331
332
  httpStatus: 404
@@ -335,7 +336,7 @@ class APIService extends BaseService_1.BaseService {
335
336
  (0, LogService_1.logCrit)('${APIService.js}', 'API Service started at: ' + this.options.port + ", with base endpoint:" + this.options.baseEndPoint + ", ver.: " + this.version);
336
337
  });
337
338
  }
338
- async sendResponse(res, data, requestTime, endpoint, log, req) {
339
+ async sendResponse(ref, res, data, requestTime, endpoint, log, req) {
339
340
  if (this.options.postproducer) {
340
341
  try {
341
342
  data = await this.options.postproducer(req, res, data, requestTime, endpoint, log);
@@ -351,8 +352,10 @@ class APIService extends BaseService_1.BaseService {
351
352
  data.endpoint = endpoint ?? "no_endpoint";
352
353
  if (this.options.appVersion)
353
354
  data.version = this.options.appVersion;
354
- if (log)
355
+ if (log) {
355
356
  log.time = data.responseTime;
357
+ log.referer = ref;
358
+ }
356
359
  if (this.monitor)
357
360
  this.monitor.registrateResponse(data.endpoint, data.responseTime);
358
361
  if (res.destroyed || res.closed) {
@@ -374,7 +377,7 @@ class APIService extends BaseService_1.BaseService {
374
377
  this.options.onError("Can't send file: " + data.file, err);
375
378
  if (this.monitor && data.endpoint)
376
379
  this.monitor.registrateAPIError(data.endpoint);
377
- this.sendResponse(res, {
380
+ this.sendResponse(ref, res, {
378
381
  error: DefaultErrors_1.default.CANT_SEND_FILE,
379
382
  data: null,
380
383
  httpStatus: 500
@@ -18,6 +18,7 @@ export interface MysqlServiceOptions {
18
18
  }
19
19
  export interface MysqlResult {
20
20
  error?: MysqlError | null;
21
+ rollbackError?: MysqlError | null;
21
22
  isDuplicateError?: boolean;
22
23
  fields?: FieldInfo[] | null;
23
24
  data: any;
@@ -25,6 +26,7 @@ export interface MysqlResult {
25
26
  export interface MySqlQuery {
26
27
  query: string;
27
28
  fields: MysqlQueryField[] | MysqlQueryFieldObject;
29
+ rollbackQuery?: string | null;
28
30
  }
29
31
  export interface MysqlQueryField {
30
32
  name: string;
@@ -60,8 +62,13 @@ export declare class MysqlService extends BaseService {
60
62
  static objectToFields(obj: MysqlQueryFieldObject | MysqlQueryField[]): MysqlQueryField[];
61
63
  static prepareQuery(query: string, fields: MysqlQueryField[] | MysqlQueryFieldObject): string;
62
64
  static prepareQueryFieldValue(value: string | number | boolean | null | undefined, system?: boolean): string | number | boolean | null | undefined;
63
- execute(query: string): Promise<MysqlResult>;
64
- sendQuery(conn: PoolConnection, query: string, resolve: (data: MysqlResult) => void): void;
65
+ execute(query: string, rollbackQuery: string | null): Promise<MysqlResult>;
66
+ sendQuery(conn: PoolConnection, query: string, resolve: (data: MysqlResult) => void, rollback: string | null): Promise<void>;
67
+ queryAsync(conn: PoolConnection, query: string): Promise<{
68
+ err: MysqlError | null;
69
+ results?: any;
70
+ fields?: FieldInfo[];
71
+ }>;
65
72
  createPool(): Promise<boolean>;
66
73
  }
67
74
  export default MysqlService;
@@ -66,7 +66,7 @@ class MysqlService extends BaseService_1.BaseService {
66
66
  const promises = [];
67
67
  for (let i of data) {
68
68
  const query = MysqlService.prepareQuery(i.query, i.fields);
69
- promises.push(this.execute(query));
69
+ promises.push(this.execute(query, i.rollbackQuery ?? null));
70
70
  }
71
71
  return await Promise.all(promises);
72
72
  };
@@ -206,7 +206,7 @@ class MysqlService extends BaseService_1.BaseService {
206
206
  return "NULL";
207
207
  return value;
208
208
  }
209
- async execute(query) {
209
+ async execute(query, rollbackQuery) {
210
210
  return new Promise((resolve, reject) => {
211
211
  if (!this.pool) {
212
212
  (0, LogService_1.logError)("${MysqlService.js}", "No pool");
@@ -252,40 +252,23 @@ class MysqlService extends BaseService_1.BaseService {
252
252
  fields: null
253
253
  });
254
254
  }
255
- try {
256
- this.sendQuery(conn, query, resolve);
257
- }
258
- catch (e) {
259
- try {
260
- conn.removeAllListeners();
261
- conn.release();
262
- }
263
- catch (e) { }
264
- (0, LogService_1.logError)("${MysqlService.js}", "QUERY_ERR: " + e);
265
- resolve({
266
- error: {
267
- code: "QUERY_ERR",
268
- errno: 100002,
269
- fatal: true,
270
- sql: query,
271
- name: "QUERY_ERR",
272
- message: "Error: " + e
273
- },
274
- data: null,
275
- fields: null
276
- });
277
- }
255
+ this.sendQuery(conn, query, resolve, rollbackQuery);
278
256
  });
279
257
  });
280
258
  }
281
- sendQuery(conn, query, resolve) {
259
+ async sendQuery(conn, query, resolve, rollback) {
282
260
  let errCatched = false;
283
- conn.on("error", err => {
261
+ conn.on("error", async (err) => {
284
262
  errCatched = true;
285
- conn.release();
286
- conn.removeAllListeners();
287
- (0, LogService_1.logError)("${MysqlService.js}", err);
288
- conn.removeAllListeners();
263
+ let rollbackError = null;
264
+ if (rollback)
265
+ rollbackError = (await this.queryAsync(conn, rollback)).err;
266
+ (0, LogService_1.logError)("${MysqlService.js}->conn.on('error')", err);
267
+ try {
268
+ conn.release();
269
+ conn.removeAllListeners();
270
+ }
271
+ catch (e) { }
289
272
  resolve({
290
273
  error: {
291
274
  code: "CONN_ERR",
@@ -296,32 +279,65 @@ class MysqlService extends BaseService_1.BaseService {
296
279
  message: "Error: " + err
297
280
  },
298
281
  data: null,
299
- fields: null
282
+ fields: null,
283
+ rollbackError: rollbackError
300
284
  });
301
285
  });
302
286
  (0, LogService_1.logInfo)("${MysqlService.js}", query);
303
- conn.query(query, (err, results, fields) => {
287
+ const queryResult = await this.queryAsync(conn, query);
288
+ if (queryResult.err) {
289
+ let rollbackError = null;
290
+ if (rollback)
291
+ rollbackError = (await this.queryAsync(conn, rollback)).err;
292
+ try {
293
+ conn.release();
294
+ conn.removeAllListeners();
295
+ }
296
+ catch (e) { }
297
+ const dup = `${queryResult.err}`.toLowerCase().indexOf("er_dup_entry") !== -1;
298
+ (0, LogService_1.logError)("${MysqlService.js}->query error", queryResult.err);
299
+ resolve({
300
+ error: queryResult.err,
301
+ data: null,
302
+ fields: null,
303
+ rollbackError: rollbackError,
304
+ isDuplicateError: dup
305
+ });
306
+ }
307
+ try {
304
308
  conn.release();
305
309
  conn.removeAllListeners();
306
- if (errCatched)
307
- return;
308
- if (err) {
309
- const dup = `${err}`.toLowerCase().indexOf("er_dup_entry") !== -1;
310
- (0, LogService_1.logError)("${MysqlService.js}", err);
310
+ }
311
+ catch (e) { }
312
+ resolve({
313
+ error: queryResult.err,
314
+ data: queryResult.results,
315
+ fields: queryResult.fields
316
+ });
317
+ }
318
+ async queryAsync(conn, query) {
319
+ return new Promise((resolve, reject) => {
320
+ try {
321
+ conn.query(query, (err, results, fields) => {
322
+ resolve({
323
+ err: err,
324
+ results: results,
325
+ fields: fields
326
+ });
327
+ });
328
+ }
329
+ catch (e) {
311
330
  resolve({
312
- error: err,
313
- data: null,
314
- fields: null,
315
- isDuplicateError: dup
331
+ err: {
332
+ code: "QUERY_ERR",
333
+ errno: 100002,
334
+ fatal: true,
335
+ sql: query,
336
+ name: "QUERY_ERR",
337
+ message: "Error: " + e
338
+ }
316
339
  });
317
- return;
318
340
  }
319
- resolve({
320
- error: err,
321
- data: results,
322
- fields: fields
323
- });
324
- return;
325
341
  });
326
342
  }
327
343
  async createPool() {
@@ -29,6 +29,7 @@ export interface HTTPRequestVO<T = any> {
29
29
  preproducerResult?: any;
30
30
  precheck?: TransferPacketVO<any> | null;
31
31
  files: FileArray | null | undefined;
32
+ referer?: string;
32
33
  unlocked?: boolean;
33
34
  }
34
35
  export interface IError {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",