badmfck-api-server 3.8.3 → 3.8.5

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>;
@@ -42,16 +40,15 @@ export interface APIServiceOptions<TInterceptor = unknown> {
42
40
  monitor?: IMonitorUser[];
43
41
  documentation?: IMonitorUser[];
44
42
  };
45
- monitor?: IMonitorUser[];
46
43
  appVersion?: string;
47
44
  fileTempDir: string;
48
45
  fileLimit: number;
49
46
  }
50
47
  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>;
48
+ export declare const getDefaultOptions: <I extends IInterceptor<any> | undefined>(overrides?: (Omit<Partial<APIServiceOptions<InferInterceptor<NonNullable<I>>>>, "interceptor"> & {
49
+ interceptor?: I | undefined;
50
+ }) | undefined) => APIServiceOptions<InferInterceptor<NonNullable<I>>>;
51
+ export declare const REQ_DEPREACTED_CREATE_NET_LOG: Req<void, APIServiceNetworkLogItem>;
55
52
  export declare const REQ_HTTP_LOG: Req<void, APIServiceNetworkLogItem[]>;
56
53
  export declare const REQ_HTTP_REQUESTS_COUNT: Req<void, number>;
57
54
  export declare const REQ_HTTP_SERVER: Req<void, {
@@ -63,7 +60,6 @@ export declare const REQ_MONITOR_USERS: Req<void, IMonitorUser[]>;
63
60
  export declare const REQ_DOC_USERS: Req<void, IMonitorUser[]>;
64
61
  export declare function Initializer(services: IBaseService[]): Promise<void>;
65
62
  export declare class APIService extends BaseService {
66
- private static nextLogID;
67
63
  private version;
68
64
  private options;
69
65
  private monitor;
@@ -72,7 +68,8 @@ export declare class APIService extends BaseService {
72
68
  netLog: APIServiceNetworkLogItem[];
73
69
  constructor(options: APIServiceOptions);
74
70
  init(): Promise<void>;
75
- sendResponse(ref: string, res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, log?: APIServiceNetworkLogItem | null, req?: HTTPRequestVO): Promise<void>;
71
+ addNetlog(data: TransferPacketVO, req: HTTPRequestVO, created: number, time: number): void;
72
+ sendResponse(ref: string, res: Response, data: TransferPacketVO<any>, requestTime: number, endpoint?: string, req?: HTTPRequestVO): Promise<void>;
76
73
  checkDataLength(data: any, result?: any, lvl?: number): any;
77
74
  }
78
75
  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,37 @@ 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: ["localhost:3000"],
64
57
  endpoints: [],
65
58
  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",
59
+ projectName: "Application project",
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: [],
66
+ documentation: []
67
+ },
68
+ appVersion: undefined,
69
+ fileTempDir: "/tmp",
70
+ fileLimit: 10_000_000,
76
71
  };
77
72
  }
73
+ const getDefaultOptions = (overrides) => {
74
+ const base = defaultOptions();
75
+ return { ...base, ...overrides };
76
+ };
78
77
  exports.getDefaultOptions = getDefaultOptions;
79
- exports.REQ_CREATE_NET_LOG = new badmfck_signal_1.Req(undefined, "REQ_CREATE_NET_LOG");
78
+ exports.REQ_DEPREACTED_CREATE_NET_LOG = new badmfck_signal_1.Req(undefined, "REQ_CREATE_NET_LOG");
80
79
  exports.REQ_HTTP_LOG = new badmfck_signal_1.Req(undefined, "REQ_HTTP_LOG");
81
80
  exports.REQ_HTTP_REQUESTS_COUNT = new badmfck_signal_1.Req(undefined, "REQ_HTTP_REQUESTS_COUNT");
82
81
  exports.REQ_HTTP_SERVER = new badmfck_signal_1.Req(undefined, "REQ_HTTP_SERVER");
@@ -97,8 +96,7 @@ async function Initializer(services) {
97
96
  }
98
97
  exports.Initializer = Initializer;
99
98
  class APIService extends BaseService_1.BaseService {
100
- static nextLogID = 0;
101
- version = "3.8.3";
99
+ version = "3.8.5";
102
100
  options;
103
101
  monitor = null;
104
102
  started = new Date();
@@ -112,7 +110,7 @@ class APIService extends BaseService_1.BaseService {
112
110
  const self = "http://localhost:" + this.options.port;
113
111
  if (!this.options.corsHostWhiteList.find(val => val === self))
114
112
  this.options.corsHostWhiteList.push();
115
- exports.REQ_MONITOR_USERS.listener = async () => this.options.access.monitor ?? this.options.monitor ?? [];
113
+ exports.REQ_MONITOR_USERS.listener = async () => this.options.access.monitor ?? [];
116
114
  exports.REQ_DOC_USERS.listener = async () => this.options.access.documentation ?? [];
117
115
  this.options.endpoints.push(new Monitor_1.Monitor(this.options));
118
116
  this.options.endpoints.push(new Documentation_1.Documentation(this.options));
@@ -124,21 +122,7 @@ class APIService extends BaseService_1.BaseService {
124
122
  exports.REQ_HTTP_REQUESTS_COUNT.listener = async () => this.requestsCount;
125
123
  }
126
124
  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
- };
125
+ exports.REQ_HTTP_LOG.listener = async (_) => this.netLog;
142
126
  exports.REQ_INTERNAL_CALL.listener = async (req) => {
143
127
  for (let i of this.options.endpoints) {
144
128
  if (!i || !i.endpoints)
@@ -170,7 +154,17 @@ class APIService extends BaseService_1.BaseService {
170
154
  error: DefaultErrors_1.default.FILE_TOO_LARGE,
171
155
  data: null,
172
156
  httpStatus: 413,
173
- }, +new Date(), req.path);
157
+ }, +new Date(), req.path, {
158
+ endpoint: req.path,
159
+ headers: req.headers,
160
+ method: req.method,
161
+ data: req.body,
162
+ params: req.params,
163
+ interceptorResult: null,
164
+ raw: req,
165
+ response: undefined,
166
+ files: undefined
167
+ });
174
168
  },
175
169
  limits: { fileSize: this.options.fileLimit },
176
170
  useTempFiles: true,
@@ -184,12 +178,6 @@ class APIService extends BaseService_1.BaseService {
184
178
  return;
185
179
  }
186
180
  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
181
  let responseError = DefaultErrors_1.default.UNKNOWN_REQUEST;
194
182
  if (typeof err === "object" && err.status === 400 && 'body' in err && err.type === 'entity.parse.failed') {
195
183
  responseError = DefaultErrors_1.default.JSON_MALFORMED;
@@ -198,7 +186,17 @@ class APIService extends BaseService_1.BaseService {
198
186
  error: responseError,
199
187
  data: null,
200
188
  httpStatus: 400
201
- }, tme, "", log);
189
+ }, tme, "", {
190
+ endpoint: "",
191
+ headers: req.headers,
192
+ method: req.method,
193
+ data: req.body,
194
+ params: req.params,
195
+ interceptorResult: null,
196
+ raw: req,
197
+ response: undefined,
198
+ files: undefined
199
+ });
202
200
  });
203
201
  const corsOptions = {
204
202
  origin: (origin, callback) => {
@@ -219,16 +217,6 @@ class APIService extends BaseService_1.BaseService {
219
217
  app.all(ep, async (req, res) => {
220
218
  this.requestsCount++;
221
219
  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
220
  const execute = async () => {
233
221
  const body = req.body;
234
222
  if (req.query && typeof req.query === "object") {
@@ -262,10 +250,10 @@ class APIService extends BaseService_1.BaseService {
262
250
  stack = [e];
263
251
  }
264
252
  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);
253
+ this.sendResponse(req.get("Referer") ?? "", res, { error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message } }, tme, ep, httpRequest);
266
254
  return;
267
255
  }
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);
256
+ 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
257
  return;
270
258
  }
271
259
  }
@@ -292,7 +280,7 @@ class APIService extends BaseService_1.BaseService {
292
280
  const httpRequestBound = bindRequestToOptions(this.options, httpRequest);
293
281
  interceptorResult = await this.options.interceptor.intercept(httpRequest);
294
282
  if (DefaultErrors_1.ErrorUtils.isError(interceptorResult) && !allowInterceptorError) {
295
- this.sendResponse(req.get("Referer") ?? "", res, interceptorResult, tme, ep, log, httpRequest);
283
+ this.sendResponse(req.get("Referer") ?? "", res, interceptorResult, tme, ep, httpRequest);
296
284
  return;
297
285
  }
298
286
  httpRequestBound.interceptorResult = interceptorResult;
@@ -301,7 +289,7 @@ class APIService extends BaseService_1.BaseService {
301
289
  }
302
290
  const precheck = await i.__precheck(httpRequest);
303
291
  if (precheck && precheck.error) {
304
- this.sendResponse(req.get("Referer") ?? "", res, precheck, tme, ep, log, httpRequest);
292
+ this.sendResponse(req.get("Referer") ?? "", res, precheck, tme, ep, httpRequest);
305
293
  return;
306
294
  }
307
295
  httpRequest.precheck = precheck;
@@ -337,10 +325,10 @@ class APIService extends BaseService_1.BaseService {
337
325
  error: { ...DefaultErrors_1.default.DB_ERROR, details: e.message }
338
326
  };
339
327
  }
340
- this.sendResponse(req.get("Referer") ?? "", res, data, tme, ep, log, httpRequest);
328
+ this.sendResponse(req.get("Referer") ?? "", res, data, tme, ep, httpRequest);
341
329
  return;
342
330
  }
343
- this.sendResponse(req.get("Referer") ?? "", res, result, tme, ep, log, httpRequest);
331
+ this.sendResponse(req.get("Referer") ?? "", res, result, tme, ep, httpRequest);
344
332
  };
345
333
  execute();
346
334
  });
@@ -352,23 +340,51 @@ class APIService extends BaseService_1.BaseService {
352
340
  error: DefaultErrors_1.default.UNKNOWN_REQUEST,
353
341
  data: null,
354
342
  httpStatus: 404
355
- }, tme, req.path);
343
+ }, tme, req.path, {
344
+ endpoint: req.path,
345
+ headers: req.headers,
346
+ method: req.method,
347
+ data: req.body,
348
+ params: req.params,
349
+ interceptorResult: null,
350
+ raw: req,
351
+ response: undefined,
352
+ files: undefined
353
+ });
356
354
  });
357
355
  server.listen(this.options.port, () => {
358
356
  (0, LogService_1.logAPI)('${APIService.js}', 'API Service started at: ' + this.options.port + ", with base endpoint:" + this.options.baseEndPoint + ", ver.: " + this.version);
359
357
  });
360
358
  }
361
- async sendResponse(ref, res, data, requestTime, endpoint, log, req) {
359
+ addNetlog(data, req, created, time) {
360
+ const logItem = {
361
+ id: nextLogID++,
362
+ created: created,
363
+ time: time,
364
+ request: {
365
+ endpoint: req?.endpoint,
366
+ headers: req?.headers,
367
+ method: req?.method,
368
+ data: req?.data,
369
+ params: req?.params,
370
+ interceptorResult: req?.interceptorResult
371
+ },
372
+ response: data
373
+ };
374
+ this.netLog.push(logItem);
375
+ if (this.netLog.length > 100)
376
+ this.netLog.shift();
377
+ }
378
+ async sendResponse(ref, res, data, requestTime, endpoint, req) {
362
379
  if (data.blockResponse) {
363
- if (log)
364
- log.error = "Response blocked";
365
- if (this.options.onNetworkLog && log)
366
- this.options.onNetworkLog(log);
380
+ (0, LogService_1.logAPI)("Response blocked");
381
+ if (req)
382
+ this.addNetlog(data, req, requestTime, 0);
367
383
  return;
368
384
  }
369
385
  if (this.options.postproducer) {
370
386
  try {
371
- data = await this.options.postproducer(req, res, data, requestTime, endpoint, log);
387
+ data = await this.options.postproducer(req, res, data, requestTime, endpoint);
372
388
  }
373
389
  catch (e) {
374
390
  (0, LogService_1.logError)("Postproducer error", e);
@@ -381,37 +397,28 @@ class APIService extends BaseService_1.BaseService {
381
397
  data.endpoint = endpoint ?? "no_endpoint";
382
398
  if (this.options.appVersion)
383
399
  data.version = this.options.appVersion;
384
- if (log) {
385
- log.time = data.responseTime;
386
- log.referer = ref;
387
- }
388
400
  MonitorService_1.S_STAT_REGISTRATE_REQUEST.invoke(data);
389
401
  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);
402
+ (0, LogService_1.logAPI)("Connection already closed, can't send response for: " + data.endpoint);
394
403
  }
395
404
  else {
396
405
  try {
397
406
  if (data.file) {
398
407
  res.sendFile(data.file, err => {
399
408
  if (err) {
400
- if (log)
401
- log.error = "Can't send file: " + data.file;
409
+ (0, LogService_1.logError)("Can't send file: " + data.file);
402
410
  this.sendResponse(ref, res, {
403
411
  error: DefaultErrors_1.default.CANT_SEND_FILE,
404
412
  data: null,
405
413
  httpStatus: 500
406
- }, requestTime, data.endpoint);
414
+ }, requestTime, data.endpoint, req);
407
415
  }
408
416
  });
409
417
  return;
410
418
  }
411
419
  if (data.redirect) {
412
420
  res.redirect(data.redirect);
413
- if (log)
414
- log.response = { redirect: data.redirect };
421
+ (0, LogService_1.logAPI)("redirect: " + data.redirect);
415
422
  }
416
423
  else {
417
424
  if (data.headers) {
@@ -424,34 +431,20 @@ class APIService extends BaseService_1.BaseService {
424
431
  res.statusCode = data.httpStatus ?? 200;
425
432
  if (data.rawResponse) {
426
433
  res.send(data.data);
427
- if (log)
428
- log.response = this.checkDataLength(data);
434
+ (0, LogService_1.logAPI)(this.checkDataLength(data));
429
435
  }
430
436
  else {
431
437
  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
- }
438
+ (0, LogService_1.logAPI)(this.checkDataLength(data));
439
+ if (data.error)
440
+ (0, LogService_1.logError)(data.error.message);
438
441
  }
439
442
  }
440
443
  }
441
444
  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";
445
+ console.error(e);
446
446
  }
447
447
  }
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
448
  }
456
449
  checkDataLength(data, result, lvl) {
457
450
  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.5",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",