badmfck-api-server 3.9.93 → 3.9.95
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 +90 -41
- 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
|
@@ -50,7 +50,7 @@ function defaultOptions() {
|
|
|
50
50
|
return {
|
|
51
51
|
port: 8080,
|
|
52
52
|
baseEndPoint: "/api/",
|
|
53
|
-
corsHostWhiteList: ["localhost:3000"],
|
|
53
|
+
corsHostWhiteList: ["http://localhost:3000"],
|
|
54
54
|
endpoints: [],
|
|
55
55
|
jsonLimit: "10mb",
|
|
56
56
|
projectName: "Application project",
|
|
@@ -77,7 +77,7 @@ exports.REQ_HTTP_REQUESTS_COUNT = new badmfck_signal_1.Req(undefined, "REQ_HTTP_
|
|
|
77
77
|
exports.REQ_HTTP_SERVER = new badmfck_signal_1.Req(undefined, "REQ_HTTP_SERVER");
|
|
78
78
|
exports.REQ_INTERNAL_CALL = new badmfck_signal_1.Req(undefined, "REQ_INTERNAL_CALL");
|
|
79
79
|
exports.REQ_MONITOR_USERS = new badmfck_signal_1.Req(undefined, "REQ_MONITOR_USERS");
|
|
80
|
-
exports.REQ_DOC_USERS = new badmfck_signal_1.Req(undefined, "
|
|
80
|
+
exports.REQ_DOC_USERS = new badmfck_signal_1.Req(undefined, "REQ_DOC_USERS");
|
|
81
81
|
const activeServices = [];
|
|
82
82
|
async function Initializer(services) {
|
|
83
83
|
services.push(new StatService_1.StatService());
|
|
@@ -105,7 +105,18 @@ class APIService extends BaseService_1.BaseService {
|
|
|
105
105
|
this.options.corsHostWhiteList = [];
|
|
106
106
|
const self = "http://localhost:" + this.options.port;
|
|
107
107
|
if (!this.options.corsHostWhiteList.find(val => val === self))
|
|
108
|
-
this.options.corsHostWhiteList.push();
|
|
108
|
+
this.options.corsHostWhiteList.push(self);
|
|
109
|
+
const list = [];
|
|
110
|
+
for (let h of this.options.corsHostWhiteList) {
|
|
111
|
+
h = h.replace(/\/$/, "");
|
|
112
|
+
if (!/^https?:\/\//i.test(h)) {
|
|
113
|
+
list.push(`http://${h}`, `https://${h}`);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
list.push(h);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this.options.corsHostWhiteList = Array.from(new Set(list));
|
|
109
120
|
exports.REQ_MONITOR_USERS.listener = async () => this.options.access.monitor ?? [];
|
|
110
121
|
exports.REQ_DOC_USERS.listener = async () => this.options.access.documentation ?? [];
|
|
111
122
|
this.options.endpoints.push(new Monitor_1.Monitor(this.options));
|
|
@@ -142,8 +153,8 @@ class APIService extends BaseService_1.BaseService {
|
|
|
142
153
|
exports.REQ_HTTP_SERVER.listener = async (_) => { return { express: app, http: server }; };
|
|
143
154
|
if (this.options.isProductionEnvironment)
|
|
144
155
|
app.set("env", 'production');
|
|
145
|
-
app.use(express_1.default.json({ limit: '10mb' }));
|
|
146
|
-
app.use(express_1.default.urlencoded({ limit: '10mb', extended: true }));
|
|
156
|
+
app.use(express_1.default.json({ limit: this.options.jsonLimit ?? '10mb' }));
|
|
157
|
+
app.use(express_1.default.urlencoded({ limit: this.options.jsonLimit ?? '10mb', extended: true }));
|
|
147
158
|
app.use((0, express_fileupload_1.default)({
|
|
148
159
|
limitHandler: (req, res, next) => {
|
|
149
160
|
this.sendResponse(req.get("Referer") ?? "", res, {
|
|
@@ -161,6 +172,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
161
172
|
response: undefined,
|
|
162
173
|
files: undefined
|
|
163
174
|
});
|
|
175
|
+
return;
|
|
164
176
|
},
|
|
165
177
|
limits: { fileSize: this.options.fileLimit },
|
|
166
178
|
useTempFiles: true,
|
|
@@ -168,7 +180,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
168
180
|
tempFileDir: this.options.fileTempDir,
|
|
169
181
|
abortOnLimit: true
|
|
170
182
|
}));
|
|
171
|
-
app.use(
|
|
183
|
+
app.use((err, req, resp, next) => {
|
|
172
184
|
if (!err) {
|
|
173
185
|
next();
|
|
174
186
|
return;
|
|
@@ -193,15 +205,53 @@ class APIService extends BaseService_1.BaseService {
|
|
|
193
205
|
response: undefined,
|
|
194
206
|
files: undefined
|
|
195
207
|
});
|
|
208
|
+
return;
|
|
196
209
|
});
|
|
210
|
+
const corsSet = new Set(this.options.corsHostWhiteList.map(x => String(x).replace(/\/$/, "")));
|
|
197
211
|
const corsOptions = {
|
|
198
212
|
origin: (origin, callback) => {
|
|
199
|
-
|
|
200
|
-
|
|
213
|
+
if (!origin)
|
|
214
|
+
return callback(null, true);
|
|
215
|
+
try {
|
|
216
|
+
const o = new URL(String(origin));
|
|
217
|
+
const originNorm = o.origin.replace(/\/$/, "");
|
|
218
|
+
const hostNorm = o.host.replace(/\/$/, "");
|
|
219
|
+
const ok = corsSet.has(originNorm);
|
|
220
|
+
return callback(null, ok);
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return callback(null, false);
|
|
224
|
+
}
|
|
201
225
|
},
|
|
202
226
|
credentials: true
|
|
203
227
|
};
|
|
204
228
|
app.use((0, cors_1.default)(corsOptions));
|
|
229
|
+
app.use((req, res, next) => {
|
|
230
|
+
const originHeader = req.headers.origin;
|
|
231
|
+
if (!originHeader)
|
|
232
|
+
return next();
|
|
233
|
+
let originNorm;
|
|
234
|
+
try {
|
|
235
|
+
originNorm = new URL(String(originHeader)).origin.replace(/\/$/, "");
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
res.status(403).send({
|
|
239
|
+
error: { ...DefaultErrors_1.default.FORBIDDEN, details: "Invalid Origin header" },
|
|
240
|
+
data: null,
|
|
241
|
+
httpStatus: 403,
|
|
242
|
+
});
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (!corsSet.has(originNorm)) {
|
|
246
|
+
res.status(403).send({
|
|
247
|
+
error: { ...DefaultErrors_1.default.FORBIDDEN, details: `Origin not allowed: ${originNorm}` },
|
|
248
|
+
data: null,
|
|
249
|
+
httpStatus: 403,
|
|
250
|
+
});
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
return next();
|
|
254
|
+
});
|
|
205
255
|
BaseEndpoint_1.BaseEndpoint.setEntryPoint(this.options.baseEndPoint);
|
|
206
256
|
for (let i of this.options.endpoints) {
|
|
207
257
|
await i.init();
|
|
@@ -214,17 +264,17 @@ class APIService extends BaseService_1.BaseService {
|
|
|
214
264
|
this.requestsCount++;
|
|
215
265
|
const tme = +new Date();
|
|
216
266
|
const execute = async () => {
|
|
217
|
-
const body = req.body;
|
|
267
|
+
const body = { ...(req.body ?? {}) };
|
|
218
268
|
if (req.query && typeof req.query === "object") {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
269
|
+
const keys = Object.keys(req.query);
|
|
270
|
+
for (let k of keys)
|
|
271
|
+
body[k] = req.query[k];
|
|
222
272
|
}
|
|
223
273
|
let httpRequest = {
|
|
224
274
|
raw: req,
|
|
225
275
|
response: res,
|
|
226
276
|
method: req.method,
|
|
227
|
-
data:
|
|
277
|
+
data: body,
|
|
228
278
|
params: req.params,
|
|
229
279
|
headers: req.headers,
|
|
230
280
|
endpoint: ep,
|
|
@@ -324,7 +374,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
324
374
|
}
|
|
325
375
|
this.sendResponse(req.get("Referer") ?? "", res, result, tme, ep, httpRequest);
|
|
326
376
|
};
|
|
327
|
-
execute();
|
|
377
|
+
return execute();
|
|
328
378
|
});
|
|
329
379
|
}
|
|
330
380
|
}
|
|
@@ -359,15 +409,17 @@ class APIService extends BaseService_1.BaseService {
|
|
|
359
409
|
endpoint: req?.endpoint,
|
|
360
410
|
headers: req?.headers,
|
|
361
411
|
method: req?.method,
|
|
362
|
-
data: req?.data,
|
|
412
|
+
data: this.checkDataLength(req?.data),
|
|
363
413
|
params: req?.params,
|
|
364
414
|
interceptorResult: req?.interceptorResult
|
|
365
415
|
},
|
|
366
|
-
response: data
|
|
416
|
+
response: this.checkDataLength(data),
|
|
367
417
|
};
|
|
368
418
|
this.netLog.push(logItem);
|
|
369
419
|
if (this.netLog.length > 100)
|
|
370
420
|
this.netLog.shift();
|
|
421
|
+
if (nextLogID > Number.MAX_SAFE_INTEGER - 1000)
|
|
422
|
+
nextLogID = 0;
|
|
371
423
|
}
|
|
372
424
|
async sendResponse(ref, res, data, requestTime, endpoint, req) {
|
|
373
425
|
if (data.blockResponse) {
|
|
@@ -392,7 +444,7 @@ class APIService extends BaseService_1.BaseService {
|
|
|
392
444
|
if (this.options.appVersion)
|
|
393
445
|
data.version = this.options.appVersion;
|
|
394
446
|
MonitorService_1.S_STAT_REGISTRATE_REQUEST.invoke(data);
|
|
395
|
-
if (res.destroyed || res.
|
|
447
|
+
if (res.socket?.destroyed || res.writableEnded || res.headersSent || (res.destroyed !== undefined && res.destroyed)) {
|
|
396
448
|
(0, LogService_1.logAPI)("Connection already closed, can't send response for: " + data.endpoint);
|
|
397
449
|
}
|
|
398
450
|
else {
|
|
@@ -401,11 +453,17 @@ class APIService extends BaseService_1.BaseService {
|
|
|
401
453
|
res.sendFile(data.file, err => {
|
|
402
454
|
if (err) {
|
|
403
455
|
(0, LogService_1.logError)("Can't send file: " + data.file);
|
|
404
|
-
|
|
405
|
-
error: DefaultErrors_1.default.CANT_SEND_FILE,
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
456
|
+
if (!res.headersSent && !res.writableEnded) {
|
|
457
|
+
res.status(500).send({ error: DefaultErrors_1.default.CANT_SEND_FILE, data: null });
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
try {
|
|
462
|
+
res.destroy?.(err);
|
|
463
|
+
}
|
|
464
|
+
catch { }
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
409
467
|
}
|
|
410
468
|
else {
|
|
411
469
|
if (req)
|
|
@@ -447,27 +505,18 @@ class APIService extends BaseService_1.BaseService {
|
|
|
447
505
|
this.addNetlog(data, req, requestTime, 0);
|
|
448
506
|
}
|
|
449
507
|
checkDataLength(data, result, lvl) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
508
|
+
let json = "";
|
|
509
|
+
try {
|
|
510
|
+
json = JSON.stringify(data, (k, v) => {
|
|
511
|
+
if (typeof v === 'string' && v.length > 255)
|
|
512
|
+
return v.slice(0, 255) + `...(${v.length})`;
|
|
513
|
+
return v;
|
|
514
|
+
});
|
|
456
515
|
}
|
|
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
|
-
}
|
|
516
|
+
catch (e) {
|
|
517
|
+
json = "[unserializable data]";
|
|
469
518
|
}
|
|
470
|
-
return
|
|
519
|
+
return json.length > 500 ? json.slice(0, 500) + `...(total ${json.length})` : json;
|
|
471
520
|
}
|
|
472
521
|
}
|
|
473
522
|
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;
|