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
|
52
|
-
interceptor?: I;
|
53
|
-
})
|
54
|
-
export declare const
|
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
|
-
|
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.
|
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
|
52
|
+
function defaultOptions() {
|
54
53
|
return {
|
55
|
-
port:
|
56
|
-
|
57
|
-
|
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
|
-
|
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
|
-
|
75
|
-
|
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.
|
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
|
-
|
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 ??
|
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 (
|
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, "",
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
-
|
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
|
-
|
364
|
-
|
365
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
433
|
-
|
434
|
-
|
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
|
-
|
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;
|