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.
|
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
|
-
|
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
|
-
|
286
|
-
|
287
|
-
|
288
|
-
conn.
|
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
|
-
|
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
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
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
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
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() {
|