node-pluginsmanager-plugin 5.0.13 → 5.0.14
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/LICENSE +1 -1
- package/lib/cjs/checkers/RangeError/checkArrayLength.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkArrayLength.js +26 -26
- package/lib/cjs/checkers/RangeError/checkArrayLengthBetween.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkArrayLengthBetween.js +33 -33
- package/lib/cjs/checkers/RangeError/checkIntegerBetween.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkIntegerBetween.js +32 -32
- package/lib/cjs/checkers/RangeError/checkNonEmptyArray.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkNonEmptyArray.js +22 -22
- package/lib/cjs/checkers/RangeError/checkNonEmptyInteger.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkNonEmptyInteger.js +22 -22
- package/lib/cjs/checkers/RangeError/checkNonEmptyNumber.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkNonEmptyNumber.js +22 -22
- package/lib/cjs/checkers/RangeError/checkNonEmptyObject.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkNonEmptyObject.js +22 -22
- package/lib/cjs/checkers/RangeError/checkNonEmptyString.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkNonEmptyString.js +22 -22
- package/lib/cjs/checkers/RangeError/checkNumberBetween.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkNumberBetween.js +32 -32
- package/lib/cjs/checkers/RangeError/checkObjectLength.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkObjectLength.js +31 -31
- package/lib/cjs/checkers/RangeError/checkObjectLengthBetween.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkObjectLengthBetween.js +36 -36
- package/lib/cjs/checkers/RangeError/checkStringLength.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkStringLength.js +26 -26
- package/lib/cjs/checkers/RangeError/checkStringLengthBetween.d.ts +2 -2
- package/lib/cjs/checkers/RangeError/checkStringLengthBetween.js +33 -33
- package/lib/cjs/checkers/ReferenceError/checkExists.d.ts +2 -2
- package/lib/cjs/checkers/ReferenceError/checkExists.js +19 -19
- package/lib/cjs/checkers/TypeError/checkArray.d.ts +2 -2
- package/lib/cjs/checkers/TypeError/checkArray.js +22 -22
- package/lib/cjs/checkers/TypeError/checkBoolean.d.ts +2 -2
- package/lib/cjs/checkers/TypeError/checkBoolean.js +22 -22
- package/lib/cjs/checkers/TypeError/checkFunction.d.ts +2 -2
- package/lib/cjs/checkers/TypeError/checkFunction.js +22 -22
- package/lib/cjs/checkers/TypeError/checkInteger.d.ts +2 -2
- package/lib/cjs/checkers/TypeError/checkInteger.js +22 -22
- package/lib/cjs/checkers/TypeError/checkNumber.d.ts +2 -2
- package/lib/cjs/checkers/TypeError/checkNumber.js +22 -22
- package/lib/cjs/checkers/TypeError/checkObject.d.ts +2 -2
- package/lib/cjs/checkers/TypeError/checkObject.js +22 -22
- package/lib/cjs/checkers/TypeError/checkString.d.ts +2 -2
- package/lib/cjs/checkers/TypeError/checkString.js +22 -22
- package/lib/cjs/components/DescriptorUser.d.ts +27 -27
- package/lib/cjs/components/DescriptorUser.js +117 -117
- package/lib/cjs/components/Mediator.d.ts +28 -28
- package/lib/cjs/components/Mediator.js +145 -145
- package/lib/cjs/components/MediatorUser.d.ts +12 -12
- package/lib/cjs/components/MediatorUser.js +40 -40
- package/lib/cjs/components/NotFoundError.d.ts +2 -2
- package/lib/cjs/components/NotFoundError.js +7 -7
- package/lib/cjs/components/Orchestrator.d.ts +57 -57
- package/lib/cjs/components/Orchestrator.js +404 -404
- package/lib/cjs/components/Server.d.ts +55 -55
- package/lib/cjs/components/Server.js +560 -560
- package/lib/cjs/main.cjs +90 -90
- package/lib/cjs/main.d.cts +30 -30
- package/lib/cjs/utils/cleanSendedError.d.ts +1 -1
- package/lib/cjs/utils/cleanSendedError.js +24 -24
- package/lib/cjs/utils/descriptor/extractParams.d.ts +3 -3
- package/lib/cjs/utils/descriptor/extractParams.js +21 -21
- package/lib/cjs/utils/descriptor/extractPathMethodByOperationId.d.ts +8 -8
- package/lib/cjs/utils/descriptor/extractPathMethodByOperationId.js +34 -34
- package/lib/cjs/utils/descriptor/extractPattern.d.ts +2 -2
- package/lib/cjs/utils/descriptor/extractPattern.js +28 -28
- package/lib/cjs/utils/descriptor/extractSchemaType.d.ts +4 -4
- package/lib/cjs/utils/descriptor/extractSchemaType.js +18 -18
- package/lib/cjs/utils/file/checkFile.d.ts +1 -1
- package/lib/cjs/utils/file/checkFile.js +17 -17
- package/lib/cjs/utils/file/isFile.d.ts +1 -1
- package/lib/cjs/utils/file/isFile.js +19 -19
- package/lib/cjs/utils/file/readJSONFile.d.ts +1 -1
- package/lib/cjs/utils/file/readJSONFile.js +20 -24
- package/lib/cjs/utils/removeFirstSlash.d.ts +1 -1
- package/lib/cjs/utils/removeFirstSlash.js +8 -8
- package/lib/cjs/utils/request/extractBody.d.ts +7 -7
- package/lib/cjs/utils/request/extractBody.js +52 -52
- package/lib/cjs/utils/request/extractCookies.d.ts +4 -4
- package/lib/cjs/utils/request/extractCookies.js +53 -53
- package/lib/cjs/utils/request/extractIp.d.ts +1 -1
- package/lib/cjs/utils/request/extractIp.js +40 -40
- package/lib/cjs/utils/send.d.ts +2 -2
- package/lib/cjs/utils/send.js +57 -57
- package/lib/cjs/utils/serverCodes.d.ts +14 -14
- package/lib/cjs/utils/serverCodes.js +15 -15
- package/package.json +42 -32
- package/lib/cjs/utils/getUniqueID.d.ts +0 -1
- package/lib/cjs/utils/getUniqueID.js +0 -16
|
@@ -1,560 +1,560 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
// deps
|
|
7
|
-
// natives
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
// externals
|
|
11
|
-
const uniqid_1 = __importDefault(require("uniqid"));
|
|
12
|
-
// locals
|
|
13
|
-
const checkInteger_1 = require("../checkers/TypeError/checkInteger");
|
|
14
|
-
const checkNonEmptyObject_1 = require("../checkers/RangeError/checkNonEmptyObject");
|
|
15
|
-
const checkNonEmptyString_1 = require("../checkers/RangeError/checkNonEmptyString");
|
|
16
|
-
const extractPattern_1 = __importDefault(require("../utils/descriptor/extractPattern"));
|
|
17
|
-
const extractParams_1 = __importDefault(require("../utils/descriptor/extractParams"));
|
|
18
|
-
const extractSchemaType_1 = __importDefault(require("../utils/descriptor/extractSchemaType"));
|
|
19
|
-
const extractBody_1 = __importDefault(require("../utils/request/extractBody"));
|
|
20
|
-
const extractIp_1 = __importDefault(require("../utils/request/extractIp"));
|
|
21
|
-
const extractCookies_1 = __importDefault(require("../utils/request/extractCookies"));
|
|
22
|
-
const send_1 = __importDefault(require("../utils/send"));
|
|
23
|
-
const cleanSendedError_1 = __importDefault(require("../utils/cleanSendedError"));
|
|
24
|
-
const MediatorUser_1 = __importDefault(require("./MediatorUser"));
|
|
25
|
-
const NotFoundError_1 = __importDefault(require("./NotFoundError"));
|
|
26
|
-
const serverCodes_1 = __importDefault(require("../utils/serverCodes"));
|
|
27
|
-
// consts
|
|
28
|
-
const WEBSOCKET_STATE_OPEN = 1;
|
|
29
|
-
// module
|
|
30
|
-
// Please note the fact that "init" and "release" method MUST NOT be re-writted. Each child has is own init logic.
|
|
31
|
-
class Server extends MediatorUser_1.default {
|
|
32
|
-
// constructor
|
|
33
|
-
constructor(opt) {
|
|
34
|
-
super(opt);
|
|
35
|
-
this._socketServer = null;
|
|
36
|
-
this._checkParameters = true;
|
|
37
|
-
this._checkResponse = false;
|
|
38
|
-
this._cors = false;
|
|
39
|
-
}
|
|
40
|
-
// protected
|
|
41
|
-
_serverType() {
|
|
42
|
-
if (!this._socketServer) {
|
|
43
|
-
return "NO_SERVER";
|
|
44
|
-
}
|
|
45
|
-
else if (this._socketServer.clients && "function" === typeof this._socketServer.clients.forEach) {
|
|
46
|
-
return "WEBSOCKET";
|
|
47
|
-
}
|
|
48
|
-
else if (this._socketServer.sockets && "function" === typeof this._socketServer.sockets.emit) {
|
|
49
|
-
return "SOCKETIO";
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
return "UNKNOWN";
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// public
|
|
56
|
-
disableCheckParameters() {
|
|
57
|
-
this._checkParameters = false;
|
|
58
|
-
return this;
|
|
59
|
-
}
|
|
60
|
-
enableCheckParameters() {
|
|
61
|
-
this._checkParameters = true;
|
|
62
|
-
return this;
|
|
63
|
-
}
|
|
64
|
-
disableCheckResponse() {
|
|
65
|
-
this._checkResponse = false;
|
|
66
|
-
return this;
|
|
67
|
-
}
|
|
68
|
-
enableCheckResponse() {
|
|
69
|
-
this._checkResponse = true;
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
disableCors() {
|
|
73
|
-
this._cors = false;
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
enableCors() {
|
|
77
|
-
this._cors = true;
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
appMiddleware(req, res, next) {
|
|
81
|
-
if (!this._Descriptor) {
|
|
82
|
-
return next();
|
|
83
|
-
}
|
|
84
|
-
if (!this._Descriptor.paths) {
|
|
85
|
-
return next();
|
|
86
|
-
}
|
|
87
|
-
this.checkDescriptor().then(() => {
|
|
88
|
-
// parse
|
|
89
|
-
const { pathname, query } = (0,
|
|
90
|
-
req.method = req.method ? req.method.toLowerCase() : "get";
|
|
91
|
-
req.pattern = null === (0, checkNonEmptyString_1.checkNonEmptyStringSync)("pattern", req.pattern) ? req.pattern : (0, extractPattern_1.default)(this._Descriptor.paths, pathname, req.method);
|
|
92
|
-
if (!req.pattern) {
|
|
93
|
-
return next();
|
|
94
|
-
}
|
|
95
|
-
req.validatedIp = null === (0, checkNonEmptyString_1.checkNonEmptyStringSync)("ip", req.validatedIp) ? req.validatedIp : (0, extractIp_1.default)(req);
|
|
96
|
-
// url
|
|
97
|
-
req.headers = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("headers", req.headers) ? req.headers : {};
|
|
98
|
-
req.cookies = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("cookies", req.cookies) ? req.cookies : (0, extractCookies_1.default)(req);
|
|
99
|
-
req.query = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("query", req.query) ? req.query : query || {};
|
|
100
|
-
req.params = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("params", req.params) ? req.params : (0, extractParams_1.default)(req.pattern, pathname);
|
|
101
|
-
// ensure content length formate
|
|
102
|
-
if ("undefined" === typeof req.headers["content-length"]) {
|
|
103
|
-
req.headers["content-length"] = 0;
|
|
104
|
-
}
|
|
105
|
-
else if ("string" === typeof req.headers["content-length"]) {
|
|
106
|
-
req.headers["content-length"] = parseInt(req.headers["content-length"], 10);
|
|
107
|
-
}
|
|
108
|
-
// set default content-type
|
|
109
|
-
if ("string" !== typeof req.headers["content-type"]) {
|
|
110
|
-
req.headers["content-type"] = "application/json";
|
|
111
|
-
}
|
|
112
|
-
if (!req.pattern || !this._Descriptor.paths[req.pattern] || !this._Descriptor.paths[req.pattern][req.method]) {
|
|
113
|
-
return next();
|
|
114
|
-
}
|
|
115
|
-
const { operationId } = this._Descriptor.paths[req.pattern][req.method];
|
|
116
|
-
this._log("info", "" +
|
|
117
|
-
"=> [" + req.validatedIp + "] " + req.url + " (" + req.method.toUpperCase() + ")" +
|
|
118
|
-
(operationId ?
|
|
119
|
-
|
|
120
|
-
("get" !== req.method && req.headers["content-length"] && 4 < req.headers["content-length"] ?
|
|
121
|
-
|
|
122
|
-
// get descriptor
|
|
123
|
-
if ("/" + this._Descriptor.info.title + "/api/descriptor" === req.pattern && "get" === req.method) {
|
|
124
|
-
return Promise.resolve().then(() => {
|
|
125
|
-
// cannot extract only validate because of stupid malformatted references
|
|
126
|
-
const SwaggerParser = require("@apidevtools/swagger-parser");
|
|
127
|
-
return SwaggerParser.validate(this._Descriptor).then((api) => {
|
|
128
|
-
// force compatibility
|
|
129
|
-
return Promise.resolve(api);
|
|
130
|
-
});
|
|
131
|
-
// add current server
|
|
132
|
-
}).then((api) => {
|
|
133
|
-
var _a;
|
|
134
|
-
if (!api.servers) {
|
|
135
|
-
api.servers = [];
|
|
136
|
-
}
|
|
137
|
-
const port = res.socket && res.socket.localPort ? res.socket.localPort : ((_a = res.socket) === null || _a === void 0 ? void 0 : _a.address()).port;
|
|
138
|
-
api.servers.push({
|
|
139
|
-
"url": req.validatedIp + ":" + port,
|
|
140
|
-
"description": "Actual current server"
|
|
141
|
-
});
|
|
142
|
-
return Promise.resolve(api);
|
|
143
|
-
}).then((api) => {
|
|
144
|
-
this._log("info", "<= [" + req.validatedIp + "] " + JSON.stringify(api));
|
|
145
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.OK, api, this._Descriptor.info.version, this._cors);
|
|
146
|
-
}).catch((err) => {
|
|
147
|
-
this._log("error", err);
|
|
148
|
-
const result = {
|
|
149
|
-
"code": "INTERNAL_SERVER_ERROR",
|
|
150
|
-
"message": (0, cleanSendedError_1.default)(err)
|
|
151
|
-
};
|
|
152
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
153
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.INTERNAL_SERVER_ERROR, result, this._Descriptor.info.version, this._cors);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
// get plugin status
|
|
157
|
-
else if ("/" + this._Descriptor.info.title + "/api/status" === req.pattern && "get" === req.method) {
|
|
158
|
-
const initialized = this.initialized && this._Mediator.initialized;
|
|
159
|
-
const status = initialized ? "INITIALIZED" : "ENABLED";
|
|
160
|
-
this._log("info", "<= [" + req.validatedIp + "] " + status);
|
|
161
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.OK, status, this._Descriptor.info.version, this._cors);
|
|
162
|
-
}
|
|
163
|
-
// missing operationId
|
|
164
|
-
else if (!operationId) {
|
|
165
|
-
const result = {
|
|
166
|
-
"code": "NOT_IMPLEMENTED",
|
|
167
|
-
"message": "Missing \"operationId\" in the Descriptor for this request"
|
|
168
|
-
};
|
|
169
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
170
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.NOT_IMPLEMENTED, result, this._Descriptor.info.version, this._cors);
|
|
171
|
-
}
|
|
172
|
-
// not implemented operationId
|
|
173
|
-
else if ("function" !== typeof this._Mediator[operationId]) {
|
|
174
|
-
const result = {
|
|
175
|
-
"code": "NOT_IMPLEMENTED",
|
|
176
|
-
"message": "Unknown Mediator's \"operationId\" method for this request"
|
|
177
|
-
};
|
|
178
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
179
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.NOT_IMPLEMENTED, result, this._Descriptor.info.version, this._cors);
|
|
180
|
-
}
|
|
181
|
-
// no "Content-Length" header found
|
|
182
|
-
else if ("get" !== req.method && null !== (0, checkInteger_1.checkIntegerSync)("headers[\"content-length\"]", req.headers["content-length"])) {
|
|
183
|
-
const result = {
|
|
184
|
-
"code": "MISSING_HEADER",
|
|
185
|
-
"message": "No valid \"Content-Length\" header found"
|
|
186
|
-
};
|
|
187
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
188
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.MISSING_HEADER, result, this._Descriptor.info.version, this._cors);
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
// force formate for path parameters
|
|
192
|
-
return Promise.resolve().then(() => {
|
|
193
|
-
const keys = Object.keys(req.params);
|
|
194
|
-
return !keys.length ? Promise.resolve() : Promise.resolve().then(() => {
|
|
195
|
-
const docParameters = this._Descriptor.paths[req.pattern][req.method].parameters.filter((p) => {
|
|
196
|
-
return "path" === p.in;
|
|
197
|
-
});
|
|
198
|
-
return !docParameters.length ? Promise.resolve() : Promise.resolve().then(() => {
|
|
199
|
-
var _a;
|
|
200
|
-
let err = null;
|
|
201
|
-
for (let i = 0; i < keys.length; ++i) {
|
|
202
|
-
const key = keys[i];
|
|
203
|
-
const schema = ((_a = docParameters.find((dp) => {
|
|
204
|
-
return dp.name === key;
|
|
205
|
-
})) === null || _a === void 0 ? void 0 : _a.schema) || null;
|
|
206
|
-
if (!schema) {
|
|
207
|
-
err = new ReferenceError("Unknown parameter: request.params['" + key + "']");
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
switch ((0, extractSchemaType_1.default)(schema, this._Descriptor.components.schemas)) {
|
|
211
|
-
case "boolean":
|
|
212
|
-
if ("boolean" !== typeof req.params[key]) {
|
|
213
|
-
if ("true" === req.params[key]) {
|
|
214
|
-
req.params[key] = true;
|
|
215
|
-
}
|
|
216
|
-
else if ("false" === req.params[key]) {
|
|
217
|
-
req.params[key] = false;
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
err = new TypeError("Error while validating request: request.params['" + key + "'] should be boolean");
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
break;
|
|
225
|
-
case "integer":
|
|
226
|
-
// error returned, not an integer
|
|
227
|
-
if (null !== (0, checkInteger_1.checkIntegerSync)("request.params['" + key + "']", req.params[key])) {
|
|
228
|
-
const value = parseInt(req.params[key], 10);
|
|
229
|
-
if (!Number.isNaN(value)) {
|
|
230
|
-
req.params[key] = value;
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
err = new TypeError("Error while validating request: request.params['" + key + "'] should be integer");
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
break;
|
|
238
|
-
case "number":
|
|
239
|
-
if ("number" !== typeof req.params[key]) {
|
|
240
|
-
const value = parseFloat(req.params[key]);
|
|
241
|
-
if (!Number.isNaN(value)) {
|
|
242
|
-
req.params[key] = value;
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
err = new TypeError("Error while validating request: request.params['" + key + "'] should be number");
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
break;
|
|
250
|
-
default:
|
|
251
|
-
// nothing to do here
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
return err ? Promise.reject(err) : Promise.resolve();
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
// extract body
|
|
259
|
-
}).then(() => {
|
|
260
|
-
if ("get" === req.method.toLowerCase()) {
|
|
261
|
-
return Promise.resolve({});
|
|
262
|
-
}
|
|
263
|
-
else if (!(0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("body", req.body)) {
|
|
264
|
-
return Promise.resolve(req.body);
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
return (0, extractBody_1.default)(req).then((body) => {
|
|
268
|
-
req.body = body.parsed;
|
|
269
|
-
if (body.value.length) {
|
|
270
|
-
this._log("log", body.value);
|
|
271
|
-
}
|
|
272
|
-
return Promise.resolve(req.body);
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
// formate data
|
|
276
|
-
}).then((body) => {
|
|
277
|
-
const parsed = {
|
|
278
|
-
"url": {
|
|
279
|
-
"path": req.params,
|
|
280
|
-
"query": req.query,
|
|
281
|
-
"headers": req.headers,
|
|
282
|
-
"cookies": req.cookies
|
|
283
|
-
},
|
|
284
|
-
body
|
|
285
|
-
};
|
|
286
|
-
// check parameters
|
|
287
|
-
return Promise.resolve().then(() => {
|
|
288
|
-
return this._checkParameters ? this._Mediator.checkParameters(operationId, parsed.url, parsed.body) : Promise.resolve();
|
|
289
|
-
// execute Mediator method
|
|
290
|
-
}).then(() => {
|
|
291
|
-
return this._Mediator[operationId](parsed.url, parsed.body);
|
|
292
|
-
});
|
|
293
|
-
// send response
|
|
294
|
-
}).then((content) => {
|
|
295
|
-
// created
|
|
296
|
-
if ("put" === req.method) {
|
|
297
|
-
if ("undefined" === typeof content || null === content) {
|
|
298
|
-
this._log("success", "<= [" + req.validatedIp + "] no content");
|
|
299
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.OK_PUT, undefined, this._Descriptor.info.version, this._cors);
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
this._log("success", "<= [" + req.validatedIp + "] " + JSON.stringify(content));
|
|
303
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.OK_PUT, content, this._Descriptor.info.version, this._cors);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
// no content
|
|
307
|
-
else if ("undefined" === typeof content || null === content) {
|
|
308
|
-
this._log("warning", "<= [" + req.validatedIp + "] no content");
|
|
309
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.OK_NO_CONTENT, undefined, this._Descriptor.info.version, this._cors);
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
this._log("success", "<= [" + req.validatedIp + "] " + JSON.stringify(content));
|
|
313
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.OK, content, this._Descriptor.info.version, this._cors);
|
|
314
|
-
}
|
|
315
|
-
}).catch((err) => {
|
|
316
|
-
if (err instanceof ReferenceError) {
|
|
317
|
-
const result = {
|
|
318
|
-
"code": "MISSING_PARAMETER",
|
|
319
|
-
"message": (0, cleanSendedError_1.default)(err)
|
|
320
|
-
};
|
|
321
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
322
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.MISSING_PARAMETER, result, this._Descriptor.info.version, this._cors);
|
|
323
|
-
}
|
|
324
|
-
else if (err instanceof TypeError) {
|
|
325
|
-
const result = {
|
|
326
|
-
"code": "WRONG_TYPE_PARAMETER",
|
|
327
|
-
"message": (0, cleanSendedError_1.default)(err)
|
|
328
|
-
};
|
|
329
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
330
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.WRONG_TYPE_PARAMETER, result, this._Descriptor.info.version, this._cors);
|
|
331
|
-
}
|
|
332
|
-
else if (err instanceof RangeError) {
|
|
333
|
-
const result = {
|
|
334
|
-
"code": "EMPTY_OR_RANGE_OR_ENUM_PARAMETER",
|
|
335
|
-
"message": (0, cleanSendedError_1.default)(err)
|
|
336
|
-
};
|
|
337
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
338
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.EMPTY_OR_RANGE_OR_ENUM_PARAMETER, result, this._Descriptor.info.version, this._cors);
|
|
339
|
-
}
|
|
340
|
-
else if (err instanceof SyntaxError) {
|
|
341
|
-
const result = {
|
|
342
|
-
"code": "JSON_PARSE",
|
|
343
|
-
"message": (0, cleanSendedError_1.default)(err)
|
|
344
|
-
};
|
|
345
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
346
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.JSON_PARSE, result, this._Descriptor.info.version, this._cors);
|
|
347
|
-
}
|
|
348
|
-
else if (err instanceof NotFoundError_1.default) {
|
|
349
|
-
const result = {
|
|
350
|
-
"code": "NOT_FOUND",
|
|
351
|
-
"message": (0, cleanSendedError_1.default)(err)
|
|
352
|
-
};
|
|
353
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
354
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.NOT_FOUND, result, this._Descriptor.info.version, this._cors);
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
this._log("error", err);
|
|
358
|
-
const result = {
|
|
359
|
-
"code": "INTERNAL_SERVER_ERROR",
|
|
360
|
-
"message": (0, cleanSendedError_1.default)(err)
|
|
361
|
-
};
|
|
362
|
-
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
363
|
-
return (0, send_1.default)(req, res, serverCodes_1.default.INTERNAL_SERVER_ERROR, result, this._Descriptor.info.version, this._cors);
|
|
364
|
-
}
|
|
365
|
-
// check response
|
|
366
|
-
}).then(() => {
|
|
367
|
-
return this._checkResponse ? this._Mediator.checkResponse(operationId, res) : Promise.resolve();
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
}).then(() => {
|
|
371
|
-
// nothing to do here
|
|
372
|
-
// must not be blocking in http server or express app
|
|
373
|
-
}).catch((err) => {
|
|
374
|
-
this._log("error", err);
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
socketMiddleware(socketServer) {
|
|
378
|
-
this._socketServer = socketServer;
|
|
379
|
-
}
|
|
380
|
-
push(command, data, log = true) {
|
|
381
|
-
const serverType = this._serverType();
|
|
382
|
-
if (!["WEBSOCKET", "SOCKETIO"].includes(serverType)) {
|
|
383
|
-
return this;
|
|
384
|
-
}
|
|
385
|
-
// valid descriptor && formate data
|
|
386
|
-
this.checkDescriptor().then(() => {
|
|
387
|
-
const result = {
|
|
388
|
-
"id": (0, uniqid_1.default)(),
|
|
389
|
-
"plugin": this._Descriptor.info.title,
|
|
390
|
-
command
|
|
391
|
-
};
|
|
392
|
-
if ("undefined" !== typeof data) {
|
|
393
|
-
result.data = (0, cleanSendedError_1.default)(data);
|
|
394
|
-
}
|
|
395
|
-
return Promise.resolve(JSON.stringify(result));
|
|
396
|
-
// log & send data
|
|
397
|
-
}).then((result) => {
|
|
398
|
-
if (log) {
|
|
399
|
-
this._log("info", "<= [PUSH] " + result, true);
|
|
400
|
-
}
|
|
401
|
-
switch (serverType) {
|
|
402
|
-
case "WEBSOCKET":
|
|
403
|
-
this._socketServer.clients.forEach((client) => {
|
|
404
|
-
if (!client.id) {
|
|
405
|
-
client.id = (0, uniqid_1.default)();
|
|
406
|
-
}
|
|
407
|
-
if (WEBSOCKET_STATE_OPEN === client.readyState) {
|
|
408
|
-
client.send(result);
|
|
409
|
-
}
|
|
410
|
-
});
|
|
411
|
-
break;
|
|
412
|
-
case "SOCKETIO":
|
|
413
|
-
this._socketServer.sockets.emit("message", result);
|
|
414
|
-
break;
|
|
415
|
-
default:
|
|
416
|
-
// nothing to do here
|
|
417
|
-
break;
|
|
418
|
-
}
|
|
419
|
-
}).catch((err) => {
|
|
420
|
-
this._log("error", err);
|
|
421
|
-
});
|
|
422
|
-
return this;
|
|
423
|
-
}
|
|
424
|
-
getClients() {
|
|
425
|
-
var _a, _b;
|
|
426
|
-
switch (this._serverType()) {
|
|
427
|
-
case "WEBSOCKET": {
|
|
428
|
-
const result = [];
|
|
429
|
-
this._socketServer.clients.forEach((s) => {
|
|
430
|
-
if (!s.id) {
|
|
431
|
-
s.id = (0, uniqid_1.default)();
|
|
432
|
-
}
|
|
433
|
-
return {
|
|
434
|
-
"id": s.id,
|
|
435
|
-
"status": WEBSOCKET_STATE_OPEN === s.readyState ? "CONNECTED" : "DISCONNECTED"
|
|
436
|
-
};
|
|
437
|
-
});
|
|
438
|
-
return result;
|
|
439
|
-
}
|
|
440
|
-
case "SOCKETIO": {
|
|
441
|
-
const result = [];
|
|
442
|
-
if ("function" !== typeof ((_b = (_a = this._socketServer.sockets) === null || _a === void 0 ? void 0 : _a.sockets) === null || _b === void 0 ? void 0 : _b.has)) { // SocketIO V2
|
|
443
|
-
for (const key in this._socketServer.sockets.sockets) {
|
|
444
|
-
const s = this._socketServer.sockets.sockets[key];
|
|
445
|
-
result.push({
|
|
446
|
-
"id": s.id,
|
|
447
|
-
"status": s.connected ? "CONNECTED" : "DISCONNECTED"
|
|
448
|
-
});
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
else {
|
|
452
|
-
this._socketServer.sockets.sockets.forEach((s) => {
|
|
453
|
-
result.push({
|
|
454
|
-
"id": s.id,
|
|
455
|
-
"status": s.connected ? "CONNECTED" : "DISCONNECTED"
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
return result;
|
|
460
|
-
}
|
|
461
|
-
default:
|
|
462
|
-
return [];
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
pushClient(clientId, command, data, log = true) {
|
|
466
|
-
const serverType = this._serverType();
|
|
467
|
-
if (!["WEBSOCKET", "SOCKETIO"].includes(serverType)) {
|
|
468
|
-
return this;
|
|
469
|
-
}
|
|
470
|
-
// valid descriptor && formate data
|
|
471
|
-
this.checkDescriptor().then(() => {
|
|
472
|
-
const result = {
|
|
473
|
-
"id": (0, uniqid_1.default)(),
|
|
474
|
-
"plugin": this._Descriptor.info.title,
|
|
475
|
-
command
|
|
476
|
-
};
|
|
477
|
-
if ("undefined" !== typeof data) {
|
|
478
|
-
result.data = (0, cleanSendedError_1.default)(data);
|
|
479
|
-
}
|
|
480
|
-
return Promise.resolve(JSON.stringify(result));
|
|
481
|
-
// log & send data
|
|
482
|
-
}).then((result) => {
|
|
483
|
-
var _a, _b;
|
|
484
|
-
switch (serverType) {
|
|
485
|
-
case "WEBSOCKET":
|
|
486
|
-
this._socketServer.clients.forEach((client) => {
|
|
487
|
-
if (!client.id) {
|
|
488
|
-
client.id = (0, uniqid_1.default)();
|
|
489
|
-
}
|
|
490
|
-
else if (client.id === clientId && WEBSOCKET_STATE_OPEN === client.readyState) {
|
|
491
|
-
if (log) {
|
|
492
|
-
this._log("info", "<= [PUSH|" + clientId + "] " + result);
|
|
493
|
-
}
|
|
494
|
-
client.send(result);
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
break;
|
|
498
|
-
case "SOCKETIO":
|
|
499
|
-
{
|
|
500
|
-
let socket = null;
|
|
501
|
-
if ("function" !== typeof ((_b = (_a = this._socketServer.sockets) === null || _a === void 0 ? void 0 : _a.sockets) === null || _b === void 0 ? void 0 : _b.has)) { // SocketIO V2
|
|
502
|
-
for (const key in this._socketServer.sockets.sockets) {
|
|
503
|
-
if (key === clientId) {
|
|
504
|
-
socket = this._socketServer.sockets.sockets[key];
|
|
505
|
-
break;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
else if (this._socketServer.sockets.sockets.has(clientId)) { // SocketIO V3&4
|
|
510
|
-
socket = this._socketServer.sockets.sockets.get(clientId);
|
|
511
|
-
}
|
|
512
|
-
if (socket && socket.connected) {
|
|
513
|
-
if (log) {
|
|
514
|
-
this._log("info", "<= [PUSH|" + clientId + "] " + result);
|
|
515
|
-
}
|
|
516
|
-
socket.emit("message", result);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
break;
|
|
520
|
-
default:
|
|
521
|
-
// nothing to do here
|
|
522
|
-
break;
|
|
523
|
-
}
|
|
524
|
-
}).catch((err) => {
|
|
525
|
-
this._log("error", err);
|
|
526
|
-
});
|
|
527
|
-
return this;
|
|
528
|
-
}
|
|
529
|
-
// init / release
|
|
530
|
-
init(...data) {
|
|
531
|
-
return this.checkDescriptor().then(() => {
|
|
532
|
-
return this.checkMediator();
|
|
533
|
-
}).then(() => {
|
|
534
|
-
return this._initWorkSpace(...data);
|
|
535
|
-
}).then(() => {
|
|
536
|
-
this.initialized = true;
|
|
537
|
-
this.emit("initialized", ...data);
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
release(...data) {
|
|
541
|
-
return this._releaseWorkSpace(...data).then(() => {
|
|
542
|
-
// can only be released by Orchestrator
|
|
543
|
-
if (this._Descriptor) {
|
|
544
|
-
this._Descriptor = null;
|
|
545
|
-
}
|
|
546
|
-
// can only be released by Orchestrator
|
|
547
|
-
if (this._Mediator) {
|
|
548
|
-
this._Mediator = null;
|
|
549
|
-
}
|
|
550
|
-
this._externalRessourcesDirectory = "";
|
|
551
|
-
this._socketServer = null;
|
|
552
|
-
this.initialized = false;
|
|
553
|
-
this.emit("released", ...data);
|
|
554
|
-
}).then(() => {
|
|
555
|
-
this.removeAllListeners();
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
exports.default = Server;
|
|
560
|
-
;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
// deps
|
|
7
|
+
// natives
|
|
8
|
+
const node_url_1 = require("node:url");
|
|
9
|
+
const node_os_1 = require("node:os");
|
|
10
|
+
// externals
|
|
11
|
+
const uniqid_1 = __importDefault(require("uniqid"));
|
|
12
|
+
// locals
|
|
13
|
+
const checkInteger_1 = require("../checkers/TypeError/checkInteger");
|
|
14
|
+
const checkNonEmptyObject_1 = require("../checkers/RangeError/checkNonEmptyObject");
|
|
15
|
+
const checkNonEmptyString_1 = require("../checkers/RangeError/checkNonEmptyString");
|
|
16
|
+
const extractPattern_1 = __importDefault(require("../utils/descriptor/extractPattern"));
|
|
17
|
+
const extractParams_1 = __importDefault(require("../utils/descriptor/extractParams"));
|
|
18
|
+
const extractSchemaType_1 = __importDefault(require("../utils/descriptor/extractSchemaType"));
|
|
19
|
+
const extractBody_1 = __importDefault(require("../utils/request/extractBody"));
|
|
20
|
+
const extractIp_1 = __importDefault(require("../utils/request/extractIp"));
|
|
21
|
+
const extractCookies_1 = __importDefault(require("../utils/request/extractCookies"));
|
|
22
|
+
const send_1 = __importDefault(require("../utils/send"));
|
|
23
|
+
const cleanSendedError_1 = __importDefault(require("../utils/cleanSendedError"));
|
|
24
|
+
const MediatorUser_1 = __importDefault(require("./MediatorUser"));
|
|
25
|
+
const NotFoundError_1 = __importDefault(require("./NotFoundError"));
|
|
26
|
+
const serverCodes_1 = __importDefault(require("../utils/serverCodes"));
|
|
27
|
+
// consts
|
|
28
|
+
const WEBSOCKET_STATE_OPEN = 1;
|
|
29
|
+
// module
|
|
30
|
+
// Please note the fact that "init" and "release" method MUST NOT be re-writted. Each child has is own init logic.
|
|
31
|
+
class Server extends MediatorUser_1.default {
|
|
32
|
+
// constructor
|
|
33
|
+
constructor(opt) {
|
|
34
|
+
super(opt);
|
|
35
|
+
this._socketServer = null;
|
|
36
|
+
this._checkParameters = true;
|
|
37
|
+
this._checkResponse = false;
|
|
38
|
+
this._cors = false;
|
|
39
|
+
}
|
|
40
|
+
// protected
|
|
41
|
+
_serverType() {
|
|
42
|
+
if (!this._socketServer) {
|
|
43
|
+
return "NO_SERVER";
|
|
44
|
+
}
|
|
45
|
+
else if (this._socketServer.clients && "function" === typeof this._socketServer.clients.forEach) {
|
|
46
|
+
return "WEBSOCKET";
|
|
47
|
+
}
|
|
48
|
+
else if (this._socketServer.sockets && "function" === typeof this._socketServer.sockets.emit) {
|
|
49
|
+
return "SOCKETIO";
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
return "UNKNOWN";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// public
|
|
56
|
+
disableCheckParameters() {
|
|
57
|
+
this._checkParameters = false;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
enableCheckParameters() {
|
|
61
|
+
this._checkParameters = true;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
disableCheckResponse() {
|
|
65
|
+
this._checkResponse = false;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
enableCheckResponse() {
|
|
69
|
+
this._checkResponse = true;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
disableCors() {
|
|
73
|
+
this._cors = false;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
enableCors() {
|
|
77
|
+
this._cors = true;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
appMiddleware(req, res, next) {
|
|
81
|
+
if (!this._Descriptor) {
|
|
82
|
+
return next();
|
|
83
|
+
}
|
|
84
|
+
if (!this._Descriptor.paths) {
|
|
85
|
+
return next();
|
|
86
|
+
}
|
|
87
|
+
this.checkDescriptor().then(() => {
|
|
88
|
+
// parse
|
|
89
|
+
const { pathname, query } = (0, node_url_1.parse)(req.url, true);
|
|
90
|
+
req.method = req.method ? req.method.toLowerCase() : "get";
|
|
91
|
+
req.pattern = null === (0, checkNonEmptyString_1.checkNonEmptyStringSync)("pattern", req.pattern) ? req.pattern : (0, extractPattern_1.default)(this._Descriptor.paths, pathname, req.method);
|
|
92
|
+
if (!req.pattern) {
|
|
93
|
+
return next();
|
|
94
|
+
}
|
|
95
|
+
req.validatedIp = null === (0, checkNonEmptyString_1.checkNonEmptyStringSync)("ip", req.validatedIp) ? req.validatedIp : (0, extractIp_1.default)(req);
|
|
96
|
+
// url
|
|
97
|
+
req.headers = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("headers", req.headers) ? req.headers : {};
|
|
98
|
+
req.cookies = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("cookies", req.cookies) ? req.cookies : (0, extractCookies_1.default)(req);
|
|
99
|
+
req.query = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("query", req.query) ? req.query : query || {};
|
|
100
|
+
req.params = null === (0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("params", req.params) ? req.params : (0, extractParams_1.default)(req.pattern, pathname);
|
|
101
|
+
// ensure content length formate
|
|
102
|
+
if ("undefined" === typeof req.headers["content-length"]) {
|
|
103
|
+
req.headers["content-length"] = 0;
|
|
104
|
+
}
|
|
105
|
+
else if ("string" === typeof req.headers["content-length"]) {
|
|
106
|
+
req.headers["content-length"] = parseInt(req.headers["content-length"], 10);
|
|
107
|
+
}
|
|
108
|
+
// set default content-type
|
|
109
|
+
if ("string" !== typeof req.headers["content-type"]) {
|
|
110
|
+
req.headers["content-type"] = "application/json";
|
|
111
|
+
}
|
|
112
|
+
if (!req.pattern || !this._Descriptor.paths[req.pattern] || !this._Descriptor.paths[req.pattern][req.method]) {
|
|
113
|
+
return next();
|
|
114
|
+
}
|
|
115
|
+
const { operationId } = this._Descriptor.paths[req.pattern][req.method];
|
|
116
|
+
this._log("info", "" +
|
|
117
|
+
"=> [" + req.validatedIp + "] " + req.url + " (" + req.method.toUpperCase() + ")" +
|
|
118
|
+
(operationId ? node_os_1.EOL + "operationId : " + operationId : "") +
|
|
119
|
+
node_os_1.EOL + "content-type : " + req.headers["content-type"] +
|
|
120
|
+
("get" !== req.method && req.headers["content-length"] && 4 < req.headers["content-length"] ?
|
|
121
|
+
node_os_1.EOL + "content-length : " + req.headers["content-length"] : ""));
|
|
122
|
+
// get descriptor
|
|
123
|
+
if ("/" + this._Descriptor.info.title + "/api/descriptor" === req.pattern && "get" === req.method) {
|
|
124
|
+
return Promise.resolve().then(() => {
|
|
125
|
+
// cannot extract only validate because of stupid malformatted references
|
|
126
|
+
const SwaggerParser = require("@apidevtools/swagger-parser");
|
|
127
|
+
return SwaggerParser.validate(this._Descriptor).then((api) => {
|
|
128
|
+
// force compatibility
|
|
129
|
+
return Promise.resolve(api);
|
|
130
|
+
});
|
|
131
|
+
// add current server
|
|
132
|
+
}).then((api) => {
|
|
133
|
+
var _a;
|
|
134
|
+
if (!api.servers) {
|
|
135
|
+
api.servers = [];
|
|
136
|
+
}
|
|
137
|
+
const port = res.socket && res.socket.localPort ? res.socket.localPort : ((_a = res.socket) === null || _a === void 0 ? void 0 : _a.address()).port;
|
|
138
|
+
api.servers.push({
|
|
139
|
+
"url": req.validatedIp + ":" + port,
|
|
140
|
+
"description": "Actual current server"
|
|
141
|
+
});
|
|
142
|
+
return Promise.resolve(api);
|
|
143
|
+
}).then((api) => {
|
|
144
|
+
this._log("info", "<= [" + req.validatedIp + "] " + JSON.stringify(api));
|
|
145
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.OK, api, this._Descriptor.info.version, this._cors);
|
|
146
|
+
}).catch((err) => {
|
|
147
|
+
this._log("error", err);
|
|
148
|
+
const result = {
|
|
149
|
+
"code": "INTERNAL_SERVER_ERROR",
|
|
150
|
+
"message": (0, cleanSendedError_1.default)(err)
|
|
151
|
+
};
|
|
152
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
153
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.INTERNAL_SERVER_ERROR, result, this._Descriptor.info.version, this._cors);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// get plugin status
|
|
157
|
+
else if ("/" + this._Descriptor.info.title + "/api/status" === req.pattern && "get" === req.method) {
|
|
158
|
+
const initialized = this.initialized && this._Mediator.initialized;
|
|
159
|
+
const status = initialized ? "INITIALIZED" : "ENABLED";
|
|
160
|
+
this._log("info", "<= [" + req.validatedIp + "] " + status);
|
|
161
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.OK, status, this._Descriptor.info.version, this._cors);
|
|
162
|
+
}
|
|
163
|
+
// missing operationId
|
|
164
|
+
else if (!operationId) {
|
|
165
|
+
const result = {
|
|
166
|
+
"code": "NOT_IMPLEMENTED",
|
|
167
|
+
"message": "Missing \"operationId\" in the Descriptor for this request"
|
|
168
|
+
};
|
|
169
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
170
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.NOT_IMPLEMENTED, result, this._Descriptor.info.version, this._cors);
|
|
171
|
+
}
|
|
172
|
+
// not implemented operationId
|
|
173
|
+
else if ("function" !== typeof this._Mediator[operationId]) {
|
|
174
|
+
const result = {
|
|
175
|
+
"code": "NOT_IMPLEMENTED",
|
|
176
|
+
"message": "Unknown Mediator's \"operationId\" method for this request"
|
|
177
|
+
};
|
|
178
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
179
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.NOT_IMPLEMENTED, result, this._Descriptor.info.version, this._cors);
|
|
180
|
+
}
|
|
181
|
+
// no "Content-Length" header found
|
|
182
|
+
else if ("get" !== req.method && null !== (0, checkInteger_1.checkIntegerSync)("headers[\"content-length\"]", req.headers["content-length"])) {
|
|
183
|
+
const result = {
|
|
184
|
+
"code": "MISSING_HEADER",
|
|
185
|
+
"message": "No valid \"Content-Length\" header found"
|
|
186
|
+
};
|
|
187
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
188
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.MISSING_HEADER, result, this._Descriptor.info.version, this._cors);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
// force formate for path parameters
|
|
192
|
+
return Promise.resolve().then(() => {
|
|
193
|
+
const keys = Object.keys(req.params);
|
|
194
|
+
return !keys.length ? Promise.resolve() : Promise.resolve().then(() => {
|
|
195
|
+
const docParameters = this._Descriptor.paths[req.pattern][req.method].parameters.filter((p) => {
|
|
196
|
+
return "path" === p.in;
|
|
197
|
+
});
|
|
198
|
+
return !docParameters.length ? Promise.resolve() : Promise.resolve().then(() => {
|
|
199
|
+
var _a;
|
|
200
|
+
let err = null;
|
|
201
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
202
|
+
const key = keys[i];
|
|
203
|
+
const schema = ((_a = docParameters.find((dp) => {
|
|
204
|
+
return dp.name === key;
|
|
205
|
+
})) === null || _a === void 0 ? void 0 : _a.schema) || null;
|
|
206
|
+
if (!schema) {
|
|
207
|
+
err = new ReferenceError("Unknown parameter: request.params['" + key + "']");
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
switch ((0, extractSchemaType_1.default)(schema, this._Descriptor.components.schemas)) {
|
|
211
|
+
case "boolean":
|
|
212
|
+
if ("boolean" !== typeof req.params[key]) {
|
|
213
|
+
if ("true" === req.params[key]) {
|
|
214
|
+
req.params[key] = true;
|
|
215
|
+
}
|
|
216
|
+
else if ("false" === req.params[key]) {
|
|
217
|
+
req.params[key] = false;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
err = new TypeError("Error while validating request: request.params['" + key + "'] should be boolean");
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
break;
|
|
225
|
+
case "integer":
|
|
226
|
+
// error returned, not an integer
|
|
227
|
+
if (null !== (0, checkInteger_1.checkIntegerSync)("request.params['" + key + "']", req.params[key])) {
|
|
228
|
+
const value = parseInt(req.params[key], 10);
|
|
229
|
+
if (!Number.isNaN(value)) {
|
|
230
|
+
req.params[key] = value;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
err = new TypeError("Error while validating request: request.params['" + key + "'] should be integer");
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
case "number":
|
|
239
|
+
if ("number" !== typeof req.params[key]) {
|
|
240
|
+
const value = parseFloat(req.params[key]);
|
|
241
|
+
if (!Number.isNaN(value)) {
|
|
242
|
+
req.params[key] = value;
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
err = new TypeError("Error while validating request: request.params['" + key + "'] should be number");
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
default:
|
|
251
|
+
// nothing to do here
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return err ? Promise.reject(err) : Promise.resolve();
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
// extract body
|
|
259
|
+
}).then(() => {
|
|
260
|
+
if ("get" === req.method.toLowerCase()) {
|
|
261
|
+
return Promise.resolve({});
|
|
262
|
+
}
|
|
263
|
+
else if (!(0, checkNonEmptyObject_1.checkNonEmptyObjectSync)("body", req.body)) {
|
|
264
|
+
return Promise.resolve(req.body);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
return (0, extractBody_1.default)(req).then((body) => {
|
|
268
|
+
req.body = body.parsed;
|
|
269
|
+
if (body.value.length) {
|
|
270
|
+
this._log("log", body.value);
|
|
271
|
+
}
|
|
272
|
+
return Promise.resolve(req.body);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
// formate data
|
|
276
|
+
}).then((body) => {
|
|
277
|
+
const parsed = {
|
|
278
|
+
"url": {
|
|
279
|
+
"path": req.params,
|
|
280
|
+
"query": req.query,
|
|
281
|
+
"headers": req.headers,
|
|
282
|
+
"cookies": req.cookies
|
|
283
|
+
},
|
|
284
|
+
body
|
|
285
|
+
};
|
|
286
|
+
// check parameters
|
|
287
|
+
return Promise.resolve().then(() => {
|
|
288
|
+
return this._checkParameters ? this._Mediator.checkParameters(operationId, parsed.url, parsed.body) : Promise.resolve();
|
|
289
|
+
// execute Mediator method
|
|
290
|
+
}).then(() => {
|
|
291
|
+
return this._Mediator[operationId](parsed.url, parsed.body);
|
|
292
|
+
});
|
|
293
|
+
// send response
|
|
294
|
+
}).then((content) => {
|
|
295
|
+
// created
|
|
296
|
+
if ("put" === req.method) {
|
|
297
|
+
if ("undefined" === typeof content || null === content) {
|
|
298
|
+
this._log("success", "<= [" + req.validatedIp + "] no content");
|
|
299
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.OK_PUT, undefined, this._Descriptor.info.version, this._cors);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
this._log("success", "<= [" + req.validatedIp + "] " + JSON.stringify(content));
|
|
303
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.OK_PUT, content, this._Descriptor.info.version, this._cors);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
// no content
|
|
307
|
+
else if ("undefined" === typeof content || null === content) {
|
|
308
|
+
this._log("warning", "<= [" + req.validatedIp + "] no content");
|
|
309
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.OK_NO_CONTENT, undefined, this._Descriptor.info.version, this._cors);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
this._log("success", "<= [" + req.validatedIp + "] " + JSON.stringify(content));
|
|
313
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.OK, content, this._Descriptor.info.version, this._cors);
|
|
314
|
+
}
|
|
315
|
+
}).catch((err) => {
|
|
316
|
+
if (err instanceof ReferenceError) {
|
|
317
|
+
const result = {
|
|
318
|
+
"code": "MISSING_PARAMETER",
|
|
319
|
+
"message": (0, cleanSendedError_1.default)(err)
|
|
320
|
+
};
|
|
321
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
322
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.MISSING_PARAMETER, result, this._Descriptor.info.version, this._cors);
|
|
323
|
+
}
|
|
324
|
+
else if (err instanceof TypeError) {
|
|
325
|
+
const result = {
|
|
326
|
+
"code": "WRONG_TYPE_PARAMETER",
|
|
327
|
+
"message": (0, cleanSendedError_1.default)(err)
|
|
328
|
+
};
|
|
329
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
330
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.WRONG_TYPE_PARAMETER, result, this._Descriptor.info.version, this._cors);
|
|
331
|
+
}
|
|
332
|
+
else if (err instanceof RangeError) {
|
|
333
|
+
const result = {
|
|
334
|
+
"code": "EMPTY_OR_RANGE_OR_ENUM_PARAMETER",
|
|
335
|
+
"message": (0, cleanSendedError_1.default)(err)
|
|
336
|
+
};
|
|
337
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
338
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.EMPTY_OR_RANGE_OR_ENUM_PARAMETER, result, this._Descriptor.info.version, this._cors);
|
|
339
|
+
}
|
|
340
|
+
else if (err instanceof SyntaxError) {
|
|
341
|
+
const result = {
|
|
342
|
+
"code": "JSON_PARSE",
|
|
343
|
+
"message": (0, cleanSendedError_1.default)(err)
|
|
344
|
+
};
|
|
345
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
346
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.JSON_PARSE, result, this._Descriptor.info.version, this._cors);
|
|
347
|
+
}
|
|
348
|
+
else if (err instanceof NotFoundError_1.default) {
|
|
349
|
+
const result = {
|
|
350
|
+
"code": "NOT_FOUND",
|
|
351
|
+
"message": (0, cleanSendedError_1.default)(err)
|
|
352
|
+
};
|
|
353
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
354
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.NOT_FOUND, result, this._Descriptor.info.version, this._cors);
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
this._log("error", err);
|
|
358
|
+
const result = {
|
|
359
|
+
"code": "INTERNAL_SERVER_ERROR",
|
|
360
|
+
"message": (0, cleanSendedError_1.default)(err)
|
|
361
|
+
};
|
|
362
|
+
this._log("error", "<= [" + req.validatedIp + "] " + JSON.stringify(result));
|
|
363
|
+
return (0, send_1.default)(req, res, serverCodes_1.default.INTERNAL_SERVER_ERROR, result, this._Descriptor.info.version, this._cors);
|
|
364
|
+
}
|
|
365
|
+
// check response
|
|
366
|
+
}).then(() => {
|
|
367
|
+
return this._checkResponse ? this._Mediator.checkResponse(operationId, res) : Promise.resolve();
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}).then(() => {
|
|
371
|
+
// nothing to do here
|
|
372
|
+
// must not be blocking in http server or express app
|
|
373
|
+
}).catch((err) => {
|
|
374
|
+
this._log("error", err);
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
socketMiddleware(socketServer) {
|
|
378
|
+
this._socketServer = socketServer;
|
|
379
|
+
}
|
|
380
|
+
push(command, data, log = true) {
|
|
381
|
+
const serverType = this._serverType();
|
|
382
|
+
if (!["WEBSOCKET", "SOCKETIO"].includes(serverType)) {
|
|
383
|
+
return this;
|
|
384
|
+
}
|
|
385
|
+
// valid descriptor && formate data
|
|
386
|
+
this.checkDescriptor().then(() => {
|
|
387
|
+
const result = {
|
|
388
|
+
"id": (0, uniqid_1.default)(),
|
|
389
|
+
"plugin": this._Descriptor.info.title,
|
|
390
|
+
command
|
|
391
|
+
};
|
|
392
|
+
if ("undefined" !== typeof data) {
|
|
393
|
+
result.data = (0, cleanSendedError_1.default)(data);
|
|
394
|
+
}
|
|
395
|
+
return Promise.resolve(JSON.stringify(result));
|
|
396
|
+
// log & send data
|
|
397
|
+
}).then((result) => {
|
|
398
|
+
if (log) {
|
|
399
|
+
this._log("info", "<= [PUSH] " + result, true);
|
|
400
|
+
}
|
|
401
|
+
switch (serverType) {
|
|
402
|
+
case "WEBSOCKET":
|
|
403
|
+
this._socketServer.clients.forEach((client) => {
|
|
404
|
+
if (!client.id) {
|
|
405
|
+
client.id = (0, uniqid_1.default)();
|
|
406
|
+
}
|
|
407
|
+
if (WEBSOCKET_STATE_OPEN === client.readyState) {
|
|
408
|
+
client.send(result);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
break;
|
|
412
|
+
case "SOCKETIO":
|
|
413
|
+
this._socketServer.sockets.emit("message", result);
|
|
414
|
+
break;
|
|
415
|
+
default:
|
|
416
|
+
// nothing to do here
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
}).catch((err) => {
|
|
420
|
+
this._log("error", err);
|
|
421
|
+
});
|
|
422
|
+
return this;
|
|
423
|
+
}
|
|
424
|
+
getClients() {
|
|
425
|
+
var _a, _b;
|
|
426
|
+
switch (this._serverType()) {
|
|
427
|
+
case "WEBSOCKET": {
|
|
428
|
+
const result = [];
|
|
429
|
+
this._socketServer.clients.forEach((s) => {
|
|
430
|
+
if (!s.id) {
|
|
431
|
+
s.id = (0, uniqid_1.default)();
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
"id": s.id,
|
|
435
|
+
"status": WEBSOCKET_STATE_OPEN === s.readyState ? "CONNECTED" : "DISCONNECTED"
|
|
436
|
+
};
|
|
437
|
+
});
|
|
438
|
+
return result;
|
|
439
|
+
}
|
|
440
|
+
case "SOCKETIO": {
|
|
441
|
+
const result = [];
|
|
442
|
+
if ("function" !== typeof ((_b = (_a = this._socketServer.sockets) === null || _a === void 0 ? void 0 : _a.sockets) === null || _b === void 0 ? void 0 : _b.has)) { // SocketIO V2
|
|
443
|
+
for (const key in this._socketServer.sockets.sockets) {
|
|
444
|
+
const s = this._socketServer.sockets.sockets[key];
|
|
445
|
+
result.push({
|
|
446
|
+
"id": s.id,
|
|
447
|
+
"status": s.connected ? "CONNECTED" : "DISCONNECTED"
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
this._socketServer.sockets.sockets.forEach((s) => {
|
|
453
|
+
result.push({
|
|
454
|
+
"id": s.id,
|
|
455
|
+
"status": s.connected ? "CONNECTED" : "DISCONNECTED"
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
return result;
|
|
460
|
+
}
|
|
461
|
+
default:
|
|
462
|
+
return [];
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
pushClient(clientId, command, data, log = true) {
|
|
466
|
+
const serverType = this._serverType();
|
|
467
|
+
if (!["WEBSOCKET", "SOCKETIO"].includes(serverType)) {
|
|
468
|
+
return this;
|
|
469
|
+
}
|
|
470
|
+
// valid descriptor && formate data
|
|
471
|
+
this.checkDescriptor().then(() => {
|
|
472
|
+
const result = {
|
|
473
|
+
"id": (0, uniqid_1.default)(),
|
|
474
|
+
"plugin": this._Descriptor.info.title,
|
|
475
|
+
command
|
|
476
|
+
};
|
|
477
|
+
if ("undefined" !== typeof data) {
|
|
478
|
+
result.data = (0, cleanSendedError_1.default)(data);
|
|
479
|
+
}
|
|
480
|
+
return Promise.resolve(JSON.stringify(result));
|
|
481
|
+
// log & send data
|
|
482
|
+
}).then((result) => {
|
|
483
|
+
var _a, _b;
|
|
484
|
+
switch (serverType) {
|
|
485
|
+
case "WEBSOCKET":
|
|
486
|
+
this._socketServer.clients.forEach((client) => {
|
|
487
|
+
if (!client.id) {
|
|
488
|
+
client.id = (0, uniqid_1.default)();
|
|
489
|
+
}
|
|
490
|
+
else if (client.id === clientId && WEBSOCKET_STATE_OPEN === client.readyState) {
|
|
491
|
+
if (log) {
|
|
492
|
+
this._log("info", "<= [PUSH|" + clientId + "] " + result);
|
|
493
|
+
}
|
|
494
|
+
client.send(result);
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
break;
|
|
498
|
+
case "SOCKETIO":
|
|
499
|
+
{
|
|
500
|
+
let socket = null;
|
|
501
|
+
if ("function" !== typeof ((_b = (_a = this._socketServer.sockets) === null || _a === void 0 ? void 0 : _a.sockets) === null || _b === void 0 ? void 0 : _b.has)) { // SocketIO V2
|
|
502
|
+
for (const key in this._socketServer.sockets.sockets) {
|
|
503
|
+
if (key === clientId) {
|
|
504
|
+
socket = this._socketServer.sockets.sockets[key];
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
else if (this._socketServer.sockets.sockets.has(clientId)) { // SocketIO V3&4
|
|
510
|
+
socket = this._socketServer.sockets.sockets.get(clientId);
|
|
511
|
+
}
|
|
512
|
+
if (socket && socket.connected) {
|
|
513
|
+
if (log) {
|
|
514
|
+
this._log("info", "<= [PUSH|" + clientId + "] " + result);
|
|
515
|
+
}
|
|
516
|
+
socket.emit("message", result);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
break;
|
|
520
|
+
default:
|
|
521
|
+
// nothing to do here
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
}).catch((err) => {
|
|
525
|
+
this._log("error", err);
|
|
526
|
+
});
|
|
527
|
+
return this;
|
|
528
|
+
}
|
|
529
|
+
// init / release
|
|
530
|
+
init(...data) {
|
|
531
|
+
return this.checkDescriptor().then(() => {
|
|
532
|
+
return this.checkMediator();
|
|
533
|
+
}).then(() => {
|
|
534
|
+
return this._initWorkSpace(...data);
|
|
535
|
+
}).then(() => {
|
|
536
|
+
this.initialized = true;
|
|
537
|
+
this.emit("initialized", ...data);
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
release(...data) {
|
|
541
|
+
return this._releaseWorkSpace(...data).then(() => {
|
|
542
|
+
// can only be released by Orchestrator
|
|
543
|
+
if (this._Descriptor) {
|
|
544
|
+
this._Descriptor = null;
|
|
545
|
+
}
|
|
546
|
+
// can only be released by Orchestrator
|
|
547
|
+
if (this._Mediator) {
|
|
548
|
+
this._Mediator = null;
|
|
549
|
+
}
|
|
550
|
+
this._externalRessourcesDirectory = "";
|
|
551
|
+
this._socketServer = null;
|
|
552
|
+
this.initialized = false;
|
|
553
|
+
this.emit("released", ...data);
|
|
554
|
+
}).then(() => {
|
|
555
|
+
this.removeAllListeners();
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
exports.default = Server;
|
|
560
|
+
;
|