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
@@ -1,17 +1,21 @@
1
1
  "use strict";
2
2
  const ServiceRequestHandler = require("./ServiceRequestHandler");
3
3
  const SocketDispatcher = require("./SocketDispatcher");
4
+ const getProtocol = (url) => url.match(/^(\w+):\/\//)[0];
5
+
4
6
  module.exports = function SystemLynxClientModule(
7
+ httpClient,
5
8
  { methods, namespace, route, connectionData, name },
6
- { port, host },
9
+ { port, host, serviceUrl },
7
10
  reconnectService,
8
11
  systemContext
9
12
  ) {
10
13
  const events = {};
11
- const ClientModule = this || {};
14
+ const ClientModule = {};
12
15
 
13
16
  ClientModule.__setConnection = (host, port, route, namespace) => {
14
17
  ClientModule.__connectionData = () => ({ route, host, port });
18
+
15
19
  SocketDispatcher.apply(ClientModule, [namespace, events, systemContext]);
16
20
  };
17
21
  ClientModule.__setConnection(host, port, route, namespace);
@@ -24,9 +28,11 @@ module.exports = function SystemLynxClientModule(
24
28
 
25
29
  if (typeof cb === "function") cb();
26
30
  };
27
-
31
+ const protocol = getProtocol(serviceUrl);
28
32
  methods.forEach(({ method, fn }) => {
29
33
  ClientModule[fn] = ServiceRequestHandler.apply(ClientModule, [
34
+ httpClient,
35
+ protocol,
30
36
  method,
31
37
  fn,
32
38
  reconnectService,
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- const HttpClient = require("../../HttpClient/HttpClient")();
3
2
  const isObject = (value) =>
4
3
  typeof value === "object" ? (!value ? false : !Array.isArray(value)) : false;
5
4
 
@@ -9,53 +8,58 @@ const makeQuery = (data) =>
9
8
  "?"
10
9
  );
11
10
  module.exports = function ServiceRequestHandler(
11
+ httpClient,
12
+ protocol,
12
13
  method,
13
14
  fn,
14
15
  reconnectService,
15
16
  reconnectModule
16
17
  ) {
17
18
  const ClientModule = this;
18
-
19
19
  return function sendRequest() {
20
20
  const __arguments = Array.from(arguments);
21
21
 
22
22
  const tryRequest = (cb, errCount = 0) => {
23
23
  const { route, port, host } = ClientModule.__connectionData();
24
- const singleFileURL = `http://${host}:${port}/sf${route}/${fn}`;
25
- const multiFileURL = `http://${host}:${port}/mf${route}/${fn}`;
26
- const defaultURL = `http://${host}:${port}${route}/${fn}`;
24
+ const singleFileURL = `${protocol}${host}:${port}/sf${route}/${fn}`;
25
+ const multiFileURL = `${protocol}${host}:${port}/mf${route}/${fn}`;
26
+ const defaultURL = `${protocol}${host}:${port}${route}/${fn}`;
27
27
  const { file, files } = __arguments[0] || {};
28
28
  const url = file ? singleFileURL : files ? multiFileURL : defaultURL;
29
29
 
30
30
  if (url === defaultURL)
31
- HttpClient.request({
32
- url: `${url}${
33
- method === "get" && isObject(__arguments[0]) ? makeQuery(__arguments[0]) : ""
34
- }`,
35
- method,
36
- body: { __arguments },
37
- })
31
+ httpClient
32
+ .request({
33
+ url: `${url}${
34
+ method === "get" && isObject(__arguments[0])
35
+ ? makeQuery(__arguments[0])
36
+ : ""
37
+ }`,
38
+ method,
39
+ body: { __arguments },
40
+ })
38
41
  .then((results) => cb(null, results))
39
42
  .catch((err) => ErrorHandler(err, errCount, cb));
40
43
  else
41
- HttpClient.upload({
42
- url,
43
- method,
44
- formData: { ...__arguments[0], __arguments },
45
- })
44
+ httpClient
45
+ .upload({
46
+ url,
47
+ method,
48
+ formData: { ...__arguments[0], __arguments },
49
+ })
46
50
  .then((results) => cb(null, results))
47
51
  .catch((err) => ErrorHandler(err, errCount, cb));
48
52
  };
49
53
 
50
54
  const ErrorHandler = (err, errCount, cb) => {
51
- if (err.SystemLynxServiceError) {
55
+ if (err.SystemLynxService) {
52
56
  cb(err);
53
57
  } else if (errCount <= 3) {
54
58
  console.log(err);
55
59
  errCount++;
56
60
  if (reconnectModule) reconnectModule(() => tryRequest(cb, errCount));
57
61
  else reconnectService(() => tryRequest(cb, errCount));
58
- } else throw Error(`[SystemLynx][Service][Error]: Invalid route:${err}`);
62
+ } else console.error(Error(`[SystemLynx][Service][Error]: Invalid route:${err}`));
59
63
  };
60
64
 
61
65
  return new Promise((resolve, reject) =>
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  const io = require("socket.io-client");
3
- const SystemLynxDispatcher = require("../../Dispatcher/Dispatcher");
3
+ const createDispatcher = require("../../Dispatcher/Dispatcher");
4
4
 
5
5
  module.exports = function SocketDispatcher(namespace, events = {}, systemContext) {
6
6
  const dispatcher =
7
7
  (this || {}).on && (this || {}).emit
8
8
  ? this
9
- : SystemLynxDispatcher.apply(this, [events, systemContext]);
9
+ : createDispatcher.apply(this, [events, systemContext]);
10
10
  const socket = io.connect(namespace);
11
11
  socket.on("dispatch", (event) => dispatcher.emit(event.name, event.data, event));
12
12
  socket.on("disconnect", () => {
@@ -1,10 +1,12 @@
1
- const HttpClient = require("../../HttpClient/HttpClient")();
2
-
3
- module.exports = function loadConnectionData(url, { limit = 10, wait = 150 } = {}) {
1
+ module.exports = function loadConnectionData(
2
+ httpClient,
3
+ url,
4
+ { limit = 3, wait = 1000 } = {}
5
+ ) {
4
6
  const errors = [];
5
7
 
6
8
  return new Promise(function getData(resolve) {
7
- HttpClient.request({ method: "GET", url }, (err, results) => {
9
+ httpClient.request({ method: "GET", url }, (err, results) => {
8
10
  if (err) {
9
11
  errors.push(err);
10
12
 
@@ -1,14 +1,14 @@
1
1
  const { expect } = require("chai");
2
- const SystemLynxClient = require("../Client");
3
- const SystemLynxService = require("../../Service/Service");
4
- const Service = SystemLynxService();
2
+ const createClient = require("../Client");
3
+ const createService = require("../../Service/Service");
4
+ const Service = createService();
5
5
  const port = 6757;
6
6
  const route = "service-test";
7
7
  const url = `http://localhost:${port}/${route}`;
8
8
 
9
- describe("SystemLynxClient()", () => {
9
+ describe("createClient()", () => {
10
10
  it("should return a SystemLynx Client", () => {
11
- const Client = SystemLynxClient();
11
+ const Client = createClient();
12
12
  expect(Client)
13
13
  .to.be.an("object")
14
14
  .that.has.property("loadService")
@@ -36,13 +36,21 @@ describe("Client", () => {
36
36
  );
37
37
 
38
38
  await Service.startService({ route, port });
39
- const Client = SystemLynxClient();
39
+ const Client = createClient();
40
40
  const buAPI = await Client.loadService(url);
41
41
 
42
42
  expect(buAPI)
43
43
  .to.be.an("object")
44
- .that.has.all.keys("emit", "on", "resetConnection", "disconnect", "orders")
44
+ .that.has.all.keys(
45
+ "emit",
46
+ "on",
47
+ "$clearEvent",
48
+ "resetConnection",
49
+ "disconnect",
50
+ "orders"
51
+ )
45
52
  .that.respondsTo("emit")
53
+ .that.respondsTo("$clearEvent")
46
54
  .that.respondsTo("on")
47
55
  .that.respondsTo("resetConnection")
48
56
  .that.respondsTo("disconnect");
@@ -52,6 +60,7 @@ describe("Client", () => {
52
60
  .that.has.all.keys(
53
61
  "emit",
54
62
  "on",
63
+ "$clearEvent",
55
64
  "disconnect",
56
65
  "__setConnection",
57
66
  "__connectionData",
@@ -61,8 +70,10 @@ describe("Client", () => {
61
70
  "noArgTest"
62
71
  )
63
72
  .that.respondsTo("emit")
73
+ .that.respondsTo("$clearEvent")
64
74
  .that.respondsTo("on")
65
75
  .that.respondsTo("emit")
76
+ .that.respondsTo("$clearEvent")
66
77
  .that.respondsTo("__setConnection")
67
78
  .that.respondsTo("__connectionData")
68
79
  .that.respondsTo("action1")
@@ -74,7 +85,7 @@ describe("Client", () => {
74
85
 
75
86
  describe("Service", () => {
76
87
  it("should be able to call methods from the frontend client to the backend Module", async () => {
77
- const Client = SystemLynxClient();
88
+ const Client = createClient();
78
89
  const buAPI = await Client.loadService(url);
79
90
 
80
91
  const results = await buAPI.orders.action1({ code: 3 });
@@ -89,7 +100,7 @@ describe("Service", () => {
89
100
  });
90
101
  });
91
102
  it("should be able to send multiple arguments to the backend Module", async () => {
92
- const Client = SystemLynxClient();
103
+ const Client = createClient();
93
104
  const buAPI = await Client.loadService(url);
94
105
  const arg1 = 4,
95
106
  arg2 = 5,
@@ -107,7 +118,7 @@ describe("Service", () => {
107
118
  });
108
119
 
109
120
  it("should be able to send no arguments and use a promise", async () => {
110
- const Client = SystemLynxClient();
121
+ const Client = createClient();
111
122
  const buAPI = await Client.loadService(url);
112
123
  const results = await buAPI.orders.noArgTest();
113
124
 
@@ -122,13 +133,13 @@ describe("Service", () => {
122
133
  const route = "test-service";
123
134
  const port = "8980";
124
135
  const url = `http://localhost:${port}/${route}`;
125
- const Service = SystemLynxService();
136
+ const Service = createService();
126
137
  const eventTester = Service.module("eventTester", function () {
127
138
  this.sendEvent = () => this.emit(eventName, { testPassed: true });
128
139
  });
129
140
  await Service.startService({ route, port });
130
141
 
131
- const Client = SystemLynxClient();
142
+ const Client = createClient();
132
143
 
133
144
  const buAPI = await Client.loadService(url);
134
145
  setTimeout(() => eventTester.emit(eventName, { testPassed: true }), 500);
@@ -148,8 +159,8 @@ describe("Service", () => {
148
159
  });
149
160
 
150
161
  it("should be able to send REST http requests", async () => {
151
- const Client = SystemLynxClient();
152
- const Service = SystemLynxService();
162
+ const Client = createClient();
163
+ const Service = createService();
153
164
  const route = "rest-tester";
154
165
  const port = "8492";
155
166
  const url = `http://localhost:${port}/${route}`;
@@ -183,7 +194,7 @@ describe("Service", () => {
183
194
  });
184
195
 
185
196
  it("should be able to use 'useReturnValue' configuration option to enable synchronous return values from Module methods", async () => {
186
- const service = SystemLynxService();
197
+ const service = createService();
187
198
  const route = "sync/test";
188
199
  const port = 4920;
189
200
  const host = "localhost";
@@ -199,7 +210,7 @@ describe("Service", () => {
199
210
  port,
200
211
  host,
201
212
  });
202
- const Client = SystemLynxClient();
213
+ const Client = createClient();
203
214
  const { AsyncMath } = await Client.loadService(url);
204
215
  const results = await AsyncMath.max(10, 2);
205
216
  expect(results).to.equal(10);
@@ -1,6 +1,7 @@
1
1
  const { expect } = require("chai");
2
2
  const SocketDispatcher = require("../components/SocketDispatcher");
3
- const { WebSocket, SocketServer } = require("../../ServerManager/components/WebSocketServer")();
3
+ const { WebSocket, SocketServer } =
4
+ require("../../ServerManager/components/WebSocketServer")();
4
5
 
5
6
  const namespace = "test-namespace";
6
7
  const port = 4592;
@@ -14,9 +15,10 @@ describe("SocketDispatcher", () => {
14
15
  it("should return an EventDispatcher object with methods on and emit", async () => {
15
16
  expect(dispatcher)
16
17
  .to.be.an("object")
17
- .that.has.all.keys("on", "emit", "disconnect")
18
+ .that.has.all.keys("on", "emit", "$clearEvent", "disconnect")
18
19
  .that.respondsTo("on")
19
20
  .that.respondsTo("emit")
21
+ .that.respondsTo("$clearEvent")
20
22
  .that.respondsTo("disconnect");
21
23
  });
22
24
  it("Should be able to emit and handle events", (done) => {
@@ -25,19 +27,25 @@ describe("SocketDispatcher", () => {
25
27
  done();
26
28
  });
27
29
  dispatcher.on("connect", () => console.log(`I'm all the way connected!`));
28
- setTimeout(() => socket.emit("dispatch", { name: eventName, data: { testPassed: true } }), 500);
30
+ setTimeout(
31
+ () => socket.emit("dispatch", { name: eventName, data: { testPassed: true } }),
32
+ 500
33
+ );
29
34
  });
30
35
  });
31
36
 
32
37
  describe("SocketDispatcher.apply()", () => {
33
38
  const eventName = "testing-event";
34
- const dispatcher = SocketDispatcher.apply({}, [`http://localhost:${port}/${namespace}`]);
39
+ const dispatcher = SocketDispatcher.apply({}, [
40
+ `http://localhost:${port}/${namespace}`,
41
+ ]);
35
42
  it("should return an EventDispatcher object with methods on and emit", async () => {
36
43
  expect(dispatcher)
37
44
  .to.be.an("object")
38
- .that.has.all.keys("on", "emit", "disconnect")
45
+ .that.has.all.keys("on", "emit", "$clearEvent", "disconnect")
39
46
  .that.respondsTo("on")
40
47
  .that.respondsTo("emit")
48
+ .that.respondsTo("$clearEvent")
41
49
  .that.respondsTo("disconnect");
42
50
  });
43
51
  it("Should be able to emit and handle events", (done) => {
@@ -49,6 +57,9 @@ describe("SocketDispatcher.apply()", () => {
49
57
  done();
50
58
  });
51
59
 
52
- setTimeout(() => socket.emit("dispatch", { name: eventName, data: { testPassed: true } }), 500);
60
+ setTimeout(
61
+ () => socket.emit("dispatch", { name: eventName, data: { testPassed: true } }),
62
+ 500
63
+ );
53
64
  });
54
65
  });
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- module.exports = function SystemLynxDispatcher(events = {}, systemContext) {
2
+ module.exports = function createDispatcher(events = {}, systemContext) {
3
3
  const Dispatcher = this || {};
4
4
 
5
5
  Dispatcher.emit = (eventName, data, event) => {
@@ -24,5 +24,20 @@ module.exports = function SystemLynxDispatcher(events = {}, systemContext) {
24
24
  return Dispatcher;
25
25
  };
26
26
 
27
+ Dispatcher.$clearEvent = (eventName, fn) => {
28
+ if (!events[eventName]) return Dispatcher;
29
+
30
+ if (!fn) {
31
+ // Clear all listeners for the given event
32
+ delete events[eventName];
33
+ } else {
34
+ // Remove the listener function with the specified name from the event's listener array
35
+ events[eventName] = events[eventName].filter((callback) => {
36
+ return callback.name !== fn;
37
+ });
38
+ }
39
+
40
+ return Dispatcher;
41
+ };
27
42
  return Dispatcher;
28
43
  };
@@ -1,14 +1,15 @@
1
1
  const { expect } = require("chai");
2
2
  const Dispatcher = require("./Dispatcher");
3
3
 
4
- describe("SystemLynxDispatcher", () => {
4
+ describe("createDispatcher", () => {
5
5
  const dispatcher = Dispatcher();
6
6
  it("should return an EventDispatcher object with methods on and emit", async () => {
7
7
  expect(dispatcher)
8
8
  .to.be.an("object")
9
- .that.has.all.keys("on", "emit")
9
+ .that.has.all.keys("on", "emit", "$clearEvent")
10
10
  .that.respondsTo("on")
11
- .that.respondsTo("emit");
11
+ .that.respondsTo("emit")
12
+ .that.respondsTo("$clearEvent");
12
13
  });
13
14
  it("Should be able to emit and handle events", (done) => {
14
15
  dispatcher.on("test", (data) => {
@@ -2,7 +2,7 @@
2
2
  const httpClient = require("request");
3
3
  const json = true;
4
4
 
5
- module.exports = function SystemLynxClient() {
5
+ module.exports = function createClient() {
6
6
  const Client = this || {};
7
7
  Client.request = ({ method, url, body }, cb) => {
8
8
  const tryRequest = (callback) => {
@@ -1,6 +1,6 @@
1
1
  const { expect } = require("chai");
2
2
  const LoadBalancer = require("../LoadBalancer")();
3
- const SystemLynxService = require("../../Service/Service");
3
+ const createService = require("../../Service/Service");
4
4
  const HttpClient = require("../../HttpClient/HttpClient")();
5
5
  const lbPort = 5030;
6
6
  const route = "loadbalancer";
@@ -9,14 +9,33 @@ describe("LoadBalancer()", () => {
9
9
  it("should return a SystemLynx LoadBalancer", () => {
10
10
  expect(LoadBalancer)
11
11
  .to.be.an("object")
12
- .that.has.all.keys("startService", "server", "WebSocket", "module", "clones")
12
+ .that.has.all.keys(
13
+ "startService",
14
+ "server",
15
+ "WebSocket",
16
+ "module",
17
+ "clones",
18
+ "before"
19
+ )
13
20
  .that.respondsTo("startService")
14
- .that.respondsTo("module");
21
+ .that.respondsTo("module")
22
+ .that.respondsTo("before");
15
23
  expect(LoadBalancer.clones)
16
24
  .to.be.an("object")
17
- .that.has.all.keys("on", "emit", "clones", "register", "dispatch", "assignDispatch")
25
+ .that.has.all.keys(
26
+ "on",
27
+ "emit",
28
+ "$clearEvent",
29
+ "before",
30
+ "clones",
31
+ "register",
32
+ "dispatch",
33
+ "assignDispatch"
34
+ )
18
35
  .that.respondsTo("emit")
36
+ .that.respondsTo("$clearEvent")
19
37
  .that.respondsTo("on")
38
+ .that.respondsTo("before")
20
39
  .that.respondsTo("register")
21
40
  .that.respondsTo("dispatch")
22
41
  .that.respondsTo("assignDispatch")
@@ -71,6 +90,8 @@ describe("LoadBalancer.clones (Module)", () => {
71
90
  "on",
72
91
  "emit",
73
92
  "$emit",
93
+ "$clearEvent",
94
+ "before",
74
95
  "register",
75
96
  "dispatch",
76
97
  "assignDispatch",
@@ -78,6 +99,8 @@ describe("LoadBalancer.clones (Module)", () => {
78
99
  )
79
100
  .that.respondsTo("on")
80
101
  .that.respondsTo("emit")
102
+ .that.respondsTo("$clearEvent")
103
+ .that.respondsTo("before")
81
104
  .that.respondsTo("$emit")
82
105
  .that.respondsTo("register")
83
106
  .that.respondsTo("dispatch")
@@ -87,7 +110,7 @@ describe("LoadBalancer.clones (Module)", () => {
87
110
  });
88
111
 
89
112
  it("should be able to use clones.register(connData, callback) method to host connection", async () => {
90
- const Service = SystemLynxService();
113
+ const Service = createService();
91
114
  const { route, port, host } = test_service1;
92
115
  await Service.startService({ route, port, host });
93
116
  LoadBalancer.clones.register({ route, port, host }, () => {});
@@ -113,8 +136,8 @@ describe("LoadBalancer.clones (Module)", () => {
113
136
 
114
137
  it("should be able to manager the routing to multiple clones of the same Service", async () => {
115
138
  const { route, port1, port2, host } = test_service2;
116
- const Clone1 = SystemLynxService();
117
- const Clone2 = SystemLynxService();
139
+ const Clone1 = createService();
140
+ const Clone2 = createService();
118
141
  await Clone1.startService({ route, port: port1, host });
119
142
  await Clone2.startService({ route, port: port2, host });
120
143
  LoadBalancer.clones.register({ route, port: port1, host }, () => {});
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
- const SystemLynxServer = require("./components/Server");
3
- const SystemLynxRouter = require("./components/Router");
2
+ const createServer = require("./components/Server");
3
+ const createRouter = require("./components/Router");
4
4
  const SocketEmitter = require("./components/SocketEmitter");
5
- const SystemLynxWebSocket = require("./components/WebSocketServer");
5
+ const createWebSocket = require("./components/WebSocketServer");
6
6
  const parseMethods = require("./components/parseMethods");
7
7
  const shortId = require("shortid");
8
+ const randomPort = () => parseInt(Math.random() * parseInt(Math.random() * 10000)) + 1023;
9
+ const createSSLServer = (app, options) => {
10
+ const https = require("https");
11
+ return https.createServer(options, app);
12
+ };
8
13
 
9
- module.exports = function SystemLynxServerManager() {
14
+ module.exports = function createServerManager(customServer, customWebSocketServer) {
10
15
  let serverConfigurations = {
11
16
  route: null,
12
17
  port: null,
@@ -16,21 +21,27 @@ module.exports = function SystemLynxServerManager() {
16
21
  useREST: false,
17
22
  useService: true,
18
23
  staticRouting: false,
19
- middleware: [],
24
+ ssl: { key: "", cert: "" },
25
+ validators: { $all: [] },
20
26
  };
21
- const server = SystemLynxServer();
22
- const router = SystemLynxRouter(server, () => serverConfigurations);
23
- const { SocketServer, WebSocket } = SystemLynxWebSocket();
27
+ const server = createServer(customServer);
28
+ const router = createRouter(server, () => serverConfigurations);
29
+ const { SocketServer, WebSocket } = createWebSocket(customWebSocketServer);
24
30
  const moduleQueue = [];
25
31
  const modules = [];
26
32
 
27
33
  const ServerManager = { server, WebSocket };
28
34
 
29
35
  ServerManager.startService = (options) => {
30
- let { route, host = "localhost", port, socketPort, staticRouting } = options;
36
+ let {
37
+ route,
38
+ host = "localhost",
39
+ port,
40
+ socketPort = randomPort(),
41
+ staticRouting,
42
+ ssl,
43
+ } = options;
31
44
 
32
- socketPort =
33
- socketPort || parseInt(Math.random() * parseInt(Math.random() * 10000)) + 1023;
34
45
  const namespace = staticRouting ? route : shortId();
35
46
  SocketServer.listen(socketPort);
36
47
  SocketEmitter.apply(ServerManager, [namespace, WebSocket]);
@@ -38,7 +49,8 @@ module.exports = function SystemLynxServerManager() {
38
49
  route = route.charAt(0) === "/" ? route.substr(1) : route;
39
50
  route =
40
51
  route.charAt(route.length - 1) === "/" ? route.substr(route.length - 1) : route;
41
- const serviceUrl = `http://${host}:${port}/${route}`;
52
+ const protocol = ssl ? "https" : "http";
53
+ const serviceUrl = `${protocol}://${host}:${port}/${route}`;
42
54
 
43
55
  serverConfigurations = {
44
56
  ...serverConfigurations,
@@ -57,46 +69,44 @@ module.exports = function SystemLynxServerManager() {
57
69
  SystemLynxService: true,
58
70
  };
59
71
 
60
- const selectModules = (moduleList) =>
61
- moduleList.reduce(
62
- (sum, moduleName) =>
63
- sum.concat(modules.find(({ name }) => name === moduleName) || []),
64
- []
65
- );
66
-
67
72
  server.get(`/${route}`, (req, res) => {
68
73
  //The route will return connection data for the service including an array of
69
74
  //modules (objects) which contain instructions on how to make request to each object
70
- const { query } = req;
71
-
72
- res.json({
73
- ...connectionData,
74
- modules: query.modules ? selectModules(query.modules.split(",")) : modules,
75
- });
75
+ res.json({ ...connectionData, modules });
76
76
  });
77
77
 
78
- return new Promise((resolve) =>
79
- server.listen(port, () => {
78
+ return new Promise((resolve) => {
79
+ const _server = ssl ? createSSLServer(server, ssl) : server;
80
+ _server.listen(port, () => {
80
81
  console.log(`[SystemLynx][Service]: Listening on ${serviceUrl}`);
81
82
  moduleQueue.forEach(({ name, Module, reserved_methods }) =>
82
83
  ServerManager.addModule(name, Module, reserved_methods)
83
84
  );
84
85
  moduleQueue.length = 0;
85
86
  resolve(connectionData);
86
- })
87
- );
87
+ });
88
+ });
88
89
  };
89
90
 
90
91
  ServerManager.addModule = (name, Module, reserved_methods = []) => {
91
- const { host, route, serviceUrl, staticRouting, useService, useREST, socketPort } =
92
- serverConfigurations;
92
+ const {
93
+ host,
94
+ route,
95
+ serviceUrl,
96
+ staticRouting,
97
+ useService,
98
+ useREST,
99
+ socketPort,
100
+ validators,
101
+ } = serverConfigurations;
93
102
 
94
103
  if (!serviceUrl) return moduleQueue.push({ name, Module, reserved_methods });
95
- const methods = parseMethods(Module, ["on", "emit", ...reserved_methods], useREST);
104
+ const exclude_methods = ["on", "emit", "before", "$clearEvent", ...reserved_methods];
105
+ const methods = parseMethods(Module, exclude_methods, useREST);
96
106
  const namespace = staticRouting ? name : shortId();
97
107
 
98
108
  SocketEmitter.apply(Module, [namespace, WebSocket]);
99
-
109
+ const _validators = [...validators.$all, ...(validators[name] || [])];
100
110
  if (useService) {
101
111
  const path = staticRouting ? `${route}/${name}` : `${shortId()}/${shortId()}`;
102
112
 
@@ -106,19 +116,48 @@ module.exports = function SystemLynxServerManager() {
106
116
  name,
107
117
  methods,
108
118
  });
109
- methods.forEach((method) => router.addService(Module, path, method, name));
119
+ methods.forEach((method) => {
120
+ const nsp = `${name}.${method.fn}`;
121
+ const customValidators = [..._validators, ...(validators[nsp] || [])];
122
+ router.addService(Module, path, method, name, customValidators);
123
+ });
110
124
  }
111
125
  if (useREST)
112
126
  methods.forEach((method) => {
127
+ const nsp = `${name}.${method.fn}`;
128
+ const customValidators = [..._validators, ...(validators[nsp] || [])];
113
129
  switch (method.fn) {
114
130
  case "get":
115
131
  case "put":
116
132
  case "post":
117
133
  case "delete":
118
- router.addREST(Module, `${route}/${name}`, method, name);
134
+ router.addREST(Module, `${route}/${name}`, method, name, customValidators);
119
135
  }
120
136
  });
121
137
  };
122
-
138
+ ServerManager.addRouteHandler = (...args) => {
139
+ const name = typeof args[0] === "string" ? args.shift() : "$all";
140
+ args.forEach(async (middleware) => {
141
+ if (!serverConfigurations.validators[name])
142
+ serverConfigurations.validators[name] = [];
143
+ serverConfigurations.validators[name].push(async function (req, res, next) {
144
+ try {
145
+ await middleware(req, res, next);
146
+ } catch (error) {
147
+ res.sendError(error);
148
+ }
149
+ });
150
+ });
151
+ };
123
152
  return ServerManager;
124
153
  };
154
+
155
+ //creating an ssl setup with openssl cli
156
+ //1. `openssl genrsa -out key.pem` to generate a private key
157
+ //2. create a certificate signing request using the key we just generated
158
+ // `openssl req -new -key key.pem -out csr.pem`
159
+ //3. Answer the prompts in the terminal
160
+ //4. use the newly generate csr to generate a ssl certificate
161
+ // openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out cert.pem
162
+ //(x509 is the standard to use for the certificate, days are the number of day the cert is valid)
163
+ //5. csr.pem is no longer needed