badmfck-api-server 3.8.3 → 3.8.4

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.
@@ -32,8 +32,6 @@ export interface APIServiceOptions<TInterceptor = unknown> {
32
32
  projectName: string;
33
33
  endpoints: IBaseEndpoint[];
34
34
  jsonLimit: string;
35
- onNetworkLog?: ((log: APIServiceNetworkLogItem) => void) | null;
36
- onError?: ((...rest: any[]) => void) | null;
37
35
  isProductionEnvironment: boolean;
38
36
  interceptor?: IInterceptor<TInterceptor>;
39
37
  postproducer?: (req: HTTPRequestVO | undefined | null, res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, log?: APIServiceNetworkLogItem | null) => Promise<TransferPacketVO>;
@@ -48,10 +46,10 @@ export interface APIServiceOptions<TInterceptor = unknown> {
48
46
  fileLimit: number;
49
47
  }
50
48
  type InferInterceptor<T> = T extends IInterceptor<infer U> ? U : unknown;
51
- export declare function getDefaultOptions<I extends IInterceptor<any> | undefined>(opts: Omit<APIServiceOptions<InferInterceptor<NonNullable<I>>>, 'interceptor'> & {
52
- interceptor?: I;
53
- }): APIServiceOptions<InferInterceptor<NonNullable<I>>>;
54
- export declare const REQ_CREATE_NET_LOG: Req<void, APIServiceNetworkLogItem>;
49
+ export declare const getDefaultOptions: <I extends IInterceptor<any> | undefined>(overrides?: (Omit<Partial<APIServiceOptions<InferInterceptor<NonNullable<I>>>>, "interceptor"> & {
50
+ interceptor?: I | undefined;
51
+ }) | undefined) => APIServiceOptions<InferInterceptor<NonNullable<I>>>;
52
+ export declare const REQ_DEPREACTED_CREATE_NET_LOG: Req<void, APIServiceNetworkLogItem>;
55
53
  export declare const REQ_HTTP_LOG: Req<void, APIServiceNetworkLogItem[]>;
56
54
  export declare const REQ_HTTP_REQUESTS_COUNT: Req<void, number>;
57
55
  export declare const REQ_HTTP_SERVER: Req<void, {
@@ -72,7 +70,8 @@ export declare class APIService extends BaseService {
72
70
  netLog: APIServiceNetworkLogItem[];
73
71
  constructor(options: APIServiceOptions);
74
72
  init(): Promise<void>;
75
- sendResponse(ref: string, res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, log?: APIServiceNetworkLogItem | null, req?: HTTPRequestVO): Promise<void>;
73
+ addNetlog(data: TransferPacketVO, req: HTTPRequestVO, created: number, time: number): void;
74
+ sendResponse(ref: string, res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, req?: HTTPRequestVO): Promise<void>;
76
75
  checkDataLength(data: any, result?: any, lvl?: number): any;
77
76
  }
78
77
  export {};
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.APIService = exports.Initializer = exports.REQ_DOC_USERS = exports.REQ_MONITOR_USERS = exports.REQ_INTERNAL_CALL = exports.REQ_HTTP_SERVER = exports.REQ_HTTP_REQUESTS_COUNT = exports.REQ_HTTP_LOG = exports.REQ_CREATE_NET_LOG = exports.getDefaultOptions = void 0;
29
+ exports.APIService = exports.Initializer = exports.REQ_DOC_USERS = exports.REQ_MONITOR_USERS = exports.REQ_INTERNAL_CALL = exports.REQ_HTTP_SERVER = exports.REQ_HTTP_REQUESTS_COUNT = exports.REQ_HTTP_LOG = exports.REQ_DEPREACTED_CREATE_NET_LOG = exports.getDefaultOptions = void 0;
30
30
  const express_1 = __importDefault(require("express"));
31
31
  const BaseService_1 = require("./BaseService");
32
32
  const cors_1 = __importDefault(require("cors"));
@@ -35,9 +35,7 @@ const DefaultErrors_1 = __importStar(require("./structures/DefaultErrors"));
35
35
  const badmfck_signal_1 = require("badmfck-signal");
36
36
  const LogService_1 = require("./LogService");
37
37
  const Monitor_1 = require("./monitor/Monitor");
38
- const path_1 = __importDefault(require("path"));
39
38
  const express_fileupload_1 = __importDefault(require("express-fileupload"));
40
- const os_1 = __importDefault(require("os"));
41
39
  const Liveness_1 = require("./routes/Liveness");
42
40
  const Readiness_1 = require("./routes/Readiness");
43
41
  const http_1 = __importDefault(require("http"));
@@ -47,36 +45,35 @@ const MonitorService_1 = require("./MonitorService");
47
45
  const MysqlAdapter_1 = require("./db/MysqlAdapter");
48
46
  const DocumentService_1 = require("./DocumentService");
49
47
  const Documentation_1 = require("./documentation/Documentation");
48
+ let nextLogID = 0;
50
49
  function bindRequestToOptions(opts, req) {
51
50
  return req;
52
51
  }
53
- function getDefaultOptions(opts) {
52
+ function defaultOptions() {
54
53
  return {
55
- port: 8091,
56
- access: {
57
- monitor: [],
58
- documentation: [],
59
- },
60
- baseEndPoint: '/api/',
61
- corsHostWhiteList: [
62
- 'http://localhost:3000',
63
- ],
54
+ port: 8080,
55
+ baseEndPoint: "/api/",
56
+ corsHostWhiteList: [],
57
+ projectName: "App",
64
58
  endpoints: [],
65
59
  jsonLimit: "10mb",
66
- onNetworkLog: function (log) {
67
- (0, LogService_1.logAPI)("${APIService.js}", log);
68
- },
69
- onError: function (err) {
70
- (0, LogService_1.logError)("${APIService.js}", err);
71
- },
72
- projectName: "API Service",
73
60
  isProductionEnvironment: false,
74
- fileLimit: 50 * 1024 * 1024,
75
- fileTempDir: path_1.default.resolve(os_1.default.tmpdir(), "fileTempDir")
61
+ interceptor: undefined,
62
+ postproducer: undefined,
63
+ preproducer: undefined,
64
+ access: {},
65
+ monitor: undefined,
66
+ appVersion: undefined,
67
+ fileTempDir: "/tmp",
68
+ fileLimit: 10_000_000,
76
69
  };
77
70
  }
71
+ const getDefaultOptions = (overrides) => {
72
+ const base = defaultOptions();
73
+ return { ...base, ...overrides };
74
+ };
78
75
  exports.getDefaultOptions = getDefaultOptions;
79
- exports.REQ_CREATE_NET_LOG = new badmfck_signal_1.Req(undefined, "REQ_CREATE_NET_LOG");
76
+ exports.REQ_DEPREACTED_CREATE_NET_LOG = new badmfck_signal_1.Req(undefined, "REQ_CREATE_NET_LOG");
80
77
  exports.REQ_HTTP_LOG = new badmfck_signal_1.Req(undefined, "REQ_HTTP_LOG");
81
78
  exports.REQ_HTTP_REQUESTS_COUNT = new badmfck_signal_1.Req(undefined, "REQ_HTTP_REQUESTS_COUNT");
82
79
  exports.REQ_HTTP_SERVER = new badmfck_signal_1.Req(undefined, "REQ_HTTP_SERVER");
@@ -98,7 +95,7 @@ async function Initializer(services) {
98
95
  exports.Initializer = Initializer;
99
96
  class APIService extends BaseService_1.BaseService {
100
97
  static nextLogID = 0;
101
- version = "3.8.3";
98
+ version = "3.8.4";
102
99
  options;
103
100
  monitor = null;
104
101
  started = new Date();
@@ -124,21 +121,7 @@ class APIService extends BaseService_1.BaseService {
124
121
  exports.REQ_HTTP_REQUESTS_COUNT.listener = async () => this.requestsCount;
125
122
  }
126
123
  async init() {
127
- exports.REQ_HTTP_LOG.listener = async (ignore) => this.netLog;
128
- exports.REQ_CREATE_NET_LOG.listener = async (ignore) => {
129
- const log = {
130
- created: +new Date(),
131
- time: 0,
132
- request: {},
133
- response: {},
134
- error: null,
135
- id: APIService.nextLogID++
136
- };
137
- this.netLog.push(log);
138
- if (this.netLog.length > 1000)
139
- this.netLog.shift();
140
- return log;
141
- };
124
+ exports.REQ_HTTP_LOG.listener = async (_) => this.netLog;
142
125
  exports.REQ_INTERNAL_CALL.listener = async (req) => {
143
126
  for (let i of this.options.endpoints) {
144
127
  if (!i || !i.endpoints)
@@ -170,7 +153,17 @@ class APIService extends BaseService_1.BaseService {
170
153
  error: DefaultErrors_1.default.FILE_TOO_LARGE,
171
154
  data: null,
172
155
  httpStatus: 413,
173
- }, +new Date(), req.path);
156
+ }, +new Date(), req.path, {
157
+ endpoint: req.path,
158
+ headers: req.headers,
159
+ method: req.method,
160
+ data: req.body,
161
+ params: req.params,
162
+ interceptorResult: null,
163
+ raw: req,
164
+ response: undefined,
165
+ files: undefined
166
+ });
174
167
  },
175
168
  limits: { fileSize: this.options.fileLimit },
176
169
  useTempFiles: true,
@@ -184,12 +177,6 @@ class APIService extends BaseService_1.BaseService {
184
177
  return;
185
178
  }
186
179
  const tme = +new Date();
187
- const log = await exports.REQ_CREATE_NET_LOG.request();
188
- log.request = {
189
- method: req.method,
190
- data: "",
191
- params: req.params
192
- };
193
180
  let responseError = DefaultErrors_1.default.UNKNOWN_REQUEST;
194
181
  if (typeof err === "object" && err.status === 400 && 'body' in err && err.type === 'entity.parse.failed') {
195
182
  responseError = DefaultErrors_1.default.JSON_MALFORMED;
@@ -198,7 +185,17 @@ class APIService extends BaseService_1.BaseService {
198
185
  error: responseError,
199
186
  data: null,
200
187
  httpStatus: 400
201
- }, tme, "", log);
188
+ }, tme, "", {
189
+ endpoint: "",
190
+ headers: req.headers,
191
+ method: req.method,
192
+ data: req.body,
193
+ params: req.params,
194
+ interceptorResult: null,
195
+ raw: req,
196
+ response: undefined,
197
+ files: undefined
198
+ });
202
199
  });
203
200
  const corsOptions = {
204
201
  origin: (origin, callback) => {
@@ -219,16 +216,6 @@ class APIService extends BaseService_1.BaseService {
219
216
  app.all(ep, async (req, res) => {
220
217
  this.requestsCount++;
221
218
  const tme = +new Date();
222
- let log = null;
223
- if (!i.ignoreHttpLogging) {
224
- log = await exports.REQ_CREATE_NET_LOG.request();
225
- log.request = {
226
- url: req.url,
227
- method: req.method,
228
- data: this.checkDataLength(req.body),
229
- params: this.checkDataLength(req.params)
230
- };
231
- }
232
219
  const execute = async () => {
233
220
  const body = req.body;
234
221
  if (req.query && typeof req.query === "object") {
@@ -262,10 +249,10 @@ class APIService extends BaseService_1.BaseService {
262
249
  stack = [e];
263
250
  }
264
251
  if ((0, MysqlAdapter_1.isError)(e)) {
265
- this.sendResponse(req.get("Referer") ?? "", res, { error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message } }, tme, ep, log, httpRequest);
252
+ this.sendResponse(req.get("Referer") ?? "", res, { error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message } }, tme, ep, httpRequest);
266
253
  return;
267
254
  }
268
- 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);
255
+ this.sendResponse(req.get("Referer") ?? "", res, { error: { code: 10002, message: "Internal server error!", stack: stack, details: details }, data: null, httpStatus: 500 }, tme, ep, httpRequest);
269
256
  return;
270
257
  }
271
258
  }
@@ -292,7 +279,7 @@ class APIService extends BaseService_1.BaseService {
292
279
  const httpRequestBound = bindRequestToOptions(this.options, httpRequest);
293
280
  interceptorResult = await this.options.interceptor.intercept(httpRequest);
294
281
  if (DefaultErrors_1.ErrorUtils.isError(interceptorResult) && !allowInterceptorError) {
295
- this.sendResponse(req.get("Referer") ?? "", res, interceptorResult, tme, ep, log, httpRequest);
282
+ this.sendResponse(req.get("Referer") ?? "", res, interceptorResult, tme, ep, httpRequest);
296
283
  return;
297
284
  }
298
285
  httpRequestBound.interceptorResult = interceptorResult;
@@ -301,7 +288,7 @@ class APIService extends BaseService_1.BaseService {
301
288
  }
302
289
  const precheck = await i.__precheck(httpRequest);
303
290
  if (precheck && precheck.error) {
304
- this.sendResponse(req.get("Referer") ?? "", res, precheck, tme, ep, log, httpRequest);
291
+ this.sendResponse(req.get("Referer") ?? "", res, precheck, tme, ep, httpRequest);
305
292
  return;
306
293
  }
307
294
  httpRequest.precheck = precheck;
@@ -337,10 +324,10 @@ class APIService extends BaseService_1.BaseService {
337
324
  error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message }
338
325
  };
339
326
  }
340
- this.sendResponse(req.get("Referer") ?? "", res, data, tme, ep, log, httpRequest);
327
+ this.sendResponse(req.get("Referer") ?? "", res, data, tme, ep, httpRequest);
341
328
  return;
342
329
  }
343
- this.sendResponse(req.get("Referer") ?? "", res, result, tme, ep, log, httpRequest);
330
+ this.sendResponse(req.get("Referer") ?? "", res, result, tme, ep, httpRequest);
344
331
  };
345
332
  execute();
346
333
  });
@@ -352,23 +339,51 @@ class APIService extends BaseService_1.BaseService {
352
339
  error: DefaultErrors_1.default.UNKNOWN_REQUEST,
353
340
  data: null,
354
341
  httpStatus: 404
355
- }, tme, req.path);
342
+ }, tme, req.path, {
343
+ endpoint: req.path,
344
+ headers: req.headers,
345
+ method: req.method,
346
+ data: req.body,
347
+ params: req.params,
348
+ interceptorResult: null,
349
+ raw: req,
350
+ response: undefined,
351
+ files: undefined
352
+ });
356
353
  });
357
354
  server.listen(this.options.port, () => {
358
355
  (0, LogService_1.logAPI)('${APIService.js}', 'API Service started at: ' + this.options.port + ", with base endpoint:" + this.options.baseEndPoint + ", ver.: " + this.version);
359
356
  });
360
357
  }
361
- async sendResponse(ref, res, data, requestTime, endpoint, log, req) {
358
+ addNetlog(data, req, created, time) {
359
+ const logItem = {
360
+ id: nextLogID++,
361
+ created: created,
362
+ time: time,
363
+ request: {
364
+ endpoint: req?.endpoint,
365
+ headers: req?.headers,
366
+ method: req?.method,
367
+ data: req?.data,
368
+ params: req?.params,
369
+ interceptorResult: req?.interceptorResult
370
+ },
371
+ response: data
372
+ };
373
+ this.netLog.push(logItem);
374
+ if (this.netLog.length > 100)
375
+ this.netLog.shift();
376
+ }
377
+ async sendResponse(ref, res, data, requestTime, endpoint, req) {
362
378
  if (data.blockResponse) {
363
- if (log)
364
- log.error = "Response blocked";
365
- if (this.options.onNetworkLog && log)
366
- this.options.onNetworkLog(log);
379
+ (0, LogService_1.logAPI)("Response blocked");
380
+ if (req)
381
+ this.addNetlog(data, req, requestTime, 0);
367
382
  return;
368
383
  }
369
384
  if (this.options.postproducer) {
370
385
  try {
371
- data = await this.options.postproducer(req, res, data, requestTime, endpoint, log);
386
+ data = await this.options.postproducer(req, res, data, requestTime, endpoint);
372
387
  }
373
388
  catch (e) {
374
389
  (0, LogService_1.logError)("Postproducer error", e);
@@ -381,37 +396,28 @@ class APIService extends BaseService_1.BaseService {
381
396
  data.endpoint = endpoint ?? "no_endpoint";
382
397
  if (this.options.appVersion)
383
398
  data.version = this.options.appVersion;
384
- if (log) {
385
- log.time = data.responseTime;
386
- log.referer = ref;
387
- }
388
399
  MonitorService_1.S_STAT_REGISTRATE_REQUEST.invoke(data);
389
400
  if (res.destroyed || res.closed) {
390
- if (log)
391
- log.error = "Connection already closed, can't send response for: " + data.endpoint;
392
- if (this.options.onError)
393
- this.options.onError("Connection already closed, can't send response: " + data.endpoint, data);
401
+ (0, LogService_1.logAPI)("Connection already closed, can't send response for: " + data.endpoint);
394
402
  }
395
403
  else {
396
404
  try {
397
405
  if (data.file) {
398
406
  res.sendFile(data.file, err => {
399
407
  if (err) {
400
- if (log)
401
- log.error = "Can't send file: " + data.file;
408
+ (0, LogService_1.logError)("Can't send file: " + data.file);
402
409
  this.sendResponse(ref, res, {
403
410
  error: DefaultErrors_1.default.CANT_SEND_FILE,
404
411
  data: null,
405
412
  httpStatus: 500
406
- }, requestTime, data.endpoint);
413
+ }, requestTime, data.endpoint, req);
407
414
  }
408
415
  });
409
416
  return;
410
417
  }
411
418
  if (data.redirect) {
412
419
  res.redirect(data.redirect);
413
- if (log)
414
- log.response = { redirect: data.redirect };
420
+ (0, LogService_1.logAPI)("redirect: " + data.redirect);
415
421
  }
416
422
  else {
417
423
  if (data.headers) {
@@ -424,34 +430,20 @@ class APIService extends BaseService_1.BaseService {
424
430
  res.statusCode = data.httpStatus ?? 200;
425
431
  if (data.rawResponse) {
426
432
  res.send(data.data);
427
- if (log)
428
- log.response = this.checkDataLength(data);
433
+ (0, LogService_1.logAPI)(this.checkDataLength(data));
429
434
  }
430
435
  else {
431
436
  res.send(data);
432
- if (log)
433
- log.response = this.checkDataLength(data);
434
- if (data.error) {
435
- if (log)
436
- log.error = data.error.message;
437
- }
437
+ (0, LogService_1.logAPI)(this.checkDataLength(data));
438
+ if (data.error)
439
+ (0, LogService_1.logError)(data.error.message);
438
440
  }
439
441
  }
440
442
  }
441
443
  catch (e) {
442
- if (this.options.onError)
443
- this.options.onError("Can't send response", e);
444
- if (log)
445
- log.error = "Can't send response";
444
+ console.error(e);
446
445
  }
447
446
  }
448
- if (log && log.error && this.options.onError) {
449
- this.options.onError(log.error);
450
- }
451
- else {
452
- if (this.options.onNetworkLog && log)
453
- this.options.onNetworkLog(log);
454
- }
455
447
  }
456
448
  checkDataLength(data, result, lvl) {
457
449
  if (!lvl)
@@ -26,9 +26,7 @@ export interface HTTPRequestVO<T = any, TInterceport = any> {
26
26
  params: {
27
27
  [key: string]: string;
28
28
  };
29
- headers: {
30
- [key: string]: string;
31
- };
29
+ headers: Record<string, string>;
32
30
  endpoint: string;
33
31
  interceptorResult?: any;
34
32
  preproducerResult?: any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "3.8.3",
3
+ "version": "3.8.4",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",