zyket 1.0.13 → 1.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/index.js CHANGED
@@ -1,12 +1,14 @@
1
1
  const Kernel = require("./src/kernel");
2
2
  const Service = require("./src/services/Service");
3
- const { Handler, Middleware } = require("./src/services/socketio");
4
3
  const EnvManager = require("./src/utils/EnvManager");
5
4
 
5
+ const {Route, Middleware} = require("./src/services/express");
6
+ const { Handler, Guard } = require("./src/services/socketio");
7
+
8
+
6
9
  module.exports = {
7
- Kernel,
8
- Service,
9
- Handler,
10
- Middleware,
10
+ Kernel, Service,
11
+ Route, Middleware,
12
+ Handler, Guard,
11
13
  EnvManager
12
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zyket",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -1,6 +1,11 @@
1
1
  const Service = require("../Service");
2
2
  const express = require("express");
3
3
  const cors = require("cors");
4
+ const Route = require("./Route");
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const fg = require('fast-glob');
8
+ const Middleware = require("./Middleware");
4
9
 
5
10
 
6
11
  module.exports = class Express extends Service {
@@ -26,8 +31,69 @@ module.exports = class Express extends Service {
26
31
  origin: '*'
27
32
  }))
28
33
 
34
+ const routes = await this.#loadRoutesFromFolder(path.join(process.cwd(), "src", "routes"));
35
+
36
+ routes.forEach((route) => {
37
+ const { post, get } = route;
38
+ for (const method of [post, get]) {
39
+ if(!method) continue;
40
+ const methodName = method === post ? 'post' : 'get';
41
+ this.#container.get('logger').debug(`Registering route: [${methodName}] ${route.path}`);
42
+ const middlewares = route?.middlewares?.[methodName] || [];
43
+ for (const mw of middlewares) {
44
+ // mw is instance of Middleware
45
+ if (!(mw instanceof Middleware)) {
46
+ throw new Error(`Middleware for route ${route.path} is not an instance of Middleware`);
47
+ }
48
+ }
49
+
50
+ this.#app[methodName](
51
+ route.path,
52
+ ...middlewares.map(mw => (req, res, next) => mw.handle({ container: this.#container, request: req, response: res, next })),
53
+ async (req, res) => {
54
+ try {
55
+ const routeResponse = await route[methodName]({ container: this.#container, request: req, response: res });
56
+ const status = routeResponse?.status || 200;
57
+ return res.status(status).json({
58
+ ...routeResponse,
59
+ success: routeResponse?.success !== false,
60
+ });
61
+ } catch (error) {
62
+ this.#container.get('logger').error(`Error in route [${methodName}] ${route.path}: ${error.message}`);
63
+ return res.status(500).json({ success: false, message: error.message || 'Internal Server Error' });
64
+ }
65
+ });
66
+ }
67
+ });
68
+
29
69
  this.#httpServer.on("request", this.#app);
30
70
 
31
71
  this.#container.get('logger').info(`Express is running on http://localhost:${httpServer.address().port}`);
32
72
  }
73
+
74
+ async #loadRoutesFromFolder(routesFolder) {
75
+ this.#createRoutesFolder(routesFolder);
76
+ const routes = (await fg('**/*.js', { cwd: routesFolder })).map((rt) => {
77
+ const route = require(path.join(routesFolder, rt));
78
+ if(!(route.prototype instanceof Route)) throw new Error(`${rt} is not a valid route`);
79
+ let routePath = `/${rt.replace('.js', '')}`;
80
+ routePath = routePath.replaceAll('index', '/');
81
+ routePath = routePath.replaceAll('//', '/');
82
+ routePath = routePath.replace(/\[([^\]]+)\]/g, ':$1');
83
+
84
+ return new route(routePath);
85
+ });
86
+ return routes;
87
+ }
88
+
89
+ #createRoutesFolder(routesFolder, overwrite = false) {
90
+ if (fs.existsSync(routesFolder) && !overwrite) return;
91
+ this.#container.get('logger').info(`Creating routes folder at ${routesFolder}`);
92
+ fs.mkdirSync(routesFolder);
93
+ this.#container.get('template-manager').installFile('default/src/routes/index', path.join(routesFolder, "index.js"));
94
+ fs.mkdirSync(path.join(routesFolder, "[test]"));
95
+ this.#container.get('template-manager').installFile('default/src/routes/[test]/message', path.join(routesFolder, "[test]", "message.js"));
96
+ fs.mkdirSync(path.join(process.cwd(), "src", "middlewares"));
97
+ this.#container.get('template-manager').installFile('default/src/middlewares/default', path.join(process.cwd(), "src", "middlewares", "default.js"));
98
+ }
33
99
  }
@@ -1,2 +1,8 @@
1
- export default class Middleware {
1
+ module.exports = class Middleware {
2
+ constructor() {
3
+ }
4
+
5
+ handle({ container, request, response, next }) {
6
+ throw new Error("You should implement 'handle()' method on your route");
7
+ }
2
8
  }
@@ -1,2 +1,7 @@
1
- export default class Route {
1
+ module.exports = class Route {
2
+ path;
3
+
4
+ constructor(_path) {
5
+ this.path = _path;
6
+ }
2
7
  }
@@ -1,3 +1,5 @@
1
1
  module.exports = {
2
2
  Express: require("./Express"),
3
+ Route: require("./Route"),
4
+ Middleware: require("./Middleware"),
3
5
  }
@@ -10,6 +10,6 @@ module.exports = [
10
10
  process.env.DATABASE_URL ? ["database", Database, ["@service_container", process.env.DATABASE_URL]] : null,
11
11
  process.env.CACHE_URL ? ["cache", Cache, ["@service_container", process.env.CACHE_URL]] : null,
12
12
  (process.env.S3_ENDPOINT && process.env.S3_ACCESS_KEY && process.env.S3_SECRET_KEY) ? ["s3", S3, ["@service_container", process.env.S3_ENDPOINT, process.env.S3_PORT, process.env.S3_USE_SSL === "true", process.env.S3_ACCESS_KEY, process.env.S3_SECRET_KEY]] : null,
13
- ["socketio", SocketIO, ["@service_container"]],
14
- ["express", Express, ["@service_container"]]
13
+ process.env.DISABLE_SOCKET !== 'true' ? ["socketio", SocketIO, ["@service_container"]] : null,
14
+ process.env.DISABLE_EXPRESS !== 'true' ? ["express", Express, ["@service_container"]] : null
15
15
  ].filter(Boolean);
@@ -1,4 +1,4 @@
1
- module.exports = class Middleware {
1
+ module.exports = class Guard {
2
2
  name;
3
3
 
4
4
  constructor(name) {
@@ -4,13 +4,13 @@ const fs = require("fs");
4
4
  const path = require("path");
5
5
  const fg = require('fast-glob');
6
6
  const Handler = require("./Handler");
7
- const Middleware = require("./Middleware");
7
+ const Guard = require("./Guard");
8
8
 
9
9
 
10
10
  module.exports = class SocketIO extends Service {
11
11
  #container;
12
12
  io;
13
- middlewares = {};
13
+ guards = {};
14
14
 
15
15
  constructor(container) {
16
16
  super("socketio");
@@ -18,39 +18,39 @@ module.exports = class SocketIO extends Service {
18
18
  }
19
19
 
20
20
  async boot({ httpServer } = {}) {
21
- const middlewares = await this.#loadMiddlewaresFromFolder(path.join(process.cwd(), "src", "middlewares"));
22
- for (const middleware of middlewares) {
23
- this.middlewares[middleware.name] = middleware;
21
+ const guards = await this.#loadGuardsFromFolder(path.join(process.cwd(), "src", "guards"));
22
+ for (const guard of guards) {
23
+ this.guards[guard.name] = guard;
24
24
  }
25
25
  const handlers = await this.#loadHandlersFromFolder(path.join(process.cwd(), "src", "handlers"));
26
26
  const connectionHandler = new (await this.#loadConnectionHandler())();
27
27
 
28
28
 
29
- this.#container.get('logger').debug(`Middlewares: ${middlewares.map(mdl => mdl.name).join(", ")}`);
29
+ this.#container.get('logger').debug(`Guards: ${guards.map(mdl => mdl.name).join(", ")}`);
30
30
  this.#container.get('logger').debug(`Handlers: ${handlers.map(hdl => hdl.event).join(", ")}`);
31
31
 
32
32
  this.io = new Server({ cors: { origin: "*" }, maxHttpBufferSize: 10 * 1024 * 1024 });
33
33
 
34
34
  this.io.on("connection", (socket) => {
35
- const connectionMiddlewares = (connectionHandler?.middlewares || []).map(mdl => this.middlewares[mdl])
36
- for (const middleware of connectionMiddlewares) {
37
- if(!middleware) {
38
- this.#container.get('logger').warn(`You are using a middleware that does not exist`);
35
+ const connectionGuards = (connectionHandler?.guards || []).map(mdl => this.guards[mdl])
36
+ for (const guard of connectionGuards) {
37
+ if(!guard) {
38
+ this.#container.get('logger').warn(`You are using a guard that does not exist`);
39
39
  continue;
40
40
  }
41
- middleware.handle({ container: this.#container, socket, io: this.io });
41
+ guard.handle({ container: this.#container, socket, io: this.io });
42
42
  }
43
43
  connectionHandler.handle({ container: this.#container, socket, io: this.io });
44
44
  handlers.forEach((handler) => {
45
- const handlerMiddlewares = (handler?.middlewares || []).map(mdl => this.middlewares[mdl])
45
+ const handlerGuards = (handler?.guards || []).map(mdl => this.guards[mdl])
46
46
  socket.on(handler.event, async (data) => {
47
- this.#container.get('logger').debug(`[${socket?.id}] Sent ${handler.event} with middlewares: ${handlerMiddlewares?.map(mdl => mdl?.name).join(", ")}`);
48
- for (const middleware of handlerMiddlewares) {
49
- if(!middleware) {
50
- this.#container.get('logger').warn(`You are using a middleware that does not exist`);
47
+ this.#container.get('logger').debug(`[${socket?.id}] Sent ${handler.event} with guards: ${handlerGuards?.map(mdl => mdl?.name).join(", ")}`);
48
+ for (const guard of handlerGuards) {
49
+ if(!guard) {
50
+ this.#container.get('logger').warn(`You are using a guard that does not exist`);
51
51
  continue;
52
52
  }
53
- await middleware.handle({ container: this.#container, socket, io: this.io });
53
+ await guard.handle({ container: this.#container, socket, io: this.io });
54
54
  }
55
55
  return await handler.handle({ container: this.#container, socket, data, io: this.io });
56
56
  });
@@ -71,9 +71,7 @@ module.exports = class SocketIO extends Service {
71
71
 
72
72
  async #loadHandlersFromFolder(handlersFolder) {
73
73
  this.#createHandlersFolder(handlersFolder);
74
- // need to read all files and subfolders
75
74
  const handlers = (await fg('**/*.js', { cwd: handlersFolder, ignore: 'connection.js' })).map((hdr) => {
76
- // should be type handler
77
75
  const handler = require(path.join(handlersFolder, hdr));
78
76
  if(!(handler.prototype instanceof Handler)) throw new Error(`${hdr} is not a valid handler`);
79
77
  return new handler(hdr.replace('.js', ''));
@@ -88,24 +86,22 @@ module.exports = class SocketIO extends Service {
88
86
  this.#container.get('template-manager').installFile('default/src/handlers/message', path.join(handlersFolder, "message.js"));
89
87
  }
90
88
 
91
- async #loadMiddlewaresFromFolder(middlewaresFolder) {
92
- this.#createMiddlewaresFolder(middlewaresFolder);
93
- // need to read all files and subfolders
94
- const middlewares = await fg('**/*.js', { cwd: middlewaresFolder })
89
+ async #loadGuardsFromFolder(guardsFolder) {
90
+ this.#createGuardsFolder(guardsFolder);
91
+ const guards = await fg('**/*.js', { cwd: guardsFolder })
95
92
 
96
- return middlewares.map((mdl) => {
97
- // should be type middleware
98
- const middleware = require(path.join(middlewaresFolder, mdl));
99
- if(!(middleware.prototype instanceof Middleware)) throw new Error(`${mdl} is not a valid middleware`);
100
- return new middleware(mdl.replace('.js', ''));
93
+ return guards.map((gd) => {
94
+ const guard = require(path.join(guardsFolder, gd));
95
+ if(!(guard.prototype instanceof Guard)) throw new Error(`${gd} is not a valid guard`);
96
+ return new guard(gd.replace('.js', ''));
101
97
  });
102
98
  }
103
99
 
104
- #createMiddlewaresFolder(middlewaresFolder, overwrite = false) {
105
- if (fs.existsSync(middlewaresFolder) && !overwrite) return;
106
- this.#container.get('logger').info(`Creating middlewares folder at ${middlewaresFolder}`);
107
- fs.mkdirSync(middlewaresFolder);
108
- this.#container.get('template-manager').installFile('default/src/middlewares/default', path.join(middlewaresFolder, "default.js"));
100
+ #createGuardsFolder(guardsFolder, overwrite = false) {
101
+ if (fs.existsSync(guardsFolder) && !overwrite) return;
102
+ this.#container.get('logger').info(`Creating guards folder at ${guardsFolder}`);
103
+ fs.mkdirSync(guardsFolder);
104
+ this.#container.get('template-manager').installFile('default/src/guards/default', path.join(guardsFolder, "default.js"));
109
105
  }
110
106
 
111
107
  stop() {
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
2
  SocketIO: require("./SocketIO"),
3
3
  Handler: require("./Handler"),
4
- Middleware: require("./Middleware")
4
+ Guard: require("./Guard")
5
5
  }
@@ -0,0 +1,7 @@
1
+ const { Guard } = require("zyket");
2
+
3
+ module.exports = class DefaultGuard extends Guard {
4
+ async handle({ container, socket, io }) {
5
+ container.get("logger").info("Default guard");
6
+ }
7
+ };
@@ -1,7 +1,7 @@
1
1
  const { Handler } = require("zyket");
2
2
 
3
3
  module.exports = class MessageHandler extends Handler {
4
- middlewares = ["default"];
4
+ guards = ["default"];
5
5
 
6
6
  async handle({ container, socket, data, io }) {
7
7
  container.get("logger").info("Message handler");
@@ -1,6 +1,8 @@
1
1
  const { Middleware } = require("zyket");
2
+
2
3
  module.exports = class DefaultMiddleware extends Middleware {
3
- async handle({ container, socket, io }) {
4
+ async handle({ container, request, response, next }) {
4
5
  container.get("logger").info("Default middleware");
6
+ next();
5
7
  }
6
8
  };
@@ -0,0 +1,21 @@
1
+ const { Route } = require("zyket");
2
+
3
+ module.exports = class DefaultRoute extends Route {
4
+ async post({ container, request }) {
5
+ const { test } = request.params;
6
+ container.get("logger").info("Default route GET");
7
+
8
+ return {
9
+ test: "Hello World GET! Param: " + test
10
+ }
11
+ }
12
+
13
+ async get({ container, request }) {
14
+ const { test } = request.params;
15
+ container.get("logger").info("Default route GET");
16
+
17
+ return {
18
+ test: "Hello World GET! Param: " + test
19
+ }
20
+ }
21
+ };
@@ -0,0 +1,23 @@
1
+ const { Route } = require("zyket");
2
+ const DefaultMiddleware = require("../middlewares/default");
3
+
4
+ module.exports = class DefaultRoute extends Route {
5
+ middlewares = {
6
+ post: [ new DefaultMiddleware() ],
7
+ get: [ new DefaultMiddleware() ]
8
+ }
9
+
10
+ async post({ container, request }) {
11
+ container.get("logger").info("Default route POST");
12
+ return {
13
+ test: "Hello World POST!"
14
+ }
15
+ }
16
+
17
+ async get({ container, request }) {
18
+ container.get("logger").info("Default route GET");
19
+ return {
20
+ test: "Hello World GET!"
21
+ }
22
+ }
23
+ };
@@ -15,6 +15,8 @@ module.exports = class EnvManager {
15
15
  const envsToCreate = {
16
16
  DEBUG: true,
17
17
  PORT: 3000,
18
+ DISABLE_SOCKET: false,
19
+ DISABLE_EXPRESS: false,
18
20
  DATABASE_URL: '',
19
21
  CACHE_URL: '',
20
22
  S3_ENDPOINT: '',