dinou 7.0.0 → 7.2.0

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/dinou/index.d.ts CHANGED
@@ -120,8 +120,29 @@ export interface RequestContextStore {
120
120
  // DINOU CONFIGURATION & PLUGIN INTERFACES
121
121
  // ====================================================================
122
122
 
123
+ export type NodeMiddleware = (
124
+ req: import("node:http").IncomingMessage,
125
+ res: import("node:http").ServerResponse,
126
+ next: () => void
127
+ ) => void | Promise<void>;
128
+
129
+ export interface ServerHookContext {
130
+ /** The underlying Node.js http.Server instance */
131
+ server: import("node:http").Server;
132
+ /** Whether the server is running in development mode */
133
+ isDev: boolean;
134
+ /** Register a raw Node.js middleware (req, res, next) executed before Dinou routes */
135
+ use(middleware: NodeMiddleware): void;
136
+ }
137
+
123
138
  export interface DinouPlugin {
124
139
  name?: string;
140
+ /**
141
+ * Hook invoked when the Node.js HTTP server is instantiated,
142
+ * allowing plugins to attach WebSockets (Socket.IO, ws), listeners, or raw Node middlewares.
143
+ */
144
+ configureServer?(context: ServerHookContext): Promise<void> | void;
145
+
125
146
  /**
126
147
  * Universal Web Standards middleware and webhook handler.
127
148
  * Runs on every incoming HTTP request before React rendering.
@@ -119,12 +119,32 @@ export async function fetch(req) {
119
119
 
120
120
  const PORT = Number(process.env.PORT || 3000);
121
121
 
122
- export function startServer(port = PORT, host = "0.0.0.0") {
122
+ const nodeMiddlewares = [];
123
+
124
+ export async function startServer(port = PORT, host = "0.0.0.0") {
123
125
  const server = http.createServer(async (req, res) => {
124
126
  try {
127
+ if (res.writableEnded || res.headersSent) {
128
+ return;
129
+ }
130
+
131
+ if (nodeMiddlewares.length > 0) {
132
+ for (const mw of nodeMiddlewares) {
133
+ let continued = false;
134
+ await mw(req, res, () => {
135
+ continued = true;
136
+ });
137
+ if (!continued || res.writableEnded || res.headersSent) {
138
+ return;
139
+ }
140
+ }
141
+ }
142
+
125
143
  const webReq = nodeToWebRequest(req);
126
144
  const webRes = await fetch(webReq);
127
- await sendWebResponseToNode(webRes, res);
145
+ if (!res.writableEnded && !res.headersSent) {
146
+ await sendWebResponseToNode(webRes, res);
147
+ }
128
148
  } catch (err) {
129
149
  console.error("[Dinou Node Server] Request error:", err);
130
150
  if (!res.headersSent) {
@@ -135,6 +155,29 @@ export function startServer(port = PORT, host = "0.0.0.0") {
135
155
  }
136
156
  });
137
157
 
158
+ try {
159
+ const { getDinouConfig } = await import("${dinouDirSlash}/core/load-dinou-config.js");
160
+ const cfg = await getDinouConfig();
161
+ if (cfg.plugins && Array.isArray(cfg.plugins)) {
162
+ const serverContext = {
163
+ server,
164
+ isDev: false,
165
+ use(middleware) {
166
+ if (typeof middleware === "function") {
167
+ nodeMiddlewares.push(middleware);
168
+ }
169
+ },
170
+ };
171
+ for (const plugin of cfg.plugins) {
172
+ if (typeof plugin.configureServer === "function") {
173
+ await plugin.configureServer(serverContext);
174
+ }
175
+ }
176
+ }
177
+ } catch (err) {
178
+ console.error("❌ [Dinou Node Server] Error running configureServer plugins:", err);
179
+ }
180
+
138
181
  return new Promise((resolve, reject) => {
139
182
  server.on("error", reject);
140
183
  server.listen(port, () => {
@@ -2302,9 +2302,52 @@ async function startClientBundler(tool) {
2302
2302
  throw new Error(`Unsupported DINOU_BUILD_TOOL: ${tool}`);
2303
2303
  }
2304
2304
 
2305
+ // Node.js Middlewares registered by plugins via configureServer
2306
+ const nodeMiddlewares = [];
2307
+
2308
+ async function applyServerPlugins(serverInstance) {
2309
+ try {
2310
+ const { getDinouConfig } = require(path.join(dinouDir, "core/load-dinou-config.js"));
2311
+ const config = await getDinouConfig();
2312
+ if (config.plugins && Array.isArray(config.plugins)) {
2313
+ const serverContext = {
2314
+ server: serverInstance,
2315
+ isDev: true,
2316
+ use(middleware) {
2317
+ if (typeof middleware === "function") {
2318
+ nodeMiddlewares.push(middleware);
2319
+ }
2320
+ },
2321
+ };
2322
+ for (const plugin of config.plugins) {
2323
+ if (typeof plugin.configureServer === "function") {
2324
+ await plugin.configureServer(serverContext);
2325
+ }
2326
+ }
2327
+ }
2328
+ } catch (err) {
2329
+ console.error("❌ [Dinou Dev] Error applying plugin configureServer hooks:", err);
2330
+ }
2331
+ }
2332
+
2305
2333
  // HTTP Server
2306
2334
  const server = http.createServer(async (req, res) => {
2307
2335
  try {
2336
+ if (res.writableEnded || res.headersSent) {
2337
+ return;
2338
+ }
2339
+
2340
+ if (nodeMiddlewares.length > 0) {
2341
+ for (const mw of nodeMiddlewares) {
2342
+ let continued = false;
2343
+ await mw(req, res, () => {
2344
+ continued = true;
2345
+ });
2346
+ if (!continued || res.writableEnded || res.headersSent) {
2347
+ return;
2348
+ }
2349
+ }
2350
+ }
2308
2351
  if (clientBundlerPromise) {
2309
2352
  await clientBundlerPromise;
2310
2353
  }
@@ -2493,7 +2536,9 @@ const server = http.createServer(async (req, res) => {
2493
2536
  console.log(`[DEV 404] ${req.method} ${pathname}`);
2494
2537
  }
2495
2538
 
2496
- await sendWebResponseToNode(webRes, res);
2539
+ if (!res.writableEnded && !res.headersSent) {
2540
+ await sendWebResponseToNode(webRes, res);
2541
+ }
2497
2542
  } catch (err) {
2498
2543
  console.error("[Dinou Dev Server] Request error:", err);
2499
2544
  if (!res.headersSent) {
@@ -2515,6 +2560,8 @@ server.on("error", (err) => {
2515
2560
  process.exit(1);
2516
2561
  });
2517
2562
 
2563
+ await applyServerPlugins(server);
2564
+
2518
2565
  server.listen(PORT, async () => {
2519
2566
  const buildTool = isWebpackBuild ? "webpack" : (process.env.DINOU_BUILD_TOOL || "esbuild");
2520
2567
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinou-ejected",
3
- "version": "7.0.0",
3
+ "version": "7.2.0",
4
4
  "main": "index.js",
5
5
  "private": true,
6
6
  "exports": {