systemlynx 1.7.2 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/API.md +7 -0
  2. package/README.md +11 -5
  3. package/index.js +22 -23
  4. package/index.test.js +47 -17
  5. package/package.json +3 -4
  6. package/systemlynx/App/App.js +11 -6
  7. package/systemlynx/App/components/initializeApp.js +2 -2
  8. package/systemlynx/App/components/loadServices.js +3 -3
  9. package/systemlynx/App/tests/App.test.js +95 -31
  10. package/systemlynx/Client/Client.js +6 -3
  11. package/systemlynx/Client/components/ClientModule.js +9 -3
  12. package/systemlynx/Client/components/ServiceRequestHandler.js +23 -19
  13. package/systemlynx/Client/components/SocketDispatcher.js +2 -2
  14. package/systemlynx/Client/components/loadConnectionData.js +6 -4
  15. package/systemlynx/Client/tests/Client.test.js +27 -16
  16. package/systemlynx/Client/tests/SocketDispatcher.test.js +17 -6
  17. package/systemlynx/Dispatcher/Dispatcher.js +16 -1
  18. package/systemlynx/Dispatcher/Dispatcher.test.js +4 -3
  19. package/systemlynx/HttpClient/HttpClient.js +1 -1
  20. package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +30 -7
  21. package/systemlynx/ServerManager/ServerManager.js +75 -36
  22. package/systemlynx/ServerManager/components/Router.js +31 -12
  23. package/systemlynx/ServerManager/components/Server.js +23 -20
  24. package/systemlynx/ServerManager/components/SocketEmitter.js +2 -2
  25. package/systemlynx/ServerManager/components/WebSocketServer.js +2 -2
  26. package/systemlynx/ServerManager/components/clearFolder.js +10 -0
  27. package/systemlynx/ServerManager/components/parseMethods.js +1 -1
  28. package/systemlynx/ServerManager/tests/ServerManager.test.js +124 -11
  29. package/systemlynx/Service/Service.js +31 -12
  30. package/systemlynx/Service/Service.test.js +81 -16
  31. package/temp/.gitignore +0 -4
@@ -3,8 +3,8 @@ const isObject = (value) =>
3
3
  const isEmpty = (obj) => Object.getOwnPropertyNames(obj).length === 0;
4
4
  const isPromise = (p) => typeof p === "object" && typeof (p || {}).then === "function";
5
5
 
6
- module.exports = function SystemLynxRouter(server, config) {
7
- const addService = (Module, route, { fn, method }, module_name) => {
6
+ module.exports = function createRouter(server, config) {
7
+ const addService = (Module, route, { fn, method }, module_name, validators) => {
8
8
  server[method](
9
9
  [`/${route}/${fn}`, `/sf/${route}/${fn}`, `/mf/${route}/${fn}`],
10
10
  (req, res, next) => {
@@ -13,11 +13,13 @@ module.exports = function SystemLynxRouter(server, config) {
13
13
  req.Module = Module;
14
14
  next();
15
15
  },
16
- routeHandler
16
+ setHelpers,
17
+ validators,
18
+ requestHandler
17
19
  );
18
20
  };
19
21
 
20
- const addREST = (Module, route, { method }, module_name) => {
22
+ const addREST = (Module, route, { method }, module_name, validators) => {
21
23
  server[method](
22
24
  [`/${route}`],
23
25
  (req, res, next) => {
@@ -26,12 +28,15 @@ module.exports = function SystemLynxRouter(server, config) {
26
28
  req.Module = Module;
27
29
  next();
28
30
  },
29
- routeHandler
31
+ setHelpers,
32
+ validators,
33
+ requestHandler
30
34
  );
31
35
  };
32
36
 
33
- const routeHandler = (req, res) => {
34
- const { query, file, files, body, fn, Module, module_name, method } = req;
37
+ const setHelpers = (req, res, next) => {
38
+ const { fn, module_name, query, file, files, body, method, Module } = req;
39
+
35
40
  const { serviceUrl } = config();
36
41
  const presets = { serviceUrl, module_name, fn };
37
42
  const unhandledMessage = `[SystemLynx]: handled error While calling ${module_name}.${fn}(...)`;
@@ -44,12 +49,12 @@ module.exports = function SystemLynxRouter(server, config) {
44
49
  ...error,
45
50
  status,
46
51
  message,
47
- SystemLynxServiceError: true,
52
+ SystemLynxService: true,
48
53
  });
49
54
  };
50
55
 
51
56
  const sendResponse = (returnValue) => {
52
- const status = (returnValue || {}).status || 200;
57
+ const status = (returnValue || {}).status >= 100 ? returnValue.status : 200;
53
58
  if (status < 400) {
54
59
  res.status(status).json({
55
60
  ...presets,
@@ -68,12 +73,26 @@ module.exports = function SystemLynxRouter(server, config) {
68
73
  status: 404,
69
74
  });
70
75
 
71
- try {
76
+ const getArguments = () => {
72
77
  const args = body.__arguments || [];
73
78
  if (!isEmpty(query) && !args.length) args.push(query);
74
- if (isObject(args[0]) && method === "PUT") args[0] = { ...args[0], file, files };
79
+ if (isObject(args[0]) && method === "PUT")
80
+ args[0] = { ...args[0], ...(file && { file }), ...(files && { files }) };
81
+ return args;
82
+ };
83
+ req.arguments = getArguments();
84
+ res.sendError = sendError;
85
+ res.sendResponse = sendResponse;
86
+ next();
87
+ };
88
+
89
+ const requestHandler = (req, res) => {
90
+ const { fn, Module } = req;
91
+ const { sendError, sendResponse } = res;
75
92
 
76
- const results = Module[fn].apply(Module, args);
93
+ try {
94
+ const args = req.arguments;
95
+ const results = Module[fn].apply({ ...Module, req, res }, args);
77
96
 
78
97
  if (isPromise(results)) {
79
98
  results.then(sendResponse).catch(sendError);
@@ -1,12 +1,12 @@
1
1
  //express server, socket.io server and middleware needed for SystemLynx basic functionality
2
-
3
- module.exports = function SystemLynxServer() {
2
+ const clearFolder = require("./clearFolder");
3
+ const clearTempFolder = clearFolder.bind({}, "./temp");
4
+ module.exports = function createServer(customServer) {
4
5
  const cwd = process.cwd();
5
6
  //express server
6
7
  const express = require("express");
7
- const server = express();
8
+ const server = customServer || express();
8
9
  //express middleware
9
- const bodyParser = require("body-parser");
10
10
  const multer = require("multer");
11
11
  //express file upload middleware setup
12
12
  const TEMP_LOCATION = "./temp";
@@ -18,35 +18,38 @@ module.exports = function SystemLynxServer() {
18
18
  cb(null, `${shortId()}.${mime.getExtension(file.mimetype)}`),
19
19
  });
20
20
  //multi-file and single-file upload middleware functions
21
- const sf = multer({ storage: storage }).single("file");
22
- const mf = multer({ storage: storage }).array("files");
21
+ const sf = multer({ storage }).single("file");
22
+ const mf = multer({ storage }).array("files");
23
23
  //the sf and mf functions are used to a extract file from the req during a file upload
24
24
  //a property named file and files will be added to the req object respectively
25
25
  const singleFileUpload = (req, res, next) =>
26
26
  sf(req, res, (err) => {
27
- if (err) res.json(errorResponseBuilder(err));
28
- else next();
27
+ if (err) return res.json(err);
28
+ res.on("finish", clearTempFolder);
29
+ next();
29
30
  });
30
31
  const multiFileUpload = (req, res, next) =>
31
32
  mf(req, res, (err) => {
32
- if (err) res.json(errorResponseBuilder(err));
33
- else next();
33
+ if (err) return res.json(err);
34
+ res.on("finish", clearTempFolder);
35
+ next();
34
36
  });
35
37
 
36
38
  server.use("/sf", singleFileUpload);
37
39
  server.use("/mf", multiFileUpload);
38
40
  server.use(express.static(cwd + "/public"));
39
- server.use(bodyParser.json({ limit: "5mb" }));
41
+ server.use(express.json({ limit: "5mb" }));
40
42
 
41
- server.use((req, res, next) => {
42
- res.setHeader("Access-Control-Allow-Origin", "*");
43
- res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT ,DELETE");
44
- res.setHeader(
45
- "Access-Control-Allow-Headers",
46
- "X-Requested-With,content-type, Authorization"
47
- );
48
- next();
49
- });
43
+ !customServer &&
44
+ server.use((req, res, next) => {
45
+ res.setHeader("Access-Control-Allow-Origin", "*");
46
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT ,DELETE");
47
+ res.setHeader(
48
+ "Access-Control-Allow-Headers",
49
+ "X-Requested-With,content-type, Authorization"
50
+ );
51
+ next();
52
+ });
50
53
 
51
54
  return server;
52
55
  };
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
- const SystemLynxDispatcher = require("../../Dispatcher/Dispatcher");
2
+ const createDispatcher = require("../../Dispatcher/Dispatcher");
3
3
  const shortid = require("shortid");
4
4
  module.exports = function SocketEmitter(namespace, WebSocket) {
5
5
  const Emitter =
6
- (this || {}).on && (this || {}).emit ? this : SystemLynxDispatcher.apply(this);
6
+ (this || {}).on && (this || {}).emit ? this : createDispatcher.apply(this);
7
7
 
8
8
  const socket = WebSocket.of(`/${namespace}`);
9
9
  //use $emit to emit events locally only
@@ -1,6 +1,6 @@
1
- module.exports = function SystemLynxWebWebSocket() {
1
+ module.exports = function createWebSocket(server) {
2
2
  const express = require("express");
3
- const SocketServer = require("http").Server(express());
3
+ const SocketServer = require("http").Server(server || express());
4
4
  const WebSocket = require("socket.io")(SocketServer);
5
5
 
6
6
  return { WebSocket, SocketServer };
@@ -0,0 +1,10 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ module.exports = function clearFolder(folder) {
4
+ fs.readdir(folder, (err, files) => {
5
+ if (err) return console.error(err);
6
+ files.forEach((file) => {
7
+ fs.unlink(path.join(folder, file), (err) => err && console.error(err));
8
+ });
9
+ });
10
+ };
@@ -1,6 +1,6 @@
1
1
  const parseMethods = (obj, reserved_methods = [], useREST) => {
2
2
  const methods = [];
3
- const REST_methods = ["get", "put", "post", "delete"];
3
+ const REST_methods = ["get", "put", "post", "delete", "options"];
4
4
  const props = Object.getOwnPropertyNames(obj);
5
5
 
6
6
  props.forEach((fn) => {
@@ -1,21 +1,28 @@
1
1
  const { expect } = require("chai");
2
- const SystemLynxServerManager = require("../ServerManager");
2
+ const createServerManager = require("../ServerManager");
3
3
  const request = require("request");
4
4
 
5
- describe("SystemLynxServerManager function", () => {
5
+ describe("createServerManager function", () => {
6
6
  it("should return an ServerManager instance", () => {
7
- const ServerManager = SystemLynxServerManager();
7
+ const ServerManager = createServerManager();
8
8
 
9
9
  expect(ServerManager)
10
10
  .to.be.an("Object")
11
- .that.has.all.keys(["startService", "addModule", "server", "WebSocket"])
11
+ .that.has.all.keys([
12
+ "startService",
13
+ "addModule",
14
+ "addRouteHandler",
15
+ "server",
16
+ "WebSocket",
17
+ ])
12
18
  .that.respondsTo("startService")
13
- .that.respondsTo("addModule");
19
+ .that.respondsTo("addModule")
20
+ .that.respondsTo("addRouteHandler");
14
21
  });
15
22
  });
16
23
  describe("ServerManager", () => {
17
24
  it("should be able use ServerManager.startService to start a server that will accept requests for Module Connection Data on the given route", async () => {
18
- const ServerManager = SystemLynxServerManager();
25
+ const ServerManager = createServerManager();
19
26
  const route = "/testService";
20
27
  const port = 4400;
21
28
  const url = `http://localhost:${port}${route}`;
@@ -43,7 +50,7 @@ describe("ServerManager", () => {
43
50
  });
44
51
 
45
52
  it("should be able to use the ServerManager.addModule method to add data to the ServerManager instance that can be accessed via a GET request", async () => {
46
- const ServerManager = SystemLynxServerManager();
53
+ const ServerManager = createServerManager();
47
54
  const route = "/testService";
48
55
  const port = 4634;
49
56
  const url = `http://localhost:${port}${route}`;
@@ -78,7 +85,7 @@ describe("ServerManager", () => {
78
85
  });
79
86
 
80
87
  it("should be able call ServerManager.addModule method before or after calling ServerManager.startService", async () => {
81
- const ServerManager = SystemLynxServerManager();
88
+ const ServerManager = createServerManager();
82
89
  const route = "/testService";
83
90
  const port = 4500;
84
91
  const url = `http://localhost:${port}${route}`;
@@ -117,13 +124,13 @@ describe("ServerManager", () => {
117
124
 
118
125
  describe("ServerManager.startService(ServerConfiguration)", () => {
119
126
  it("should be able to use the useREST=true property to create a REST API route for any method with the name 'get', 'put', 'post' or 'delete'", async () => {
120
- const ServerManager = SystemLynxServerManager();
127
+ const ServerManager = createServerManager();
121
128
  const route = "/testAPI";
122
129
  const port = 8372;
123
130
  const url = `http://localhost:${port}${route}`;
124
131
  const name = "testObject";
125
132
  const object = {
126
- get: () => (null, { REST_TEST_PASSED: true }),
133
+ get: () => ({ REST_TEST_PASSED: true }),
127
134
  put: () => {},
128
135
  post: () => {},
129
136
  delete: () => {},
@@ -156,7 +163,7 @@ describe("ServerManager.startService(ServerConfiguration)", () => {
156
163
  });
157
164
 
158
165
  it("should be able to use the staticRouting=true property to create static routes to the Modules", async () => {
159
- const ServerManager = SystemLynxServerManager();
166
+ const ServerManager = createServerManager();
160
167
  const route = "/testAPI";
161
168
  const port = 2233;
162
169
  const url = `http://localhost:${port}${route}`;
@@ -192,4 +199,110 @@ describe("ServerManager.startService(ServerConfiguration)", () => {
192
199
  status: 200,
193
200
  });
194
201
  });
202
+
203
+ it("should be able to use the ServerManager.addRouteHandler method to add additional route handling", async () => {
204
+ const ServerManager = createServerManager();
205
+ const route = "/testAPI";
206
+ const port = 5454;
207
+ const url = `http://localhost:${port}${route}`;
208
+ const name = "testObject";
209
+ const object = {
210
+ get: function () {
211
+ const { req } = this;
212
+ return {
213
+ SERVICE_TEST_PASSED: true,
214
+ $allHandlerAdded: req.$allHandlerAdded,
215
+ putHandlerAdded: req.putHandlerAdded,
216
+ };
217
+ },
218
+ put: function () {
219
+ const { req } = this;
220
+ return {
221
+ SERVICE_TEST_PASSED: true,
222
+ $allHandlerAdded: req.$allHandlerAdded,
223
+ putHandlerAdded: req.putHandlerAdded,
224
+ };
225
+ },
226
+ test: function () {
227
+ return { SERVICE_TEST_PASSED: false };
228
+ },
229
+ };
230
+
231
+ ServerManager.addRouteHandler((req, res, next) => {
232
+ req.$allHandlerAdded = true;
233
+ next();
234
+ });
235
+ ServerManager.addRouteHandler(`${name}.put`, (req, res, next) => {
236
+ req.putHandlerAdded = true;
237
+ next();
238
+ });
239
+ ServerManager.addRouteHandler(`${name}.test`, (req, res, next) => {
240
+ res.sendError({ status: 400, message: "tested passed" });
241
+ });
242
+ ServerManager.addModule(name, object);
243
+ await ServerManager.startService({
244
+ route,
245
+ port,
246
+ staticRouting: true,
247
+ useREST: true,
248
+ });
249
+
250
+ const results = await new Promise((resolve) => {
251
+ request({ url: `${url}/${name}/get`, json: true }, (err, res, body) => {
252
+ resolve(body);
253
+ });
254
+ });
255
+
256
+ expect(results).to.deep.equal({
257
+ returnValue: {
258
+ SERVICE_TEST_PASSED: true,
259
+ $allHandlerAdded: true,
260
+ },
261
+ fn: "get",
262
+ message: "[SystemLynx][response]: testObject.get(...) returned successfully",
263
+ module_name: "testObject",
264
+ serviceUrl: "http://localhost:5454/testAPI",
265
+ status: 200,
266
+ });
267
+
268
+ const result2 = await new Promise((resolve) => {
269
+ request(
270
+ { url: `${url}/${name}/put`, json: true, method: "PUT" },
271
+ (err, res, body) => {
272
+ resolve(body);
273
+ }
274
+ );
275
+ });
276
+
277
+ expect(result2).to.deep.equal({
278
+ returnValue: {
279
+ SERVICE_TEST_PASSED: true,
280
+ $allHandlerAdded: true,
281
+ putHandlerAdded: true,
282
+ },
283
+ fn: "put",
284
+ message: "[SystemLynx][response]: testObject.put(...) returned successfully",
285
+ module_name: "testObject",
286
+ serviceUrl: "http://localhost:5454/testAPI",
287
+ status: 200,
288
+ });
289
+
290
+ const result3 = await new Promise((resolve) => {
291
+ request(
292
+ { url: `${url}/${name}/test`, json: true, method: "PUT" },
293
+ (err, res, body) => {
294
+ resolve(body);
295
+ }
296
+ );
297
+ });
298
+
299
+ expect(result3).to.deep.equal({
300
+ message: "tested passed",
301
+ fn: "test",
302
+ module_name: "testObject",
303
+ serviceUrl: "http://localhost:5454/testAPI",
304
+ status: 400,
305
+ SystemLynxService: true,
306
+ });
307
+ });
195
308
  });
@@ -1,22 +1,41 @@
1
1
  "use strict";
2
- const SystemLynxServerManager = require("../ServerManager/ServerManager");
3
- const SystemLynxDispatcher = require("../Dispatcher/Dispatcher");
2
+ const createServerManager = require("../ServerManager/ServerManager");
3
+ const createDispatcher = require("../Dispatcher/Dispatcher");
4
4
 
5
- module.exports = function SystemLynxService(systemContext = {}) {
6
- const ServerManager = SystemLynxServerManager();
7
- const { startService, server, WebSocket } = ServerManager;
8
- const Service = { startService, server, WebSocket };
5
+ module.exports = function createService(
6
+ customServer,
7
+ customWebSocketServer,
8
+ systemContext = {}
9
+ ) {
10
+ const ServerManager = createServerManager(customServer, customWebSocketServer);
11
+ const { startService, addRouteHandler, server, WebSocket } = ServerManager;
12
+ const Service = { startService, server, WebSocket, before: addRouteHandler };
9
13
 
10
14
  Service.module = function (name, constructor, reserved_methods = []) {
11
15
  const exclude_methods = reserved_methods.concat(
12
16
  Object.getOwnPropertyNames(systemContext)
13
17
  );
14
-
18
+ const before = (...args) => {
19
+ if (typeof args[0] === "string") {
20
+ const arg1 = args.shift();
21
+ const fn = arg1 === "$all" ? "" : `.${arg1}`;
22
+ addRouteHandler(`${name}${fn}`, ...args);
23
+ } else {
24
+ addRouteHandler(`${name}`, ...args);
25
+ }
26
+ };
15
27
  if (typeof constructor === "object" && constructor instanceof Object) {
16
- const Module = SystemLynxDispatcher.apply({ ...constructor, ...systemContext }, [
17
- undefined,
18
- systemContext,
19
- ]);
28
+ const Module = createDispatcher.apply(
29
+ {
30
+ ...Object.getOwnPropertyNames(constructor).reduce((obj, fn) => {
31
+ if (typeof constructor[fn] === "function") obj[fn] = constructor[fn];
32
+ return obj;
33
+ }, {}),
34
+ ...systemContext,
35
+ before,
36
+ },
37
+ [undefined, systemContext]
38
+ );
20
39
  ServerManager.addModule(name, Module, exclude_methods);
21
40
  return Module;
22
41
  }
@@ -25,7 +44,7 @@ module.exports = function SystemLynxService(systemContext = {}) {
25
44
  if (constructor.constructor.name === "AsyncFunction")
26
45
  throw `[SystemLynx][Module][Error]: Module(name, constructor) function cannot receive an async function as the constructor`;
27
46
 
28
- const Module = SystemLynxDispatcher.apply(systemContext, [
47
+ const Module = createDispatcher.apply({ ...systemContext, before }, [
29
48
  undefined,
30
49
  systemContext,
31
50
  ]);
@@ -1,21 +1,22 @@
1
1
  const { expect } = require("chai");
2
2
  const request = require("request");
3
- const SystemLynxService = require("./Service");
4
-
5
- describe("SystemLynxService", () => {
3
+ const createService = require("./Service");
4
+ const createClient = require("../Client/Client");
5
+ describe("createService", () => {
6
6
  it("should return a new instance of a Service", () => {
7
- const Service = SystemLynxService();
7
+ const Service = createService();
8
8
  expect(Service)
9
9
  .to.be.an("object")
10
- .that.has.all.keys("startService", "module", "server", "WebSocket")
10
+ .that.has.all.keys("startService", "module", "server", "WebSocket", "before")
11
11
  .that.respondsTo("startService")
12
- .that.respondsTo("module");
12
+ .that.respondsTo("module")
13
+ .that.respondsTo("before");
13
14
  });
14
15
  });
15
16
 
16
17
  describe("Service factory", () => {
17
18
  it("should be able to use Service.startService to initiate a ServerManager instance that hosts the Service Connection Data", async () => {
18
- const Service = SystemLynxService();
19
+ const Service = createService();
19
20
  const route = "/testService";
20
21
  const port = 5500;
21
22
  const url = `http://localhost:${port}${route}`;
@@ -47,7 +48,7 @@ describe("Service factory", () => {
47
48
  });
48
49
 
49
50
  describe("Service.module(constructor)", () => {
50
- const Service = SystemLynxService();
51
+ const Service = createService();
51
52
  const port = 6542;
52
53
  const route = "test/service";
53
54
  const url = `http://localhost:${port}/${route}`;
@@ -60,13 +61,15 @@ describe("Service.module(constructor)", () => {
60
61
 
61
62
  expect(mod)
62
63
  .to.be.an("Object")
63
- .that.has.all.keys("on", "emit", "test", "test2")
64
+ .that.has.all.keys("on", "emit", "$clearEvent", "before", "test", "test2")
64
65
  .that.respondsTo("on")
65
66
  .that.respondsTo("emit")
67
+ .that.respondsTo("$clearEvent")
68
+ .that.respondsTo("before")
66
69
  .that.respondsTo("test")
67
70
  .that.respondsTo("test2");
68
71
  });
69
- it("should 'Serve' Service connection data created using the 'this' value of the constructor function", async () => {
72
+ it("should 'Serve' Service connection data", async () => {
70
73
  await Service.startService({ route, port });
71
74
 
72
75
  const results = await new Promise((resolve) =>
@@ -109,23 +112,69 @@ describe("Service.module(constructor)", () => {
109
112
  });
110
113
 
111
114
  describe("Service.module(object)", () => {
112
- const Service = SystemLynxService();
115
+ const Service = createService();
113
116
  const port = 6543;
114
117
  const route = "test/service2";
115
118
  const url = `http://localhost:${port}/${route}`;
116
- it("should be able to return a Service instance created using an object as the constructor", () => {
119
+ it("should return a ServerModule instance created using an object as the constructor", () => {
117
120
  const mod = Service.module("mod", {
118
- action1: () => {},
119
- action2: () => {},
121
+ action1: function () {
122
+ const { req } = this;
123
+ const { beforeAction1, beforeAction12, beforeModule, beforeService } = req;
124
+ return {
125
+ beforeAction1,
126
+ beforeModule,
127
+ beforeService,
128
+ beforeAction12,
129
+ };
130
+ },
131
+ action2: function () {
132
+ const { req } = this;
133
+ const { beforeAction1, beforeModule, beforeService } = req;
134
+ return { beforeAction1, beforeModule, beforeService };
135
+ },
136
+ });
137
+ Service.module("mod2", function () {
138
+ this.action3 = function () {
139
+ const { req } = this;
140
+ const { beforeAction3, beforeModule, beforeService } = req;
141
+ return { beforeAction3, beforeModule, beforeService };
142
+ };
143
+ this.before("action3", (req, res, next) => {
144
+ req.beforeAction3 = true;
145
+ next();
146
+ });
147
+ });
148
+ mod.before(
149
+ "action1",
150
+ (req, res, next) => {
151
+ req.beforeAction1 = true;
152
+ next();
153
+ },
154
+ (req, res, next) => {
155
+ req.beforeAction12 = true;
156
+ next();
157
+ }
158
+ );
159
+
160
+ mod.before((req, res, next) => {
161
+ req.beforeModule = true;
162
+ next();
120
163
  });
121
164
 
165
+ Service.before((req, res, next) => {
166
+ req.beforeService = true;
167
+ next();
168
+ });
122
169
  expect(mod)
123
170
  .to.be.an("Object")
124
- .that.has.all.keys("action1", "action2", "on", "emit")
171
+ .that.has.all.keys("action1", "action2", "on", "emit", "$clearEvent", "before")
125
172
  .that.respondsTo("action1")
126
173
  .that.respondsTo("action2")
127
174
  .that.respondsTo("on")
128
- .that.respondsTo("emit");
175
+ .that.respondsTo("emit")
176
+ .that.respondsTo("$clearEvent")
177
+ .that.respondsTo("before");
129
178
  });
130
179
  it("should 'Serve' Service connection data created using an object as the constructor", async () => {
131
180
  await Service.startService({ route, port });
@@ -167,4 +216,20 @@ describe("Service.module(object)", () => {
167
216
  expect(results.host, "localhost");
168
217
  expect(results.port, port);
169
218
  });
219
+
220
+ it("should use SeverModule.before method to add a route handler before a target method", async () => {
221
+ const Client = createClient();
222
+ const { mod, mod2 } = await Client.loadService(url);
223
+ const result = await mod.action1();
224
+ expect(result).to.deep.equal({
225
+ beforeAction1: true,
226
+ beforeAction12: true,
227
+ beforeModule: true,
228
+ beforeService: true,
229
+ });
230
+ const result2 = await mod.action2();
231
+ expect(result2).to.deep.equal({ beforeModule: true, beforeService: true });
232
+ const result3 = await mod2.action3();
233
+ expect(result3).to.deep.equal({ beforeAction3: true, beforeService: true });
234
+ });
170
235
  });
package/temp/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- # Ignore everything in this directory
2
- *
3
- # Except this file
4
- !.gitignore