systemlynx 1.13.10 → 1.15.10
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/index.test.js +11 -4
- package/package.json +1 -1
- package/systemlynx/App/App.js +5 -0
- package/systemlynx/App/tests/App.test.js +10 -4
- package/systemlynx/HttpClient/HttpClient.js +6 -2
- package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +8 -2
- package/systemlynx/ServerManager/ServerManager.js +53 -22
- package/systemlynx/ServerManager/components/Router.js +66 -24
- package/systemlynx/ServerManager/tests/ServerManager.test.js +115 -6
- package/systemlynx/Service/Service.js +21 -5
- package/systemlynx/Service/Service.test.js +66 -8
package/index.test.js
CHANGED
|
@@ -37,6 +37,7 @@ describe("SystemLynx Objects", () => {
|
|
|
37
37
|
"emit",
|
|
38
38
|
"$clearEvent",
|
|
39
39
|
"before",
|
|
40
|
+
"after",
|
|
40
41
|
"use",
|
|
41
42
|
"startService",
|
|
42
43
|
"loadService",
|
|
@@ -50,6 +51,7 @@ describe("SystemLynx Objects", () => {
|
|
|
50
51
|
.that.respondsTo("emit")
|
|
51
52
|
.that.respondsTo("$clearEvent")
|
|
52
53
|
.that.respondsTo("before")
|
|
54
|
+
.that.respondsTo("after")
|
|
53
55
|
.that.respondsTo("use")
|
|
54
56
|
.that.respondsTo("startService")
|
|
55
57
|
.that.respondsTo("loadService")
|
|
@@ -81,15 +83,18 @@ describe("SystemLynx Objects", () => {
|
|
|
81
83
|
"WebSocket",
|
|
82
84
|
"clones",
|
|
83
85
|
"module",
|
|
84
|
-
"before"
|
|
86
|
+
"before",
|
|
87
|
+
"after"
|
|
85
88
|
)
|
|
86
89
|
.that.respondsTo("startService")
|
|
87
90
|
.that.respondsTo("module")
|
|
88
|
-
.that.respondsTo("before")
|
|
91
|
+
.that.respondsTo("before")
|
|
92
|
+
.that.respondsTo("after");
|
|
89
93
|
expect(LoadBalancer.clones)
|
|
90
94
|
.to.be.an("object")
|
|
91
95
|
.that.has.all.keys(
|
|
92
96
|
"before",
|
|
97
|
+
"after",
|
|
93
98
|
"on",
|
|
94
99
|
"emit",
|
|
95
100
|
"$clearEvent",
|
|
@@ -102,6 +107,7 @@ describe("SystemLynx Objects", () => {
|
|
|
102
107
|
.that.respondsTo("$clearEvent")
|
|
103
108
|
.that.respondsTo("on")
|
|
104
109
|
.that.respondsTo("before")
|
|
110
|
+
.that.respondsTo("after")
|
|
105
111
|
.that.respondsTo("register")
|
|
106
112
|
.that.respondsTo("dispatch")
|
|
107
113
|
.that.respondsTo("assignDispatch")
|
|
@@ -115,13 +121,14 @@ describe("SystemLynx Objects", () => {
|
|
|
115
121
|
.that.has.all.keys([
|
|
116
122
|
"startService",
|
|
117
123
|
"addModule",
|
|
118
|
-
"
|
|
124
|
+
"addBeforware",
|
|
125
|
+
"addAfterware",
|
|
119
126
|
"server",
|
|
120
127
|
"WebSocket",
|
|
121
128
|
])
|
|
122
129
|
.that.respondsTo("startService")
|
|
123
130
|
.that.respondsTo("addModule")
|
|
124
|
-
.that.respondsTo("
|
|
131
|
+
.that.respondsTo("addBeforware");
|
|
125
132
|
});
|
|
126
133
|
|
|
127
134
|
it("should return a new instance of a Service", () => {
|
package/package.json
CHANGED
package/systemlynx/App/App.js
CHANGED
|
@@ -48,6 +48,11 @@ module.exports = function createApp(server, WebSocket, customClient) {
|
|
|
48
48
|
return App;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
+
App.after = (...args) => {
|
|
52
|
+
system.Service.after(...args);
|
|
53
|
+
return App;
|
|
54
|
+
};
|
|
55
|
+
|
|
51
56
|
App.loadService = (name, url) => {
|
|
52
57
|
system.services.push({ name, url, onLoad: null, client: {} });
|
|
53
58
|
return App;
|
|
@@ -14,6 +14,7 @@ describe("createApp()", () => {
|
|
|
14
14
|
"on",
|
|
15
15
|
"emit",
|
|
16
16
|
"before",
|
|
17
|
+
"after",
|
|
17
18
|
"$clearEvent",
|
|
18
19
|
"use",
|
|
19
20
|
"startService",
|
|
@@ -28,6 +29,7 @@ describe("createApp()", () => {
|
|
|
28
29
|
.that.respondsTo("emit")
|
|
29
30
|
.that.respondsTo("$clearEvent")
|
|
30
31
|
.that.respondsTo("before")
|
|
32
|
+
.that.respondsTo("after")
|
|
31
33
|
.that.respondsTo("use")
|
|
32
34
|
.that.respondsTo("startService")
|
|
33
35
|
.that.respondsTo("loadService")
|
|
@@ -236,7 +238,8 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
236
238
|
"on",
|
|
237
239
|
"emit",
|
|
238
240
|
"$clearEvent",
|
|
239
|
-
"before"
|
|
241
|
+
"before",
|
|
242
|
+
"after"
|
|
240
243
|
)
|
|
241
244
|
.that.respondsTo("useModule")
|
|
242
245
|
.that.respondsTo("useService")
|
|
@@ -244,7 +247,8 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
244
247
|
.that.respondsTo("on")
|
|
245
248
|
.that.respondsTo("emit")
|
|
246
249
|
.that.respondsTo("$clearEvent")
|
|
247
|
-
.that.respondsTo("before")
|
|
250
|
+
.that.respondsTo("before")
|
|
251
|
+
.that.respondsTo("after");
|
|
248
252
|
}).module("test2", function () {
|
|
249
253
|
expect(this)
|
|
250
254
|
.to.be.an("object")
|
|
@@ -255,7 +259,8 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
255
259
|
"on",
|
|
256
260
|
"emit",
|
|
257
261
|
"$clearEvent",
|
|
258
|
-
"before"
|
|
262
|
+
"before",
|
|
263
|
+
"after"
|
|
259
264
|
)
|
|
260
265
|
.that.respondsTo("useModule")
|
|
261
266
|
.that.respondsTo("useService")
|
|
@@ -263,7 +268,8 @@ describe("App SystemObjects: Initializing Modules, Modules and configurations",
|
|
|
263
268
|
.that.respondsTo("on")
|
|
264
269
|
.that.respondsTo("emit")
|
|
265
270
|
.that.respondsTo("$clearEvent")
|
|
266
|
-
.that.respondsTo("before")
|
|
271
|
+
.that.respondsTo("before")
|
|
272
|
+
.that.respondsTo("after");
|
|
267
273
|
resolve();
|
|
268
274
|
})
|
|
269
275
|
);
|
|
@@ -9,7 +9,9 @@ module.exports = function createHttpClient() {
|
|
|
9
9
|
method = method.toLowerCase();
|
|
10
10
|
try {
|
|
11
11
|
const res = await axios({ url, method, headers, data });
|
|
12
|
-
|
|
12
|
+
if (res.status >= 400) {
|
|
13
|
+
throw res.data;
|
|
14
|
+
} else return res.data;
|
|
13
15
|
} catch (error) {
|
|
14
16
|
if (!error.isAxiosError) throw error;
|
|
15
17
|
if (!error.response) throw error;
|
|
@@ -33,7 +35,9 @@ module.exports = function createHttpClient() {
|
|
|
33
35
|
const res = await axios.post(url, form, {
|
|
34
36
|
headers: { ...headers, "Content-Type": "multipart/form-data" },
|
|
35
37
|
});
|
|
36
|
-
|
|
38
|
+
if (res.status >= 400) {
|
|
39
|
+
throw res.data;
|
|
40
|
+
} else return res.data;
|
|
37
41
|
} catch (error) {
|
|
38
42
|
if (!error.isAxiosError) throw error;
|
|
39
43
|
if (!error.response) throw error;
|
|
@@ -15,11 +15,13 @@ describe("LoadBalancer()", () => {
|
|
|
15
15
|
"WebSocket",
|
|
16
16
|
"module",
|
|
17
17
|
"clones",
|
|
18
|
-
"before"
|
|
18
|
+
"before",
|
|
19
|
+
"after"
|
|
19
20
|
)
|
|
20
21
|
.that.respondsTo("startService")
|
|
21
22
|
.that.respondsTo("module")
|
|
22
|
-
.that.respondsTo("before")
|
|
23
|
+
.that.respondsTo("before")
|
|
24
|
+
.that.respondsTo("after");
|
|
23
25
|
expect(LoadBalancer.clones)
|
|
24
26
|
.to.be.an("object")
|
|
25
27
|
.that.has.all.keys(
|
|
@@ -27,6 +29,7 @@ describe("LoadBalancer()", () => {
|
|
|
27
29
|
"emit",
|
|
28
30
|
"$clearEvent",
|
|
29
31
|
"before",
|
|
32
|
+
"after",
|
|
30
33
|
"clones",
|
|
31
34
|
"register",
|
|
32
35
|
"dispatch",
|
|
@@ -36,6 +39,7 @@ describe("LoadBalancer()", () => {
|
|
|
36
39
|
.that.respondsTo("$clearEvent")
|
|
37
40
|
.that.respondsTo("on")
|
|
38
41
|
.that.respondsTo("before")
|
|
42
|
+
.that.respondsTo("after")
|
|
39
43
|
.that.respondsTo("register")
|
|
40
44
|
.that.respondsTo("dispatch")
|
|
41
45
|
.that.respondsTo("assignDispatch")
|
|
@@ -92,6 +96,7 @@ describe("LoadBalancer.clones (Module)", () => {
|
|
|
92
96
|
"$emit",
|
|
93
97
|
"$clearEvent",
|
|
94
98
|
"before",
|
|
99
|
+
"after",
|
|
95
100
|
"register",
|
|
96
101
|
"dispatch",
|
|
97
102
|
"assignDispatch",
|
|
@@ -101,6 +106,7 @@ describe("LoadBalancer.clones (Module)", () => {
|
|
|
101
106
|
.that.respondsTo("emit")
|
|
102
107
|
.that.respondsTo("$clearEvent")
|
|
103
108
|
.that.respondsTo("before")
|
|
109
|
+
.that.respondsTo("after")
|
|
104
110
|
.that.respondsTo("$emit")
|
|
105
111
|
.that.respondsTo("register")
|
|
106
112
|
.that.respondsTo("dispatch")
|
|
@@ -22,7 +22,8 @@ module.exports = function createServerManager(customServer, customWebSocketServe
|
|
|
22
22
|
useService: true,
|
|
23
23
|
staticRouting: false,
|
|
24
24
|
ssl: { key: "", cert: "" },
|
|
25
|
-
|
|
25
|
+
beforeware: { $all: [] },
|
|
26
|
+
afterware: { $all: [] },
|
|
26
27
|
};
|
|
27
28
|
const server = createServer(customServer);
|
|
28
29
|
const router = createRouter(server, () => serverConfigurations);
|
|
@@ -97,16 +98,26 @@ module.exports = function createServerManager(customServer, customWebSocketServe
|
|
|
97
98
|
useService,
|
|
98
99
|
useREST,
|
|
99
100
|
socketPort,
|
|
100
|
-
|
|
101
|
+
beforeware,
|
|
102
|
+
afterware,
|
|
101
103
|
} = serverConfigurations;
|
|
102
104
|
|
|
103
105
|
if (!serviceUrl) return moduleQueue.push({ name, Module, reserved_methods });
|
|
104
|
-
const exclude_methods = [
|
|
106
|
+
const exclude_methods = [
|
|
107
|
+
"on",
|
|
108
|
+
"emit",
|
|
109
|
+
"before",
|
|
110
|
+
"after",
|
|
111
|
+
"$clearEvent",
|
|
112
|
+
...reserved_methods,
|
|
113
|
+
];
|
|
105
114
|
const methods = parseMethods(Module, exclude_methods, useREST);
|
|
106
115
|
const namespace = staticRouting ? name : shortId();
|
|
107
116
|
|
|
108
117
|
SocketEmitter.apply(Module, [namespace, WebSocket]);
|
|
109
|
-
const
|
|
118
|
+
const before_validators = [...beforeware.$all, ...(beforeware[name] || [])];
|
|
119
|
+
const after_validators = [...afterware.$all, ...(afterware[name] || [])];
|
|
120
|
+
|
|
110
121
|
if (useService) {
|
|
111
122
|
const path = staticRouting ? `${route}/${name}` : `${shortId()}/${shortId()}`;
|
|
112
123
|
|
|
@@ -118,46 +129,66 @@ module.exports = function createServerManager(customServer, customWebSocketServe
|
|
|
118
129
|
});
|
|
119
130
|
methods.forEach((method) => {
|
|
120
131
|
const nsp = `${name}.${method.fn}`;
|
|
121
|
-
const
|
|
122
|
-
|
|
132
|
+
const beforeValidators = [...before_validators, ...(beforeware[nsp] || [])];
|
|
133
|
+
const afterValidators = [...after_validators, ...(afterware[nsp] || [])];
|
|
134
|
+
router.addService(Module, path, method, name, beforeValidators, afterValidators);
|
|
123
135
|
});
|
|
124
136
|
}
|
|
125
137
|
if (useREST)
|
|
126
138
|
methods.forEach((method) => {
|
|
127
139
|
const nsp = `${name}.${method.fn}`;
|
|
128
|
-
const
|
|
140
|
+
const beforeValidators = [...before_validators, ...(beforeware[nsp] || [])];
|
|
141
|
+
const afterValidators = [...after_validators, ...(afterware[nsp] || [])];
|
|
129
142
|
switch (method.fn) {
|
|
130
143
|
case "get":
|
|
131
144
|
case "put":
|
|
132
145
|
case "post":
|
|
133
146
|
case "delete":
|
|
134
|
-
router.addREST(
|
|
147
|
+
router.addREST(
|
|
148
|
+
Module,
|
|
149
|
+
`${route}/${name}`,
|
|
150
|
+
method,
|
|
151
|
+
name,
|
|
152
|
+
beforeValidators,
|
|
153
|
+
afterValidators
|
|
154
|
+
);
|
|
135
155
|
}
|
|
136
156
|
});
|
|
137
157
|
};
|
|
138
|
-
|
|
158
|
+
|
|
159
|
+
// Shared function for adding middleware (both beforeware and afterware)
|
|
160
|
+
const addMiddleware = (type, ...args) => {
|
|
139
161
|
const name = typeof args[0] === "string" ? args.shift() : "$all";
|
|
140
162
|
args.forEach(async (middleware) => {
|
|
141
163
|
if (Array.isArray(middleware)) {
|
|
142
|
-
middleware.map(
|
|
164
|
+
middleware.map((m) => addMiddlewareItem(type, name, m));
|
|
143
165
|
} else {
|
|
144
|
-
|
|
166
|
+
addMiddlewareItem(type, name, middleware);
|
|
145
167
|
}
|
|
146
168
|
});
|
|
169
|
+
};
|
|
147
170
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
} catch (error) {
|
|
156
|
-
res.sendError(error);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
171
|
+
// Helper function to add a single middleware item
|
|
172
|
+
const addMiddlewareItem = (type, name, middleware) => {
|
|
173
|
+
if (Array.isArray(middleware))
|
|
174
|
+
return middleware.map((m) => addMiddlewareItem(type, name, m));
|
|
175
|
+
|
|
176
|
+
if (!serverConfigurations[type][name]) {
|
|
177
|
+
serverConfigurations[type][name] = [];
|
|
159
178
|
}
|
|
179
|
+
|
|
180
|
+
serverConfigurations[type][name].push(async function (req, res, next) {
|
|
181
|
+
try {
|
|
182
|
+
await middleware(req, res, next);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
res.sendError(error);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
160
187
|
};
|
|
188
|
+
|
|
189
|
+
// Use the shared function for both middleware types
|
|
190
|
+
ServerManager.addBeforware = (...args) => addMiddleware("beforeware", ...args);
|
|
191
|
+
ServerManager.addAfterware = (...args) => addMiddleware("afterware", ...args);
|
|
161
192
|
return ServerManager;
|
|
162
193
|
};
|
|
163
194
|
|
|
@@ -4,7 +4,14 @@ const isEmpty = (obj) => Object.getOwnPropertyNames(obj).length === 0;
|
|
|
4
4
|
const isPromise = (p) => typeof p === "object" && typeof (p || {}).then === "function";
|
|
5
5
|
|
|
6
6
|
module.exports = function createRouter(server, config) {
|
|
7
|
-
const addService = (
|
|
7
|
+
const addService = (
|
|
8
|
+
Module,
|
|
9
|
+
route,
|
|
10
|
+
{ fn, method },
|
|
11
|
+
module_name,
|
|
12
|
+
beforeware,
|
|
13
|
+
afterware
|
|
14
|
+
) => {
|
|
8
15
|
server[method](
|
|
9
16
|
[`/${route}/${fn}`, `/sf/${route}/${fn}`, `/mf/${route}/${fn}`],
|
|
10
17
|
(req, res, next) => {
|
|
@@ -14,13 +21,15 @@ module.exports = function createRouter(server, config) {
|
|
|
14
21
|
req.module = Module;
|
|
15
22
|
next();
|
|
16
23
|
},
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
parseRequest,
|
|
25
|
+
beforeware,
|
|
26
|
+
handleRequest,
|
|
27
|
+
afterware,
|
|
28
|
+
sendResponseMiddleware
|
|
20
29
|
);
|
|
21
30
|
};
|
|
22
31
|
|
|
23
|
-
const addREST = (Module, route, { method }, module_name,
|
|
32
|
+
const addREST = (Module, route, { method }, module_name, beforeware, afterware) => {
|
|
24
33
|
server[method](
|
|
25
34
|
[`/${route}`],
|
|
26
35
|
(req, res, next) => {
|
|
@@ -30,13 +39,15 @@ module.exports = function createRouter(server, config) {
|
|
|
30
39
|
req.module = Module;
|
|
31
40
|
next();
|
|
32
41
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
parseRequest,
|
|
43
|
+
beforeware,
|
|
44
|
+
handleRequest,
|
|
45
|
+
afterware,
|
|
46
|
+
sendResponseMiddleware
|
|
36
47
|
);
|
|
37
48
|
};
|
|
38
49
|
|
|
39
|
-
const
|
|
50
|
+
const parseRequest = (req, res, next) => {
|
|
40
51
|
const { fn, module_name, query, file, files, body, method, Module } = req;
|
|
41
52
|
|
|
42
53
|
const { serviceUrl } = config();
|
|
@@ -56,17 +67,8 @@ module.exports = function createRouter(server, config) {
|
|
|
56
67
|
};
|
|
57
68
|
|
|
58
69
|
const sendResponse = (returnValue) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
res.status(status).json({
|
|
62
|
-
...presets,
|
|
63
|
-
status,
|
|
64
|
-
message:
|
|
65
|
-
(returnValue || {}).message ||
|
|
66
|
-
`[SystemLynx][response]: ${module_name}.${fn}(...) returned successfully`,
|
|
67
|
-
returnValue,
|
|
68
|
-
});
|
|
69
|
-
} else sendError(returnValue);
|
|
70
|
+
req.returnValue = returnValue;
|
|
71
|
+
sendResponseMiddleware(req, res);
|
|
70
72
|
};
|
|
71
73
|
|
|
72
74
|
if (typeof Module[fn] !== "function")
|
|
@@ -83,23 +85,63 @@ module.exports = function createRouter(server, config) {
|
|
|
83
85
|
return args;
|
|
84
86
|
};
|
|
85
87
|
req.arguments = getArguments();
|
|
88
|
+
req.presets = presets;
|
|
86
89
|
res.sendError = sendError;
|
|
87
90
|
res.sendResponse = sendResponse;
|
|
88
91
|
next();
|
|
89
92
|
};
|
|
90
93
|
|
|
91
|
-
const
|
|
94
|
+
const sendResponseMiddleware = (req, res, next) => {
|
|
95
|
+
const returnValue = req.returnValue;
|
|
96
|
+
const presets = req.presets;
|
|
97
|
+
const { module_name, fn } = req;
|
|
98
|
+
|
|
99
|
+
const status = (returnValue || {}).status >= 100 ? returnValue.status : 200;
|
|
100
|
+
if (status < 400) {
|
|
101
|
+
res.status(status).json({
|
|
102
|
+
...presets,
|
|
103
|
+
status,
|
|
104
|
+
message:
|
|
105
|
+
(returnValue || {}).message ||
|
|
106
|
+
`[SystemLynx][response]: ${module_name}.${fn}(...) returned successfully`,
|
|
107
|
+
returnValue,
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
const unhandledMessage = `[SystemLynx]: handled error While calling ${module_name}.${fn}(...)`;
|
|
111
|
+
const error = returnValue;
|
|
112
|
+
const errorStatus = (error || {}).status || 500;
|
|
113
|
+
const message = (error || {}).message || unhandledMessage;
|
|
114
|
+
res.status(errorStatus).json({
|
|
115
|
+
...presets,
|
|
116
|
+
...error,
|
|
117
|
+
status: errorStatus,
|
|
118
|
+
message,
|
|
119
|
+
SystemLynxService: true,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Call next if it exists (needed for middleware chaining)
|
|
124
|
+
if (next) next();
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const handleRequest = (req, res, next) => {
|
|
92
128
|
const { fn, Module } = req;
|
|
93
|
-
const { sendError
|
|
129
|
+
const { sendError } = res;
|
|
94
130
|
|
|
95
131
|
try {
|
|
96
132
|
const args = req.arguments;
|
|
97
133
|
const results = Module[fn].apply({ ...Module, req, res }, args);
|
|
98
134
|
|
|
99
135
|
if (isPromise(results)) {
|
|
100
|
-
results
|
|
136
|
+
results
|
|
137
|
+
.then((result) => {
|
|
138
|
+
req.returnValue = result;
|
|
139
|
+
next();
|
|
140
|
+
})
|
|
141
|
+
.catch(sendError);
|
|
101
142
|
} else {
|
|
102
|
-
|
|
143
|
+
req.returnValue = results;
|
|
144
|
+
next();
|
|
103
145
|
}
|
|
104
146
|
} catch (error) {
|
|
105
147
|
sendError(error);
|
|
@@ -11,13 +11,15 @@ describe("createServerManager function", () => {
|
|
|
11
11
|
.that.has.all.keys([
|
|
12
12
|
"startService",
|
|
13
13
|
"addModule",
|
|
14
|
-
"
|
|
14
|
+
"addBeforware",
|
|
15
|
+
"addAfterware",
|
|
15
16
|
"server",
|
|
16
17
|
"WebSocket",
|
|
17
18
|
])
|
|
18
19
|
.that.respondsTo("startService")
|
|
19
20
|
.that.respondsTo("addModule")
|
|
20
|
-
.that.respondsTo("
|
|
21
|
+
.that.respondsTo("addBeforware")
|
|
22
|
+
.that.respondsTo("addAfterware");
|
|
21
23
|
});
|
|
22
24
|
});
|
|
23
25
|
describe("ServerManager", () => {
|
|
@@ -200,7 +202,7 @@ describe("ServerManager.startService(ServerConfiguration)", () => {
|
|
|
200
202
|
});
|
|
201
203
|
});
|
|
202
204
|
|
|
203
|
-
it("should be able to use the ServerManager.
|
|
205
|
+
it("should be able to use the ServerManager.addBeforware method to add additional route handling", async () => {
|
|
204
206
|
const ServerManager = createServerManager();
|
|
205
207
|
const route = "/testAPI";
|
|
206
208
|
const port = 5454;
|
|
@@ -228,15 +230,15 @@ describe("ServerManager.startService(ServerConfiguration)", () => {
|
|
|
228
230
|
},
|
|
229
231
|
};
|
|
230
232
|
|
|
231
|
-
ServerManager.
|
|
233
|
+
ServerManager.addBeforware((req, res, next) => {
|
|
232
234
|
req.$allHandlerAdded = true;
|
|
233
235
|
next();
|
|
234
236
|
});
|
|
235
|
-
ServerManager.
|
|
237
|
+
ServerManager.addBeforware(`${name}.put`, (req, res, next) => {
|
|
236
238
|
req.putHandlerAdded = true;
|
|
237
239
|
next();
|
|
238
240
|
});
|
|
239
|
-
ServerManager.
|
|
241
|
+
ServerManager.addBeforware(`${name}.test`, (req, res, next) => {
|
|
240
242
|
res.sendError({ status: 400, message: "tested passed" });
|
|
241
243
|
});
|
|
242
244
|
ServerManager.addModule(name, object);
|
|
@@ -305,4 +307,111 @@ describe("ServerManager.startService(ServerConfiguration)", () => {
|
|
|
305
307
|
SystemLynxService: true,
|
|
306
308
|
});
|
|
307
309
|
});
|
|
310
|
+
it("should be able to use the ServerManager.addAfterware method to add additional route handling after the method call", async () => {
|
|
311
|
+
const ServerManager = createServerManager();
|
|
312
|
+
const route = "/testAPI";
|
|
313
|
+
const port = 5455;
|
|
314
|
+
const url = `http://localhost:${port}${route}`;
|
|
315
|
+
const name = "testObject";
|
|
316
|
+
const object = {
|
|
317
|
+
get: function () {
|
|
318
|
+
const { req } = this;
|
|
319
|
+
return {
|
|
320
|
+
SERVICE_TEST_PASSED: false,
|
|
321
|
+
$allHandlerAdded: false,
|
|
322
|
+
putHandlerAdded: false,
|
|
323
|
+
};
|
|
324
|
+
},
|
|
325
|
+
put: function () {
|
|
326
|
+
const { req } = this;
|
|
327
|
+
return {
|
|
328
|
+
SERVICE_TEST_PASSED: false,
|
|
329
|
+
$allHandlerAdded: false,
|
|
330
|
+
putHandlerAdded: false,
|
|
331
|
+
};
|
|
332
|
+
},
|
|
333
|
+
test: function () {
|
|
334
|
+
return { SERVICE_TEST_PASSED: false };
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
ServerManager.addAfterware((req, res, next) => {
|
|
339
|
+
req.returnValue.$allHandlerAdded = true;
|
|
340
|
+
req.returnValue.SERVICE_TEST_PASSED = true;
|
|
341
|
+
next();
|
|
342
|
+
});
|
|
343
|
+
ServerManager.addAfterware(`${name}.put`, (req, res, next) => {
|
|
344
|
+
req.returnValue.putHandlerAdded = true;
|
|
345
|
+
next();
|
|
346
|
+
});
|
|
347
|
+
ServerManager.addAfterware(`${name}.test`, (req, res, next) => {
|
|
348
|
+
res.sendError({ status: 400, message: "tested passed" });
|
|
349
|
+
});
|
|
350
|
+
ServerManager.addModule(name, object);
|
|
351
|
+
await ServerManager.startService({
|
|
352
|
+
route,
|
|
353
|
+
port,
|
|
354
|
+
staticRouting: true,
|
|
355
|
+
useREST: true,
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const results = await new Promise((resolve) => {
|
|
359
|
+
request({ url: `${url}/${name}/get`, json: true }, (err, res, body) => {
|
|
360
|
+
resolve(body);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
expect(results).to.deep.equal({
|
|
365
|
+
returnValue: {
|
|
366
|
+
SERVICE_TEST_PASSED: true,
|
|
367
|
+
$allHandlerAdded: true,
|
|
368
|
+
putHandlerAdded: false,
|
|
369
|
+
},
|
|
370
|
+
fn: "get",
|
|
371
|
+
message: "[SystemLynx][response]: testObject.get(...) returned successfully",
|
|
372
|
+
module_name: "testObject",
|
|
373
|
+
serviceUrl: "http://localhost:5455/testAPI",
|
|
374
|
+
status: 200,
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
const result2 = await new Promise((resolve) => {
|
|
378
|
+
request(
|
|
379
|
+
{ url: `${url}/${name}/put`, json: true, method: "PUT" },
|
|
380
|
+
(err, res, body) => {
|
|
381
|
+
resolve(body);
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
expect(result2).to.deep.equal({
|
|
387
|
+
returnValue: {
|
|
388
|
+
SERVICE_TEST_PASSED: true,
|
|
389
|
+
$allHandlerAdded: true,
|
|
390
|
+
putHandlerAdded: true,
|
|
391
|
+
},
|
|
392
|
+
fn: "put",
|
|
393
|
+
message: "[SystemLynx][response]: testObject.put(...) returned successfully",
|
|
394
|
+
module_name: "testObject",
|
|
395
|
+
serviceUrl: "http://localhost:5455/testAPI",
|
|
396
|
+
status: 200,
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
const result3 = await new Promise((resolve) => {
|
|
400
|
+
request(
|
|
401
|
+
{ url: `${url}/${name}/test`, json: true, method: "post" },
|
|
402
|
+
(err, res, body) => {
|
|
403
|
+
resolve(body);
|
|
404
|
+
}
|
|
405
|
+
);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
expect(result3).to.deep.equal({
|
|
409
|
+
message: "tested passed",
|
|
410
|
+
fn: "test",
|
|
411
|
+
module_name: "testObject",
|
|
412
|
+
serviceUrl: "http://localhost:5455/testAPI",
|
|
413
|
+
status: 400,
|
|
414
|
+
SystemLynxService: true,
|
|
415
|
+
});
|
|
416
|
+
});
|
|
308
417
|
});
|
|
@@ -8,8 +8,14 @@ module.exports = function createService(
|
|
|
8
8
|
systemContext = {}
|
|
9
9
|
) {
|
|
10
10
|
const ServerManager = createServerManager(customServer, customWebSocketServer);
|
|
11
|
-
const { startService,
|
|
12
|
-
const Service = {
|
|
11
|
+
const { startService, addBeforware, addAfterware, server, WebSocket } = ServerManager;
|
|
12
|
+
const Service = {
|
|
13
|
+
startService,
|
|
14
|
+
server,
|
|
15
|
+
WebSocket,
|
|
16
|
+
before: addBeforware,
|
|
17
|
+
after: addAfterware,
|
|
18
|
+
};
|
|
13
19
|
|
|
14
20
|
Service.module = function (name, constructor, reserved_methods = []) {
|
|
15
21
|
const exclude_methods = reserved_methods.concat(
|
|
@@ -19,9 +25,18 @@ module.exports = function createService(
|
|
|
19
25
|
if (typeof args[0] === "string") {
|
|
20
26
|
const arg1 = args.shift();
|
|
21
27
|
const fn = arg1 === "$all" ? "" : `.${arg1}`;
|
|
22
|
-
|
|
28
|
+
addBeforware(`${name}${fn}`, ...args);
|
|
29
|
+
} else {
|
|
30
|
+
addBeforware(`${name}`, ...args);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const after = (...args) => {
|
|
34
|
+
if (typeof args[0] === "string") {
|
|
35
|
+
const arg1 = args.shift();
|
|
36
|
+
const fn = arg1 === "$all" ? "" : `.${arg1}`;
|
|
37
|
+
addAfterware(`${name}${fn}`, ...args);
|
|
23
38
|
} else {
|
|
24
|
-
|
|
39
|
+
addAfterware(`${name}`, ...args);
|
|
25
40
|
}
|
|
26
41
|
};
|
|
27
42
|
if (typeof constructor === "object" && constructor instanceof Object) {
|
|
@@ -33,6 +48,7 @@ module.exports = function createService(
|
|
|
33
48
|
}, {}),
|
|
34
49
|
...systemContext,
|
|
35
50
|
before,
|
|
51
|
+
after,
|
|
36
52
|
},
|
|
37
53
|
[undefined, systemContext]
|
|
38
54
|
);
|
|
@@ -44,7 +60,7 @@ module.exports = function createService(
|
|
|
44
60
|
if (constructor.constructor.name === "AsyncFunction")
|
|
45
61
|
throw `[SystemLynx][Service][Error]: Module(name, constructor) function cannot receive an async function as the constructor`;
|
|
46
62
|
|
|
47
|
-
const Module = createDispatcher.apply({ ...systemContext, before }, [
|
|
63
|
+
const Module = createDispatcher.apply({ ...systemContext, before, after }, [
|
|
48
64
|
undefined,
|
|
49
65
|
systemContext,
|
|
50
66
|
]);
|
|
@@ -7,10 +7,18 @@ describe("createService", () => {
|
|
|
7
7
|
const Service = createService();
|
|
8
8
|
expect(Service)
|
|
9
9
|
.to.be.an("object")
|
|
10
|
-
.that.has.all.keys(
|
|
10
|
+
.that.has.all.keys(
|
|
11
|
+
"startService",
|
|
12
|
+
"module",
|
|
13
|
+
"server",
|
|
14
|
+
"WebSocket",
|
|
15
|
+
"before",
|
|
16
|
+
"after"
|
|
17
|
+
)
|
|
11
18
|
.that.respondsTo("startService")
|
|
12
19
|
.that.respondsTo("module")
|
|
13
|
-
.that.respondsTo("before")
|
|
20
|
+
.that.respondsTo("before")
|
|
21
|
+
.that.respondsTo("after");
|
|
14
22
|
});
|
|
15
23
|
});
|
|
16
24
|
|
|
@@ -61,11 +69,12 @@ describe("Service.module(constructor)", () => {
|
|
|
61
69
|
|
|
62
70
|
expect(mod)
|
|
63
71
|
.to.be.an("Object")
|
|
64
|
-
.that.has.all.keys("on", "emit", "$clearEvent", "before", "test", "test2")
|
|
72
|
+
.that.has.all.keys("on", "emit", "$clearEvent", "before", "after", "test", "test2")
|
|
65
73
|
.that.respondsTo("on")
|
|
66
74
|
.that.respondsTo("emit")
|
|
67
75
|
.that.respondsTo("$clearEvent")
|
|
68
76
|
.that.respondsTo("before")
|
|
77
|
+
.that.respondsTo("after")
|
|
69
78
|
.that.respondsTo("test")
|
|
70
79
|
.that.respondsTo("test2");
|
|
71
80
|
});
|
|
@@ -144,6 +153,10 @@ describe("Service.module(object)", () => {
|
|
|
144
153
|
req.beforeAction3 = true;
|
|
145
154
|
next();
|
|
146
155
|
});
|
|
156
|
+
this.after("action3", (req, res, next) => {
|
|
157
|
+
req.returnValue.afterAction3 = true;
|
|
158
|
+
next();
|
|
159
|
+
});
|
|
147
160
|
});
|
|
148
161
|
mod.before(
|
|
149
162
|
"action1",
|
|
@@ -156,25 +169,54 @@ describe("Service.module(object)", () => {
|
|
|
156
169
|
next();
|
|
157
170
|
}
|
|
158
171
|
);
|
|
172
|
+
mod.after(
|
|
173
|
+
"action1",
|
|
174
|
+
(req, res, next) => {
|
|
175
|
+
req.returnValue.afterAction1 = true;
|
|
176
|
+
next();
|
|
177
|
+
},
|
|
178
|
+
(req, res, next) => {
|
|
179
|
+
req.returnValue.afterAction12 = true;
|
|
180
|
+
next();
|
|
181
|
+
}
|
|
182
|
+
);
|
|
159
183
|
|
|
160
184
|
mod.before((req, res, next) => {
|
|
161
185
|
req.beforeModule = true;
|
|
162
186
|
next();
|
|
163
187
|
});
|
|
188
|
+
mod.after((req, res, next) => {
|
|
189
|
+
req.returnValue.afterModule = true;
|
|
190
|
+
next();
|
|
191
|
+
});
|
|
164
192
|
|
|
165
193
|
Service.before((req, res, next) => {
|
|
166
194
|
req.beforeService = true;
|
|
167
195
|
next();
|
|
168
196
|
});
|
|
197
|
+
Service.after((req, res, next) => {
|
|
198
|
+
req.returnValue.afterService = true;
|
|
199
|
+
next();
|
|
200
|
+
});
|
|
201
|
+
|
|
169
202
|
expect(mod)
|
|
170
203
|
.to.be.an("Object")
|
|
171
|
-
.that.has.all.keys(
|
|
204
|
+
.that.has.all.keys(
|
|
205
|
+
"action1",
|
|
206
|
+
"action2",
|
|
207
|
+
"on",
|
|
208
|
+
"emit",
|
|
209
|
+
"$clearEvent",
|
|
210
|
+
"before",
|
|
211
|
+
"after"
|
|
212
|
+
)
|
|
172
213
|
.that.respondsTo("action1")
|
|
173
214
|
.that.respondsTo("action2")
|
|
174
215
|
.that.respondsTo("on")
|
|
175
216
|
.that.respondsTo("emit")
|
|
176
217
|
.that.respondsTo("$clearEvent")
|
|
177
|
-
.that.respondsTo("before")
|
|
218
|
+
.that.respondsTo("before")
|
|
219
|
+
.that.respondsTo("after");
|
|
178
220
|
});
|
|
179
221
|
it("should 'Serve' Service connection data created using an object as the constructor", async () => {
|
|
180
222
|
await Service.startService({ route, port });
|
|
@@ -217,19 +259,35 @@ describe("Service.module(object)", () => {
|
|
|
217
259
|
expect(results.port, port);
|
|
218
260
|
});
|
|
219
261
|
|
|
220
|
-
it("should use SeverModule.before method to add a route handler before
|
|
262
|
+
it("should use SeverModule.before method and SeverModule.after method to add a route handler before and after target method ", async () => {
|
|
221
263
|
const Client = createClient();
|
|
222
264
|
const { mod, mod2 } = await Client.loadService(url);
|
|
223
265
|
const result = await mod.action1();
|
|
266
|
+
|
|
224
267
|
expect(result).to.deep.equal({
|
|
225
268
|
beforeAction1: true,
|
|
226
269
|
beforeAction12: true,
|
|
227
270
|
beforeModule: true,
|
|
228
271
|
beforeService: true,
|
|
272
|
+
|
|
273
|
+
afterAction1: true,
|
|
274
|
+
afterAction12: true,
|
|
275
|
+
afterModule: true,
|
|
276
|
+
afterService: true,
|
|
229
277
|
});
|
|
230
278
|
const result2 = await mod.action2();
|
|
231
|
-
expect(result2).to.deep.equal({
|
|
279
|
+
expect(result2).to.deep.equal({
|
|
280
|
+
beforeModule: true,
|
|
281
|
+
beforeService: true,
|
|
282
|
+
afterModule: true,
|
|
283
|
+
afterService: true,
|
|
284
|
+
});
|
|
232
285
|
const result3 = await mod2.action3();
|
|
233
|
-
expect(result3).to.deep.equal({
|
|
286
|
+
expect(result3).to.deep.equal({
|
|
287
|
+
beforeAction3: true,
|
|
288
|
+
beforeService: true,
|
|
289
|
+
afterAction3: true,
|
|
290
|
+
afterService: true,
|
|
291
|
+
});
|
|
234
292
|
});
|
|
235
293
|
});
|