zyket 1.2.12 → 1.2.13
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/package.json
CHANGED
|
@@ -94,6 +94,10 @@ module.exports = class Express extends Service {
|
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
+
// In production, serve the built Vite frontend (static assets + SPA fallback).
|
|
98
|
+
// Registered after API routes so the API keeps precedence.
|
|
99
|
+
this.#serveFrontend();
|
|
100
|
+
|
|
97
101
|
// Attach Express to HTTP server - this allows dynamic route registration
|
|
98
102
|
this.#httpServer.removeAllListeners("request");
|
|
99
103
|
this.#httpServer.on("request", this.#app);
|
|
@@ -101,6 +105,34 @@ module.exports = class Express extends Service {
|
|
|
101
105
|
this.#container.get('logger').info(`Express is running on http://localhost:${httpServer.address().port}`);
|
|
102
106
|
}
|
|
103
107
|
|
|
108
|
+
#serveFrontend() {
|
|
109
|
+
const viteEnabled = process.env.VITE_ROOT && process.env.DISABLE_VITE !== 'true';
|
|
110
|
+
if (process.env.NODE_ENV !== 'production' || !viteEnabled) return;
|
|
111
|
+
|
|
112
|
+
const vite = this.#container.has('vite') ? this.#container.get('vite') : null;
|
|
113
|
+
const distPath = vite?.outDir?.()
|
|
114
|
+
|| path.resolve(process.cwd(), process.env.VITE_ROOT || 'frontend', 'dist');
|
|
115
|
+
const indexHtml = path.join(distPath, 'index.html');
|
|
116
|
+
|
|
117
|
+
if (!fs.existsSync(indexHtml)) {
|
|
118
|
+
this.#container.get('logger').warn(`Frontend build not found at ${distPath}. Skipping static serving.`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this.#app.use(express.static(distPath));
|
|
123
|
+
|
|
124
|
+
// SPA fallback: serve index.html for any GET not handled by API routes,
|
|
125
|
+
// except the Swagger docs path. Uses middleware (Express 5 dropped bare '*').
|
|
126
|
+
const docsPath = process.env.SWAGGER_PATH || '/docs';
|
|
127
|
+
this.#app.use((req, res, next) => {
|
|
128
|
+
if (req.method !== 'GET') return next();
|
|
129
|
+
if (req.path.startsWith(docsPath)) return next();
|
|
130
|
+
res.sendFile(indexHtml);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
this.#container.get('logger').info(`Serving frontend from ${distPath}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
104
136
|
async registerRoutes(routes) {
|
|
105
137
|
const methods = ['post', 'get', 'put', 'delete']
|
|
106
138
|
for (const route of routes) {
|
package/src/services/index.js
CHANGED
|
@@ -14,9 +14,10 @@ const schedulerActivated = process.env.DISABLE_SCHEDULER !== 'true';
|
|
|
14
14
|
const socketActivated = process.env.DISABLE_SOCKET !== 'true';
|
|
15
15
|
const expressActivated = process.env.DISABLE_EXPRESS !== 'true';
|
|
16
16
|
const viteActivated = process.env.VITE_ROOT && process.env.DISABLE_VITE !== 'true';
|
|
17
|
+
const loggerActivated = process.env.DISABLE_LOGGER !== 'true';
|
|
17
18
|
|
|
18
19
|
module.exports = [
|
|
19
|
-
["logger", require("./logger"), ["@service_container", process.env.LOG_DIRECTORY || `${process.cwd()}/logs`, process.env.DEBUG === "true"]],
|
|
20
|
+
["logger", require("./logger"), ["@service_container", process.env.LOG_DIRECTORY || `${process.cwd()}/logs`, process.env.DEBUG === "true", !loggerActivated]],
|
|
20
21
|
["template-manager", require("./template-manager"), []],
|
|
21
22
|
eventsActivated ? ["events", EventService, ["@service_container"]] : null,
|
|
22
23
|
databaseActivated ? ["database", Database, ["@service_container", process.env.DATABASE_URL]] : null,
|
|
@@ -25,6 +26,6 @@ module.exports = [
|
|
|
25
26
|
schedulerActivated ? ["scheduler", Scheduler, ["@service_container"]] : null,
|
|
26
27
|
bullmqActivated ? ["bullmq", require("./bullmq"), ["@service_container"]] : null,
|
|
27
28
|
socketActivated ? ["socketio", SocketIO, ["@service_container"]] : null,
|
|
28
|
-
expressActivated ? ["express", Express, ["@service_container"]] : null,
|
|
29
29
|
viteActivated ? ["vite", require("./vite"), ["@service_container", process.env.VITE_ROOT, Number(process.env.VITE_PORT) || 5173]] : null,
|
|
30
|
+
expressActivated ? ["express", Express, ["@service_container"]] : null,
|
|
30
31
|
].filter(Boolean);
|
|
@@ -6,6 +6,7 @@ module.exports = class Logger extends Service {
|
|
|
6
6
|
#container
|
|
7
7
|
#logDirectory;
|
|
8
8
|
#debugEnabled;
|
|
9
|
+
#disabled;
|
|
9
10
|
messageColors = {
|
|
10
11
|
log: "white",
|
|
11
12
|
info: "green",
|
|
@@ -15,19 +16,22 @@ module.exports = class Logger extends Service {
|
|
|
15
16
|
};
|
|
16
17
|
#storeTries = 0;
|
|
17
18
|
|
|
18
|
-
constructor(container, logDirectory, debugEnabled) {
|
|
19
|
+
constructor(container, logDirectory, debugEnabled, disabled = false) {
|
|
19
20
|
super("logger");
|
|
20
21
|
this.#container = container;
|
|
21
22
|
this.#logDirectory = logDirectory;
|
|
22
23
|
this.#debugEnabled = debugEnabled;
|
|
24
|
+
this.#disabled = disabled;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
async boot() {
|
|
28
|
+
if (this.#disabled) return this;
|
|
26
29
|
if (!fs.existsSync(this.#logDirectory)) fs.mkdirSync(this.#logDirectory);
|
|
27
30
|
return this;
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
async store(message) {
|
|
34
|
+
if (this.#disabled) return;
|
|
31
35
|
if (this.#storeTries > 10) throw new Error("Failed to store log message");
|
|
32
36
|
this.#storeTries++;
|
|
33
37
|
try{
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Builds the Vite frontend for production using Vite's JS API.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} options
|
|
7
|
+
* @param {string} options.root Absolute path to the Vite project root.
|
|
8
|
+
* @param {string|false} options.configFile Resolved vite config file, or false.
|
|
9
|
+
* @returns {Promise<string>} Absolute path to the generated output directory.
|
|
10
|
+
*/
|
|
11
|
+
module.exports = async function buildViteApp({ root, configFile } = {}) {
|
|
12
|
+
const { build, resolveConfig } = await import("vite");
|
|
13
|
+
|
|
14
|
+
// Resolve config first so we know the real outDir (respects custom config).
|
|
15
|
+
const resolved = await resolveConfig(
|
|
16
|
+
{ root, configFile },
|
|
17
|
+
"build",
|
|
18
|
+
"production"
|
|
19
|
+
);
|
|
20
|
+
const outDir = path.resolve(root, resolved.build.outDir);
|
|
21
|
+
|
|
22
|
+
await build({
|
|
23
|
+
root,
|
|
24
|
+
configFile,
|
|
25
|
+
logLevel: "warn",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return outDir;
|
|
29
|
+
};
|
|
@@ -2,26 +2,40 @@ const Service = require("../Service");
|
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const EnvManager = require("../../utils/EnvManager");
|
|
5
|
+
const buildViteApp = require("./builder");
|
|
5
6
|
|
|
6
7
|
module.exports = class Vite extends Service {
|
|
7
8
|
#container;
|
|
8
9
|
#viteServer;
|
|
9
10
|
#root;
|
|
10
11
|
#port;
|
|
12
|
+
#isProduction;
|
|
13
|
+
#outDir;
|
|
11
14
|
|
|
12
15
|
constructor(container, root, port) {
|
|
13
16
|
super("vite");
|
|
14
17
|
this.#container = container;
|
|
15
18
|
this.#root = path.resolve(process.cwd(), root || process.cwd());
|
|
16
19
|
this.#port = port || 5173;
|
|
20
|
+
this.#isProduction = process.env.NODE_ENV === "production";
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
async boot() {
|
|
20
24
|
await this.#loadViteFolder();
|
|
21
|
-
const { createServer } = await import("vite");
|
|
22
25
|
|
|
23
26
|
const configFile = this.#resolveConfigFile();
|
|
24
27
|
|
|
28
|
+
// In production we build the frontend once and let Express serve the
|
|
29
|
+
// generated static files. No dev server is started.
|
|
30
|
+
if (this.#isProduction) {
|
|
31
|
+
this.#container.get("logger").info("Building Vite frontend for production...");
|
|
32
|
+
this.#outDir = await buildViteApp({ root: this.#root, configFile });
|
|
33
|
+
this.#container.get("logger").info(`Vite build complete (output: ${this.#outDir})`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const { createServer } = await import("vite");
|
|
38
|
+
|
|
25
39
|
this.#viteServer = await createServer({
|
|
26
40
|
root: this.#root,
|
|
27
41
|
configFile,
|
|
@@ -115,4 +129,12 @@ module.exports = class Vite extends Service {
|
|
|
115
129
|
server() {
|
|
116
130
|
return this.#viteServer;
|
|
117
131
|
}
|
|
132
|
+
|
|
133
|
+
isProduction() {
|
|
134
|
+
return this.#isProduction;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
outDir() {
|
|
138
|
+
return this.#outDir;
|
|
139
|
+
}
|
|
118
140
|
};
|