badmfck-api-server 3.9.93 → 3.9.94
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.
- package/dist/apiServer/APIService.js +78 -48
- package/dist/apiServer/BaseEndpoint.d.ts +7 -1
- package/dist/apiServer/BaseEndpoint.js +149 -42
- package/dist/apiServer/external/ExternalService.js +15 -3
- package/dist/apiServer/external/MicroserviceClient.d.ts +4 -0
- package/dist/apiServer/external/MicroserviceClient.js +10 -0
- package/dist/apiServer/external/MicroserviceHost.d.ts +4 -0
- package/dist/apiServer/external/MicroserviceHost.js +10 -0
- package/dist/apiServer/structures/Interfaces.d.ts +1 -0
- package/package.json +1 -1
|
@@ -29,7 +29,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
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.getDefaultOptions = void 0;
|
|
30
30
|
const express_1 = __importDefault(require("express"));
|
|
31
31
|
const BaseService_1 = require("./BaseService");
|
|
32
|
-
const cors_1 = __importDefault(require("cors"));
|
|
33
32
|
const BaseEndpoint_1 = require("./BaseEndpoint");
|
|
34
33
|
const DefaultErrors_1 = __importStar(require("./structures/DefaultErrors"));
|
|
35
34
|
const badmfck_signal_1 = require("badmfck-signal");
|
|
@@ -50,7 +49,7 @@ function defaultOptions() {
|
|
|
50
49
|
return {
|
|
51
50
|
port: 8080,
|
|
52
51
|
baseEndPoint: "/api/",
|
|
53
|
-
corsHostWhiteList: ["localhost:3000"],
|
|
52
|
+
corsHostWhiteList: ["http://localhost:3000"],
|
|
54
53
|
endpoints: [],
|
|
55
54
|
jsonLimit: "10mb",
|
|
56
55
|
projectName: "Application project",
|
|
@@ -77,7 +76,7 @@ exports.REQ_HTTP_REQUESTS_COUNT = new badmfck_signal_1.Req(undefined, "REQ_HTTP_
|
|
|
77
76
|
exports.REQ_HTTP_SERVER = new badmfck_signal_1.Req(undefined, "REQ_HTTP_SERVER");
|
|
78
77
|
exports.REQ_INTERNAL_CALL = new badmfck_signal_1.Req(undefined, "REQ_INTERNAL_CALL");
|
|
79
78
|
exports.REQ_MONITOR_USERS = new badmfck_signal_1.Req(undefined, "REQ_MONITOR_USERS");
|
|
80
|
-
exports.REQ_DOC_USERS = new badmfck_signal_1.Req(undefined, "
|
|
79
|
+
exports.REQ_DOC_USERS = new badmfck_signal_1.Req(undefined, "REQ_DOC_USERS");
|
|
81
80
|
const activeServices = [];
|
|
82
81
|
async function Initializer(services) {
|
|
83
82
|
services.push(new StatService_1.StatService());
|
|
@@ -105,7 +104,18 @@ class APIService extends BaseService_1.BaseService {
|
|
|
105
104
|
this.options.corsHostWhiteList = [];
|
|
106
105
|
const self = "http://localhost:" + this.options.port;
|
|
107
106
|
if (!this.options.corsHostWhiteList.find(val => val === self))
|
|
108
|
-
this.options.corsHostWhiteList.push();
|
|
107
|
+
this.options.corsHostWhiteList.push(self);
|
|
108
|
+
const list = [];
|
|
109
|
+
for (let h of this.options.corsHostWhiteList) {
|
|
110
|
+
h = h.replace(/\/$/, "");
|
|
111
|
+
if (!/^https?:\/\//i.test(h)) {
|
|
112
|
+
list.push(`http://${h}`, `https://${h}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
list.push(h);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
this.options.corsHostWhiteList = Array.from(new Set(list));
|
|
109
119
|
exports.REQ_MONITOR_USERS.listener = async () => this.options.access.monitor ?? [];
|
|
110
120
|
exports.REQ_DOC_USERS.listener = async () => this.options.access.documentation ?? [];
|
|
111
121
|
this.options.endpoints.push(new Monitor_1.Monitor(this.options));
|
|
@@ -142,8 +152,8 @@ class APIService extends BaseService_1.BaseService {
|
|
|
142
152
|
exports.REQ_HTTP_SERVER.listener = async (_) => { return { express: app, http: server }; };
|
|
143
153
|
if (this.options.isProductionEnvironment)
|
|
144
154
|
app.set("env", 'production');
|
|
145
|
-
app.use(express_1.default.json({ limit: '10mb' }));
|
|
146
|
-
app.use(express_1.default.urlencoded({ limit: '10mb', extended: true }));
|
|
155
|
+
app.use(express_1.default.json({ limit: this.options.jsonLimit ?? '10mb' }));
|
|
156
|
+
app.use(express_1.default.urlencoded({ limit: this.options.jsonLimit ?? '10mb', extended: true }));
|
|
147
157
|
app.use((0, express_fileupload_1.default)({
|
|
148
158
|
limitHandler: (req, res, next) => {
|
|
149
159
|
this.sendResponse(req.get("Referer") ?? "", res, {
|
|
@@ -161,6 +171,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
161
171
|
response: undefined,
|
|
162
172
|
files: undefined
|
|
163
173
|
});
|
|
174
|
+
return;
|
|
164
175
|
},
|
|
165
176
|
limits: { fileSize: this.options.fileLimit },
|
|
166
177
|
useTempFiles: true,
|
|
@@ -168,7 +179,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
168
179
|
tempFileDir: this.options.fileTempDir,
|
|
169
180
|
abortOnLimit: true
|
|
170
181
|
}));
|
|
171
|
-
app.use(
|
|
182
|
+
app.use((err, req, resp, next) => {
|
|
172
183
|
if (!err) {
|
|
173
184
|
next();
|
|
174
185
|
return;
|
|
@@ -193,15 +204,35 @@ class APIService extends BaseService_1.BaseService {
|
|
|
193
204
|
response: undefined,
|
|
194
205
|
files: undefined
|
|
195
206
|
});
|
|
207
|
+
return;
|
|
208
|
+
});
|
|
209
|
+
const corsSet = new Set(this.options.corsHostWhiteList.map(x => String(x).replace(/\/$/, "")));
|
|
210
|
+
app.use((req, res, next) => {
|
|
211
|
+
const originHeader = req.headers.origin;
|
|
212
|
+
if (!originHeader)
|
|
213
|
+
return next();
|
|
214
|
+
let originNorm;
|
|
215
|
+
try {
|
|
216
|
+
originNorm = new URL(String(originHeader)).origin;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
res.status(403).send({
|
|
220
|
+
error: { ...DefaultErrors_1.default.FORBIDDEN, details: "Invalid Origin header" },
|
|
221
|
+
data: null,
|
|
222
|
+
httpStatus: 403,
|
|
223
|
+
});
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (!corsSet.has(originNorm)) {
|
|
227
|
+
res.status(403).send({
|
|
228
|
+
error: { ...DefaultErrors_1.default.FORBIDDEN, details: `Origin not allowed: ${originNorm}` },
|
|
229
|
+
data: null,
|
|
230
|
+
httpStatus: 403,
|
|
231
|
+
});
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
return next();
|
|
196
235
|
});
|
|
197
|
-
const corsOptions = {
|
|
198
|
-
origin: (origin, callback) => {
|
|
199
|
-
const originIsWhitelisted = this.options.corsHostWhiteList.includes(origin);
|
|
200
|
-
callback(null, originIsWhitelisted);
|
|
201
|
-
},
|
|
202
|
-
credentials: true
|
|
203
|
-
};
|
|
204
|
-
app.use((0, cors_1.default)(corsOptions));
|
|
205
236
|
BaseEndpoint_1.BaseEndpoint.setEntryPoint(this.options.baseEndPoint);
|
|
206
237
|
for (let i of this.options.endpoints) {
|
|
207
238
|
await i.init();
|
|
@@ -214,17 +245,17 @@ class APIService extends BaseService_1.BaseService {
|
|
|
214
245
|
this.requestsCount++;
|
|
215
246
|
const tme = +new Date();
|
|
216
247
|
const execute = async () => {
|
|
217
|
-
const body = req.body;
|
|
248
|
+
const body = { ...(req.body ?? {}) };
|
|
218
249
|
if (req.query && typeof req.query === "object") {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
250
|
+
const keys = Object.keys(req.query);
|
|
251
|
+
for (let k of keys)
|
|
252
|
+
body[k] = req.query[k];
|
|
222
253
|
}
|
|
223
254
|
let httpRequest = {
|
|
224
255
|
raw: req,
|
|
225
256
|
response: res,
|
|
226
257
|
method: req.method,
|
|
227
|
-
data:
|
|
258
|
+
data: body,
|
|
228
259
|
params: req.params,
|
|
229
260
|
headers: req.headers,
|
|
230
261
|
endpoint: ep,
|
|
@@ -324,7 +355,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
324
355
|
}
|
|
325
356
|
this.sendResponse(req.get("Referer") ?? "", res, result, tme, ep, httpRequest);
|
|
326
357
|
};
|
|
327
|
-
execute();
|
|
358
|
+
return execute();
|
|
328
359
|
});
|
|
329
360
|
}
|
|
330
361
|
}
|
|
@@ -359,15 +390,17 @@ class APIService extends BaseService_1.BaseService {
|
|
|
359
390
|
endpoint: req?.endpoint,
|
|
360
391
|
headers: req?.headers,
|
|
361
392
|
method: req?.method,
|
|
362
|
-
data: req?.data,
|
|
393
|
+
data: this.checkDataLength(req?.data),
|
|
363
394
|
params: req?.params,
|
|
364
395
|
interceptorResult: req?.interceptorResult
|
|
365
396
|
},
|
|
366
|
-
response: data
|
|
397
|
+
response: this.checkDataLength(data),
|
|
367
398
|
};
|
|
368
399
|
this.netLog.push(logItem);
|
|
369
400
|
if (this.netLog.length > 100)
|
|
370
401
|
this.netLog.shift();
|
|
402
|
+
if (nextLogID > Number.MAX_SAFE_INTEGER - 1000)
|
|
403
|
+
nextLogID = 0;
|
|
371
404
|
}
|
|
372
405
|
async sendResponse(ref, res, data, requestTime, endpoint, req) {
|
|
373
406
|
if (data.blockResponse) {
|
|
@@ -392,7 +425,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
392
425
|
if (this.options.appVersion)
|
|
393
426
|
data.version = this.options.appVersion;
|
|
394
427
|
MonitorService_1.S_STAT_REGISTRATE_REQUEST.invoke(data);
|
|
395
|
-
if (res.destroyed || res.
|
|
428
|
+
if (res.socket?.destroyed || res.writableEnded || res.headersSent || (res.destroyed !== undefined && res.destroyed)) {
|
|
396
429
|
(0, LogService_1.logAPI)("Connection already closed, can't send response for: " + data.endpoint);
|
|
397
430
|
}
|
|
398
431
|
else {
|
|
@@ -401,11 +434,17 @@ class APIService extends BaseService_1.BaseService {
|
|
|
401
434
|
res.sendFile(data.file, err => {
|
|
402
435
|
if (err) {
|
|
403
436
|
(0, LogService_1.logError)("Can't send file: " + data.file);
|
|
404
|
-
|
|
405
|
-
error: DefaultErrors_1.default.CANT_SEND_FILE,
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
437
|
+
if (!res.headersSent && !res.writableEnded) {
|
|
438
|
+
res.status(500).send({ error: DefaultErrors_1.default.CANT_SEND_FILE, data: null });
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
try {
|
|
443
|
+
res.destroy?.(err);
|
|
444
|
+
}
|
|
445
|
+
catch { }
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
409
448
|
}
|
|
410
449
|
else {
|
|
411
450
|
if (req)
|
|
@@ -447,27 +486,18 @@ class APIService extends BaseService_1.BaseService {
|
|
|
447
486
|
this.addNetlog(data, req, requestTime, 0);
|
|
448
487
|
}
|
|
449
488
|
checkDataLength(data, result, lvl) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
489
|
+
let json = "";
|
|
490
|
+
try {
|
|
491
|
+
json = JSON.stringify(data, (k, v) => {
|
|
492
|
+
if (typeof v === 'string' && v.length > 255)
|
|
493
|
+
return v.slice(0, 255) + `...(${v.length})`;
|
|
494
|
+
return v;
|
|
495
|
+
});
|
|
456
496
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
result = {};
|
|
460
|
-
let arrcnt = 100;
|
|
461
|
-
for (let i in data) {
|
|
462
|
-
result[i] = this.checkDataLength(data[i], result[i], lvl + 1);
|
|
463
|
-
arrcnt--;
|
|
464
|
-
if (arrcnt <= 0) {
|
|
465
|
-
result["..."] = "... total: " + Array.isArray(data) ? data.length : Object.keys(data).length;
|
|
466
|
-
break;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
497
|
+
catch (e) {
|
|
498
|
+
json = "[unserializable data]";
|
|
469
499
|
}
|
|
470
|
-
return
|
|
500
|
+
return json.length > 500 ? json.slice(0, 500) + `...(total ${json.length})` : json;
|
|
471
501
|
}
|
|
472
502
|
}
|
|
473
503
|
exports.APIService = APIService;
|
|
@@ -44,6 +44,7 @@ export declare class BaseEndpoint implements IBaseEndpoint {
|
|
|
44
44
|
ignoreInDocumentation: boolean;
|
|
45
45
|
private static entrypoint;
|
|
46
46
|
endpoint: string;
|
|
47
|
+
protected streamOptions: Record<string, any>;
|
|
47
48
|
static setEntryPoint: (ep: string) => void;
|
|
48
49
|
static getEntryPoint: () => string;
|
|
49
50
|
constructor(endpoint: string);
|
|
@@ -53,6 +54,11 @@ export declare class BaseEndpoint implements IBaseEndpoint {
|
|
|
53
54
|
__precheck(req: HTTPRequestVO): Promise<TransferPacketVO<any> | null>;
|
|
54
55
|
__execute(req: HTTPRequestVO): Promise<TransferPacketVO<any>>;
|
|
55
56
|
protected validateStructure(structure: any, req: HTTPRequestVO): Promise<void>;
|
|
56
|
-
protected createStream(req: HTTPRequestVO
|
|
57
|
+
protected createStream(req: HTTPRequestVO, opts: {
|
|
58
|
+
contentType?: string;
|
|
59
|
+
headers?: {
|
|
60
|
+
[key: string]: string;
|
|
61
|
+
};
|
|
62
|
+
}): HTTPRequestVO;
|
|
57
63
|
}
|
|
58
64
|
export {};
|
|
@@ -17,6 +17,7 @@ class BaseEndpoint {
|
|
|
17
17
|
ignoreInDocumentation = false;
|
|
18
18
|
static entrypoint = "/";
|
|
19
19
|
endpoint = "";
|
|
20
|
+
streamOptions = {};
|
|
20
21
|
static setEntryPoint = (ep) => {
|
|
21
22
|
this.entrypoint = ep;
|
|
22
23
|
if (!this.entrypoint.endsWith("/")) {
|
|
@@ -73,43 +74,65 @@ class BaseEndpoint {
|
|
|
73
74
|
for (let i of this.endpoints) {
|
|
74
75
|
let targetEP = BaseEndpoint.entrypoint + i.endpoint;
|
|
75
76
|
targetEP = targetEP.replaceAll("//", "/");
|
|
76
|
-
if (targetEP
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
if (targetEP !== req.endpoint)
|
|
78
|
+
continue;
|
|
79
|
+
const httpMethod = req.method.toUpperCase();
|
|
80
|
+
const resolveAsStream = () => {
|
|
81
|
+
if (i.asStream)
|
|
82
|
+
return true;
|
|
83
|
+
if (i.handler && typeof i.handler === "object") {
|
|
84
|
+
const h = i.handler[httpMethod];
|
|
85
|
+
if (h && typeof h === "object" && "asStream" in h && h.asStream)
|
|
86
|
+
return true;
|
|
83
87
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
88
|
+
return false;
|
|
89
|
+
};
|
|
90
|
+
const asStream = resolveAsStream();
|
|
91
|
+
if (i.handler && typeof i.handler === "function") {
|
|
92
|
+
if (req.data && req.data.validationModel && req.data.validationModel === "1")
|
|
93
|
+
return { data: i.validationModel };
|
|
94
|
+
if (i.validationModel)
|
|
95
|
+
await this.validateStructure(i.validationModel, req);
|
|
96
|
+
if (asStream)
|
|
97
|
+
req = this.createStream(req, this.streamOptions[i.endpoint] ?? {});
|
|
98
|
+
const result = await i.handler.call(this, req);
|
|
99
|
+
if (asStream)
|
|
100
|
+
return { blockResponse: true, data: null };
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
if (i.handler && i.handler[httpMethod] && typeof i.handler[httpMethod] === "function") {
|
|
104
|
+
if (req.data && req.data.validationModel && req.data.validationModel === "1")
|
|
105
|
+
return { data: i.validationModel };
|
|
106
|
+
if (i.validationModel)
|
|
107
|
+
await this.validateStructure(i.validationModel, req);
|
|
108
|
+
if (asStream)
|
|
109
|
+
req = this.createStream(req, this.streamOptions[i.endpoint] ?? {});
|
|
110
|
+
const result = await i.handler[httpMethod].call(this, req);
|
|
111
|
+
if (asStream)
|
|
112
|
+
return { blockResponse: true, data: null };
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
if (i.handler
|
|
116
|
+
&& i.handler[httpMethod]
|
|
117
|
+
&& typeof i.handler[httpMethod] === "object"
|
|
118
|
+
&& "controller" in i.handler[httpMethod]
|
|
119
|
+
&& typeof i.handler[httpMethod].controller === "function") {
|
|
120
|
+
const vmodel = i.handler[httpMethod].validationModel;
|
|
121
|
+
if (req.data && req.data.validationModel && req.data.validationModel === "1")
|
|
122
|
+
return { data: vmodel };
|
|
123
|
+
if (vmodel)
|
|
124
|
+
await this.validateStructure(vmodel, req);
|
|
125
|
+
if (asStream)
|
|
126
|
+
req = this.createStream(req, this.streamOptions[i.endpoint] ?? {});
|
|
127
|
+
const result = await i.handler[httpMethod].controller.call(this, req);
|
|
128
|
+
if (asStream)
|
|
129
|
+
return { blockResponse: true, data: null };
|
|
130
|
+
return result;
|
|
112
131
|
}
|
|
132
|
+
return {
|
|
133
|
+
error: { ...DefaultErrors_1.default.METHOD_NOT_ALLOWED, details: "No handler for " + httpMethod },
|
|
134
|
+
data: null
|
|
135
|
+
};
|
|
113
136
|
}
|
|
114
137
|
}
|
|
115
138
|
(0, LogService_1.logWarn)("${BaseEndpoint.js}", "Unhandled entrypoint: " + this.endpoint);
|
|
@@ -128,17 +151,101 @@ class BaseEndpoint {
|
|
|
128
151
|
throw { ...DefaultErrors_1.default.WRONG_PARAMS, details: report };
|
|
129
152
|
Validator_1.Validator.filterStructure(structure, req.data);
|
|
130
153
|
}
|
|
131
|
-
createStream(req) {
|
|
154
|
+
createStream(req, opts) {
|
|
132
155
|
const res = req.response;
|
|
133
|
-
res.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
if (res.headersSent)
|
|
157
|
+
throw { ...DefaultErrors_1.default.INTERNAL_SERVER_ERROR, details: "Headers already sent, can't create stream" };
|
|
158
|
+
res.statusCode = 200;
|
|
159
|
+
res.setHeader("Content-Type", opts?.contentType ?? "application/octet-stream");
|
|
160
|
+
res.setHeader("Transfer-Encoding", "chunked");
|
|
161
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
162
|
+
if (opts?.headers) {
|
|
163
|
+
for (let h in opts.headers) {
|
|
164
|
+
res.setHeader(h, opts.headers[h]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const stream = new stream_1.Readable({
|
|
168
|
+
read() {
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
let finished = false;
|
|
172
|
+
let timer;
|
|
173
|
+
const cleanup = () => {
|
|
174
|
+
if (finished)
|
|
175
|
+
return;
|
|
176
|
+
finished = true;
|
|
177
|
+
if (timer)
|
|
178
|
+
clearTimeout(timer);
|
|
179
|
+
try {
|
|
180
|
+
if (!stream.destroyed) {
|
|
181
|
+
stream.destroy();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
console.error("Error during stream cleanup:", e);
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
if (!res.writableEnded)
|
|
189
|
+
res.end();
|
|
190
|
+
}
|
|
191
|
+
catch { }
|
|
192
|
+
};
|
|
193
|
+
const endOk = () => {
|
|
194
|
+
if (finished)
|
|
195
|
+
return;
|
|
196
|
+
finished = true;
|
|
197
|
+
if (timer)
|
|
198
|
+
clearTimeout(timer);
|
|
199
|
+
try {
|
|
200
|
+
if (!stream.destroyed)
|
|
201
|
+
stream.push(null);
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
cleanup();
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
res.on('close', () => {
|
|
208
|
+
cleanup();
|
|
209
|
+
});
|
|
210
|
+
const setupTimer = () => {
|
|
211
|
+
if (finished)
|
|
212
|
+
return;
|
|
213
|
+
if (timer)
|
|
214
|
+
clearTimeout(timer);
|
|
215
|
+
timer = setTimeout(() => cleanup(), 60_000);
|
|
216
|
+
};
|
|
217
|
+
setupTimer();
|
|
218
|
+
const origPush = stream.push.bind(stream);
|
|
219
|
+
stream.push = (chunk, encoding) => {
|
|
220
|
+
if (chunk === null)
|
|
221
|
+
return origPush(null);
|
|
222
|
+
if (finished)
|
|
223
|
+
return false;
|
|
224
|
+
setupTimer();
|
|
225
|
+
return origPush(chunk, encoding);
|
|
226
|
+
};
|
|
227
|
+
req.raw?.on?.("aborted", () => {
|
|
228
|
+
cleanup();
|
|
229
|
+
try {
|
|
230
|
+
res.destroy?.();
|
|
231
|
+
}
|
|
232
|
+
catch { }
|
|
233
|
+
});
|
|
234
|
+
req.raw?.on?.("close", cleanup);
|
|
137
235
|
stream.on('error', (err) => {
|
|
138
|
-
console.error(
|
|
139
|
-
|
|
236
|
+
console.error("Stream error:", err);
|
|
237
|
+
cleanup();
|
|
238
|
+
try {
|
|
239
|
+
res.destroy?.(err);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
res.end();
|
|
243
|
+
}
|
|
140
244
|
});
|
|
245
|
+
res.on("finish", cleanup);
|
|
246
|
+
stream.pipe(res);
|
|
141
247
|
req.stream = stream;
|
|
248
|
+
req.endStream = (force) => force ? cleanup() : endOk();
|
|
142
249
|
return req;
|
|
143
250
|
}
|
|
144
251
|
}
|
|
@@ -33,6 +33,7 @@ const DefaultErrors_1 = __importStar(require("../structures/DefaultErrors"));
|
|
|
33
33
|
const Validator_1 = require("../helper/Validator");
|
|
34
34
|
const UID_1 = require("../helper/UID");
|
|
35
35
|
const crypto_1 = __importDefault(require("crypto"));
|
|
36
|
+
const __1 = require("../..");
|
|
36
37
|
exports.REQ_EXTERNAL_CALL = new badmfck_signal_1.Req(undefined, "REQ_EXTERNAL_CALL");
|
|
37
38
|
exports.REQ_XT = new badmfck_signal_1.Req(undefined, "REQ_XT");
|
|
38
39
|
exports.REQ_XT.listener = async ({ id, req }) => {
|
|
@@ -88,10 +89,21 @@ class ExternalService extends BaseService_1.BaseService {
|
|
|
88
89
|
const encrypted = this.encrypt({ requestName, requestData });
|
|
89
90
|
if (this.options.url.endsWith("/"))
|
|
90
91
|
this.options.url = this.options.url.substring(0, this.options.url.length - 1);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
const resp = await __1.Http.post(this.options.url + "/external/call/" + this.options.id, encrypted.data, {
|
|
93
|
+
headers: {
|
|
94
|
+
"authorization": encrypted.authorization,
|
|
95
|
+
"Content-Type": "application/json",
|
|
96
|
+
"Accept": "application/json"
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (!resp.ok) {
|
|
100
|
+
return { ...DefaultErrors_1.default.BAD_REQUEST, details: resp.details, stack: resp.error };
|
|
94
101
|
}
|
|
102
|
+
const json = await resp.data.json();
|
|
103
|
+
if (typeof json === "object" && "error" in json)
|
|
104
|
+
return json.error;
|
|
105
|
+
if (typeof json === "object" && "data" in json)
|
|
106
|
+
return json.data;
|
|
95
107
|
}
|
|
96
108
|
async onExternalCall(req) {
|
|
97
109
|
const data = this.decrypt(req);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MicroserviceClient = void 0;
|
|
4
|
+
const BaseService_1 = require("../BaseService");
|
|
5
|
+
class MicroserviceClient extends BaseService_1.BaseService {
|
|
6
|
+
constructor() {
|
|
7
|
+
super("MicroserviceClient");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.MicroserviceClient = MicroserviceClient;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MicroserviceHost = void 0;
|
|
4
|
+
const BaseService_1 = require("../BaseService");
|
|
5
|
+
class MicroserviceHost extends BaseService_1.BaseService {
|
|
6
|
+
constructor() {
|
|
7
|
+
super("MicroserviceHost");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.MicroserviceHost = MicroserviceHost;
|