dinou 5.1.2 → 6.0.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +3 -3
  3. package/dinou/core/cache-revalidate.js +5 -5
  4. package/dinou/core/generate-static-page.js +5 -5
  5. package/dinou/core/generate-static-pages.js +4 -4
  6. package/dinou/core/generate-static-rsc.js +3 -3
  7. package/dinou/core/generate-static-rscs.js +3 -3
  8. package/dinou/core/generate-static.js +2 -2
  9. package/dinou/core/generating-isg.js +3 -3
  10. package/dinou/core/get-asset-from-manifest.js +2 -2
  11. package/dinou/core/navigation.js +2 -2
  12. package/dinou/core/render-app-to-html.js +3 -3
  13. package/dinou/core/render-html.js +8 -8
  14. package/dinou/core/revalidating.js +39 -39
  15. package/dinou/core/server-function-proxy-webpack.js +7 -3
  16. package/dinou/core/server-function-proxy.js +8 -5
  17. package/dinou/core/server.js +105 -24
  18. package/dinou/esbuild/build.mjs +3 -3
  19. package/dinou/esbuild/dev.mjs +3 -3
  20. package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +2 -2
  21. package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +1 -1
  22. package/dinou/esbuild/plugins-esbuild/css-processor-plugin.mjs +1 -1
  23. package/dinou/esbuild/plugins-esbuild/react-client-manifest-plugin.mjs +1 -1
  24. package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +1 -1
  25. package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +1 -1
  26. package/dinou/package.json +1 -1
  27. package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +1 -1
  28. package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +1 -1
  29. package/dinou/rollup/rollup.config.js +7 -7
  30. package/dinou/webpack/webpack.config.js +4 -4
  31. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [6.0.0] - 2026-09-13
9
+
10
+ ### Changed
11
+ - **Unified `.dinou/` Directory for Build Artifacts & Manifests**: Relocated all compiler outputs, client/server bundles, and runtime metadata under a single `.dinou/` root directory instead of generating multiple folders across the project root.
12
+ * **Build Artifacts Relocation**:
13
+ - `dist2` (pre-rendered static & ISR HTML/RSC payloads) moved to `.dinou/dist2`
14
+ - `dist3` (production bundles & manifests) moved to `.dinou/dist3`
15
+ - `public` (development client bundles & compiled CSS) moved to `.dinou/public`
16
+ - `react_client_manifest` moved to `.dinou/react_client_manifest`
17
+ - `server_functions_manifest` moved to `.dinou/server_functions_manifest`
18
+ * **Clean Project Root & Improved DX**: Eliminates root-level clutter, giving projects a clean, minimal, and production-ready structure.
19
+ * **User Assets Isolation**: The root `public/` directory is now exclusively reserved for user static assets (images, favicons, fonts), preventing compiler bundles from mixing with user files.
20
+ * **Simplified `.gitignore`**: Projects now only require a single `.dinou/` entry in `.gitignore` instead of managing multiple build directory rules.
21
+ * **Effortless Cache Invalidation**: Wiping the compilation cache or performing clean builds can now be done in one command by deleting `.dinou/` (`rm -rf .dinou`).
22
+ * **Full Multi-Bundler Alignment**: Updated all Rollup, Esbuild, and Webpack compiler runners and custom manifest plugins to resolve into `.dinou/` seamlessly across development and production environments.
23
+
24
+ ## [5.2.0] - 2026-07-13
25
+
26
+ ### Added
27
+ - **Lightweight Plugin System & `dinou.config.js` support**: Added native support for extending the framework without manually modifying the core Express server.
28
+ * **Config Loader**: Automatically loads a `dinou.config.js` file at the root of the project to initialize custom plugins.
29
+ * **`onServerInit(app)` Hook**: Allows plugins to register global Express middlewares, custom endpoints (like webhooks), or API routes.
30
+ * **`onRequestContext(req, res, context)` Hook**: Allows plugins to inject custom properties (like `locale` or `userId`) into the RSC context across standard page requests, Server Actions, and dynamic compilation child processes.
31
+ * **Try-Catch Isolation**: Wrapped plugin hooks in safe boundaries with named logging to prevent third-party plugin errors from crashing the server.
32
+
33
+ ### Fixed
34
+ - **URL resolution for search params**: Fixed `useSearchParams` and `usePathname` to work correctly with URL hashes.
35
+ - **Server Actions with FormData**: Fixed server actions to correctly handle FormData arguments, supporting formData in any position in the args list.
36
+
8
37
  ## [5.1.2] - 2026-07-12
9
38
 
10
39
  ### Fixed
package/README.md CHANGED
@@ -1522,7 +1522,7 @@ Dinou is flexible and integrates with three major bundlers: **esbuild** (default
1522
1522
 
1523
1523
  ### Development
1524
1524
 
1525
- Starts the development server with hot reloading. Files are emitted to the `public` folder.
1525
+ Starts the development server with hot reloading. Files are emitted to the `./dinou/public` folder.
1526
1526
 
1527
1527
  | Command | Bundler | Description |
1528
1528
  | :-------------------- | :---------- | :------------------------- |
@@ -1533,7 +1533,7 @@ Starts the development server with hot reloading. Files are emitted to the `publ
1533
1533
 
1534
1534
  ### Production Build
1535
1535
 
1536
- Compiles the application for production. Files are emitted to the `dist3` folder.
1536
+ Compiles the application for production. Files are emitted to the `.dinou/dist3` folder.
1537
1537
 
1538
1538
  | Command | Bundler |
1539
1539
  | :---------------------- | :--------------------- |
@@ -1544,7 +1544,7 @@ Compiles the application for production. Files are emitted to the `dist3` folder
1544
1544
 
1545
1545
  ### Start Production Server
1546
1546
 
1547
- Runs the built application from the `dist3` folder.
1547
+ Runs the built application from the `.dinou/dist3` folder.
1548
1548
 
1549
1549
  | Command | Description |
1550
1550
  | :---------------------- | :---------------------------------- |
@@ -39,7 +39,7 @@ async function revalidatePath(reqPath) {
39
39
  if (referer) {
40
40
  try {
41
41
  currentPathname = new URL(referer).pathname;
42
- } catch (e) {}
42
+ } catch (e) { }
43
43
  } else {
44
44
  currentPathname = ctx.req.path || "/";
45
45
  }
@@ -55,7 +55,7 @@ async function revalidatePath(reqPath) {
55
55
  cleanPath = cleanPath.slice(0, -1);
56
56
  }
57
57
 
58
- const dist2Folder = path.resolve(process.cwd(), "dist2");
58
+ const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
59
59
  const reqPathWithSlash = cleanPath.endsWith("/") ? cleanPath : cleanPath + "/";
60
60
 
61
61
  // Check if there is an existing page to copy to _old
@@ -89,7 +89,7 @@ async function revalidatePath(reqPath) {
89
89
  if (!rscResult.success) {
90
90
  console.warn(`⚠️ [Revalidate] RSC generation failed for ${cleanPath}.`);
91
91
  if (rscResult.tempPath && existsSync(rscResult.tempPath)) {
92
- await fs.unlink(rscResult.tempPath).catch(() => {});
92
+ await fs.unlink(rscResult.tempPath).catch(() => { });
93
93
  }
94
94
  return;
95
95
  }
@@ -104,7 +104,7 @@ async function revalidatePath(reqPath) {
104
104
  } else {
105
105
  console.warn(`⚠️ [Revalidate] HTML generation failed for ${cleanPath}.`);
106
106
  if (pageResult.tempPath && existsSync(pageResult.tempPath)) {
107
- await fs.unlink(pageResult.tempPath).catch(() => {});
107
+ await fs.unlink(pageResult.tempPath).catch(() => { });
108
108
  }
109
109
  }
110
110
  } catch (e) {
@@ -114,7 +114,7 @@ async function revalidatePath(reqPath) {
114
114
 
115
115
  async function revalidateTag(tag) {
116
116
  console.log(`[Revalidate] Starting on-demand revalidation for tag: "${tag}"...`);
117
- const dist2Folder = path.resolve(process.cwd(), "dist2");
117
+ const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
118
118
  if (!existsSync(dist2Folder)) return;
119
119
 
120
120
  const metadataFiles = await walkMetadataFiles(dist2Folder);
@@ -5,7 +5,7 @@ const renderAppToHtml = require("./render-app-to-html.js");
5
5
  const { getStaticMetadata } = require("./build-static-pages.js");
6
6
  const { processMetadata } = require("./get-ssg-metadata.js");
7
7
 
8
- const OUT_DIR = path.resolve("dist2");
8
+ const OUT_DIR = path.resolve(".dinou/dist2");
9
9
 
10
10
  async function generateStaticPage(reqPath) {
11
11
  const finalReqPath = reqPath.endsWith("/") ? reqPath : reqPath + "/";
@@ -52,9 +52,9 @@ async function generateStaticPage(reqPath) {
52
52
  status: (code) => {
53
53
  capturedStatus.value = code;
54
54
  },
55
- setHeader: () => {},
56
- clearCookie: () => {},
57
- redirect: () => {},
55
+ setHeader: () => { },
56
+ clearCookie: () => { },
57
+ redirect: () => { },
58
58
  };
59
59
 
60
60
  htmlStream = renderAppToHtml(
@@ -112,7 +112,7 @@ async function generateStaticPage(reqPath) {
112
112
  status: status,
113
113
  };
114
114
  } catch (error) {
115
- await fs.unlink(tempHtmlPath).catch(() => {});
115
+ await fs.unlink(tempHtmlPath).catch(() => { });
116
116
  return { success: false, tempPath: tempHtmlPath };
117
117
  }
118
118
  }
@@ -7,7 +7,7 @@ const { getStaticMetadata } = require("./build-static-pages.js");
7
7
  const { processMetadata } = require("./get-ssg-metadata.js");
8
8
  const { updateStatus } = require("./status-manifest.js");
9
9
 
10
- const OUT_DIR = path.resolve("dist2");
10
+ const OUT_DIR = path.resolve(".dinou/dist2");
11
11
 
12
12
  async function generateStaticPages(routes) {
13
13
  for (const route of routes) {
@@ -57,9 +57,9 @@ async function generateStaticPages(routes) {
57
57
  console.warn(`[SSG] Status ${code} ignored for ${reqPath}`);
58
58
  capturedStatus.value = code;
59
59
  },
60
- setHeader: () => {},
61
- clearCookie: () => {},
62
- redirect: () => {},
60
+ setHeader: () => { },
61
+ clearCookie: () => { },
62
+ redirect: () => { },
63
63
  };
64
64
 
65
65
  htmlStream = renderAppToHtml(
@@ -9,7 +9,7 @@ const { renderToPipeableStream } = isWebpack
9
9
  : require("@roggc/react-server-dom-esm/server");
10
10
  const { requestStorage } = require("./request-context.js");
11
11
 
12
- const OUT_DIR = path.resolve("dist2");
12
+ const OUT_DIR = path.resolve(".dinou/dist2");
13
13
  // const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
14
14
 
15
15
  async function generateStaticRSC(reqPath) {
@@ -83,8 +83,8 @@ async function generateStaticRSC(reqPath) {
83
83
  fs.readFileSync(
84
84
  path.resolve(
85
85
  isWebpack
86
- ? "dist3/react-client-manifest.json"
87
- : "react_client_manifest/react-client-manifest.json"
86
+ ? ".dinou/dist3/react-client-manifest.json"
87
+ : ".dinou/react_client_manifest/react-client-manifest.json"
88
88
  ),
89
89
  "utf8"
90
90
  )
@@ -11,7 +11,7 @@ const { renderToPipeableStream } = isWebpack
11
11
  // 👇 Your context storage
12
12
  const { requestStorage } = require("./request-context.js");
13
13
 
14
- const OUT_DIR = path.resolve("dist2");
14
+ const OUT_DIR = path.resolve(".dinou/dist2");
15
15
  // const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
16
16
 
17
17
  async function generateStaticRSCs(routes) {
@@ -19,8 +19,8 @@ async function generateStaticRSCs(routes) {
19
19
  fs.readFileSync(
20
20
  path.resolve(
21
21
  isWebpack
22
- ? "dist3/react-client-manifest.json"
23
- : "react_client_manifest/react-client-manifest.json"
22
+ ? ".dinou/dist3/react-client-manifest.json"
23
+ : ".dinou/react_client_manifest/react-client-manifest.json"
24
24
  ),
25
25
  "utf8"
26
26
  )
@@ -5,11 +5,11 @@ const generateStaticPages = require("./generate-static-pages");
5
5
  const { buildStaticPages, getStaticPaths } = require("./build-static-pages");
6
6
 
7
7
  async function generateStatic() {
8
- const distFolder2 = path.resolve(process.cwd(), "dist2");
8
+ const distFolder2 = path.resolve(process.cwd(), ".dinou/dist2");
9
9
 
10
10
  if (existsSync(distFolder2)) {
11
11
  rmSync(distFolder2, { recursive: true, force: true });
12
- console.log("Deleted existing dist2 folder");
12
+ console.log("Deleted existing .dinou/dist2 folder");
13
13
  }
14
14
 
15
15
  await buildStaticPages();
@@ -9,7 +9,7 @@ const { safeRename } = require("./safe-rename");
9
9
  const { updateStatus } = require("./status-manifest");
10
10
 
11
11
  function generatingISG(reqPath, isDynamicFromServer) {
12
- const dist2Folder = path.resolve(process.cwd(), "dist2");
12
+ const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
13
13
  // 1. Concurrency Protection
14
14
  if (regenerating.has(reqPath)) return;
15
15
  try {
@@ -45,7 +45,7 @@ function generatingISG(reqPath, isDynamicFromServer) {
45
45
  const rscResult = await generateStaticRSC(reqPath);
46
46
  if (!rscResult.success) {
47
47
  console.warn(`⚠️ [ISG] RSC generation failed for ${reqPath}. Aborting.`);
48
- await fs.unlink(rscResult.tempPath).catch(() => {});
48
+ await fs.unlink(rscResult.tempPath).catch(() => { });
49
49
  return;
50
50
  }
51
51
 
@@ -59,7 +59,7 @@ function generatingISG(reqPath, isDynamicFromServer) {
59
59
  isDynamicFromServer.value = false;
60
60
  console.log(`✅ [ISG] Successfully promoted ${reqPath} to static.`);
61
61
  } else {
62
- await fs.unlink(pageResult.tempPath).catch(() => {});
62
+ await fs.unlink(pageResult.tempPath).catch(() => { });
63
63
  console.warn(`⚠️ [ISG] HTML generation failed for ${reqPath}. Aborting commit.`);
64
64
  }
65
65
 
@@ -7,13 +7,13 @@ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
7
7
 
8
8
  function getAssetFromManifest(name) {
9
9
  if (process.env.NODE_ENV === "production" && !read) {
10
- const manifestPath = path.resolve(process.cwd(), "dist3/manifest.json");
10
+ const manifestPath = path.resolve(process.cwd(), ".dinou/dist3/manifest.json");
11
11
  if (fs.existsSync(manifestPath)) {
12
12
  manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
13
13
  read = true;
14
14
  }
15
15
  } else if (isWebpack && !read) {
16
- const manifestPath = path.resolve(process.cwd(), "public/manifest.json");
16
+ const manifestPath = path.resolve(process.cwd(), ".dinou/public/manifest.json");
17
17
  if (fs.existsSync(manifestPath)) {
18
18
  manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
19
19
  read = true;
@@ -126,7 +126,7 @@ export function usePathname() {
126
126
  return "";
127
127
  }
128
128
 
129
- const path = fullRoute.split("?")[0];
129
+ const path = fullRoute.split("#")[0].split("?")[0];
130
130
  return normalizePath(path);
131
131
  }
132
132
 
@@ -165,6 +165,6 @@ export function useSearchParams() {
165
165
 
166
166
  if (typeof fullRoute !== "string") return new URLSearchParams();
167
167
 
168
- const searchPart = fullRoute.split("?")[1] || "";
168
+ const searchPart = (fullRoute.split("?")[1] || "").split("#")[0];
169
169
  return new URLSearchParams(searchPart);
170
170
  }
@@ -15,8 +15,8 @@ const { renderToPipeableStream } = isWebpack
15
15
  const manifestPath = path.resolve(
16
16
  process.cwd(),
17
17
  isWebpack
18
- ? (isDevelopment ? "public/react-client-manifest.json" : "dist3/react-client-manifest.json")
19
- : "react_client_manifest/react-client-manifest.json"
18
+ ? (isDevelopment ? ".dinou/public/react-client-manifest.json" : ".dinou/dist3/react-client-manifest.json")
19
+ : ".dinou/react_client_manifest/react-client-manifest.json"
20
20
  );
21
21
 
22
22
  let cachedManifest = null;
@@ -189,7 +189,7 @@ function renderAppToHtml(
189
189
  );
190
190
 
191
191
  const query = JSON.parse(paramsString || "{}");
192
- const rscPath = path.resolve(process.cwd(), "dist2", reqPath.replace(/^\//, ""), "rsc.rsc");
192
+ const rscPath = path.resolve(process.cwd(), ".dinou/dist2", reqPath.replace(/^\//, ""), "rsc.rsc");
193
193
  const hasStaticRsc = !isDynamic && fs.existsSync(rscPath);
194
194
 
195
195
  if (hasStaticRsc) {
@@ -144,7 +144,7 @@ function getImportMapHtml() {
144
144
 
145
145
  const manifestPath = path.resolve(
146
146
  process.cwd(),
147
- "react_client_manifest/react-client-manifest.json"
147
+ ".dinou/react_client_manifest/react-client-manifest.json"
148
148
  );
149
149
 
150
150
  if (!fs.existsSync(manifestPath)) {
@@ -184,11 +184,11 @@ function getSsrManifest() {
184
184
  const path = require("path");
185
185
  const ssrManifestPath = path.resolve(
186
186
  process.cwd(),
187
- isDevelopment ? "public/react-ssr-manifest.json" : "dist3/react-ssr-manifest.json"
187
+ isDevelopment ? ".dinou/public/react-ssr-manifest.json" : ".dinou/dist3/react-ssr-manifest.json"
188
188
  );
189
189
  const clientManifestPath = path.resolve(
190
190
  process.cwd(),
191
- isDevelopment ? "public/react-client-manifest.json" : "dist3/react-client-manifest.json"
191
+ isDevelopment ? ".dinou/public/react-client-manifest.json" : ".dinou/dist3/react-client-manifest.json"
192
192
  );
193
193
 
194
194
  const ssrContent = fs.readFileSync(ssrManifestPath, "utf8");
@@ -204,7 +204,7 @@ function getSsrManifest() {
204
204
  if (entry && entry.id !== undefined) {
205
205
  try {
206
206
  requireMap[entry.id] = fileURLToPath(fileUrl);
207
- } catch {}
207
+ } catch { }
208
208
  }
209
209
  }
210
210
  global.__webpack_require_map__ = requireMap;
@@ -294,10 +294,10 @@ async function renderToStream(
294
294
  const errorStream = renderToPipeableStream(errorJSX, {
295
295
  onShellReady() {
296
296
  const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
297
- if (!isWebpack) {
298
- const importMapHtml = getImportMapHtml();
299
- process.stdout.write(importMapHtml);
300
- }
297
+ if (!isWebpack) {
298
+ const importMapHtml = getImportMapHtml();
299
+ process.stdout.write(importMapHtml);
300
+ }
301
301
  errorStream.pipe(process.stdout);
302
302
  },
303
303
  onError(err) {
@@ -10,7 +10,7 @@ const { updateStatus } = require("./status-manifest");
10
10
  const regenerating = new Set();
11
11
 
12
12
  function revalidating(reqPath, isDynamicFromServer) {
13
- const dist2Folder = path.resolve(process.cwd(), "dist2");
13
+ const dist2Folder = path.resolve(process.cwd(), ".dinou/dist2");
14
14
  const metadataPath = path.join(dist2Folder, reqPath, "metadata.json");
15
15
 
16
16
  if (regenerating.has(reqPath)) return;
@@ -46,49 +46,49 @@ function revalidating(reqPath, isDynamicFromServer) {
46
46
  (async () => {
47
47
  try {
48
48
  console.log(`[ISR] Starting regeneration for ${reqPath}...`);
49
- const isDynamic = {};
50
- await buildStaticPage(reqPath, isDynamic);
51
- if (isDynamic.value) {
52
- isDynamicFromServer.value = true;
53
- console.log(
54
- `[ISR] Bailout detected for ${reqPath}. Switching to Dynamic.`
55
- );
49
+ const isDynamic = {};
50
+ await buildStaticPage(reqPath, isDynamic);
51
+ if (isDynamic.value) {
52
+ isDynamicFromServer.value = true;
53
+ console.log(
54
+ `[ISR] Bailout detected for ${reqPath}. Switching to Dynamic.`
55
+ );
56
56
 
57
- return;
58
- }
57
+ return;
58
+ }
59
59
 
60
- const rscResult = await generateStaticRSC(reqPath);
61
- if (!rscResult.success) {
62
- console.warn(`⚠️ [ISR] RSC generation failed for ${reqPath}. Aborting.`);
63
- await fs.unlink(rscResult.tempPath).catch(() => {});
64
- return;
65
- }
60
+ const rscResult = await generateStaticRSC(reqPath);
61
+ if (!rscResult.success) {
62
+ console.warn(`⚠️ [ISR] RSC generation failed for ${reqPath}. Aborting.`);
63
+ await fs.unlink(rscResult.tempPath).catch(() => { });
64
+ return;
65
+ }
66
66
 
67
- // Commit the RSC payload immediately so that generateStaticPage can read it
68
- await safeRename(rscResult.tempPath, rscResult.finalPath);
67
+ // Commit the RSC payload immediately so that generateStaticPage can read it
68
+ await safeRename(rscResult.tempPath, rscResult.finalPath);
69
69
 
70
- const pageResult = await generateStaticPage(reqPath);
71
- if (pageResult.success) {
72
- await safeRename(pageResult.tempPath, pageResult.finalPath);
73
- updateStatus(reqPath, pageResult.status);
74
- isDynamicFromServer.value = false;
75
- console.log(
76
- `✅ [ISR] Successfully committed ${reqPath} (Status: ${pageResult.status})`
77
- );
78
- } else {
79
- console.warn(
80
- `⚠️ [ISR] HTML generation failed for ${reqPath}. Aborting commit.`
81
- );
82
- await fs.unlink(pageResult.tempPath).catch(() => {});
83
- }
84
- } catch (e) {
85
- console.error(`[ISR] Critical error regenerating ${reqPath}:`, e);
86
- } finally {
87
- regenerating.delete(reqPath);
70
+ const pageResult = await generateStaticPage(reqPath);
71
+ if (pageResult.success) {
72
+ await safeRename(pageResult.tempPath, pageResult.finalPath);
73
+ updateStatus(reqPath, pageResult.status);
74
+ isDynamicFromServer.value = false;
75
+ console.log(
76
+ `✅ [ISR] Successfully committed ${reqPath} (Status: ${pageResult.status})`
77
+ );
78
+ } else {
79
+ console.warn(
80
+ `⚠️ [ISR] HTML generation failed for ${reqPath}. Aborting commit.`
81
+ );
82
+ await fs.unlink(pageResult.tempPath).catch(() => { });
83
+ }
84
+ } catch (e) {
85
+ console.error(`[ISR] Critical error regenerating ${reqPath}:`, e);
86
+ } finally {
87
+ regenerating.delete(reqPath);
88
+ }
89
+ })();
88
90
  }
89
- })();
90
- }
91
- }).catch((err) => {});
91
+ }).catch((err) => { });
92
92
  }
93
93
 
94
94
  module.exports = { revalidating, regenerating };
@@ -22,13 +22,17 @@ function createServerFunctionProxy(id) {
22
22
  "x-server-function-call": "1",
23
23
  };
24
24
 
25
- if (args[0] instanceof FormData) {
26
- const formData = args[0];
25
+ const formDataIndex = args.findIndex((arg) => arg instanceof FormData);
26
+
27
+ if (formDataIndex !== -1) {
28
+ const formData = args[formDataIndex];
27
29
 
28
30
  formData.append("__dinou_func_id", id);
31
+ formData.append("__dinou_formData_index", String(formDataIndex));
29
32
 
30
33
  if (args.length > 1) {
31
- formData.append("__dinou_args", JSON.stringify(args.slice(1)));
34
+ const serializedArgs = args.map((arg, i) => (i === formDataIndex ? null : arg));
35
+ formData.append("__dinou_args", JSON.stringify(serializedArgs));
32
36
  }
33
37
 
34
38
  body = formData;
@@ -1,4 +1,3 @@
1
- // public/server-function-proxy.js
2
1
  import { createFromFetch } from "@roggc/react-server-dom-esm/client";
3
2
 
4
3
  function isSafeRedirect(url) {
@@ -16,20 +15,24 @@ function executeRedirect(url) {
16
15
  }
17
16
 
18
17
  export function createServerFunctionProxy(id) {
19
- return new Proxy(() => {}, {
18
+ return new Proxy(() => { }, {
20
19
  apply: async (_target, _thisArg, args) => {
21
20
  let body;
22
21
  const headers = {
23
22
  "x-server-function-call": "1",
24
23
  };
25
24
 
26
- if (args[0] instanceof FormData) {
27
- const formData = args[0];
25
+ const formDataIndex = args.findIndex((arg) => arg instanceof FormData);
26
+
27
+ if (formDataIndex !== -1) {
28
+ const formData = args[formDataIndex];
28
29
 
29
30
  formData.append("__dinou_func_id", id);
31
+ formData.append("__dinou_formData_index", String(formDataIndex));
30
32
 
31
33
  if (args.length > 1) {
32
- formData.append("__dinou_args", JSON.stringify(args.slice(1)));
34
+ const serializedArgs = args.map((arg, i) => (i === formDataIndex ? null : arg));
35
+ formData.append("__dinou_args", JSON.stringify(serializedArgs));
33
36
  }
34
37
 
35
38
  body = formData;
@@ -72,10 +72,22 @@ addHook({
72
72
  });
73
73
  const importModule = require("./import-module");
74
74
  const generateStatic = require("./generate-static.js");
75
+
76
+ // Load Dinou configuration and plugins
77
+ let dinouConfig = { plugins: [] };
78
+ const dinouConfigPath = path.resolve(process.cwd(), "dinou.config.js");
79
+ if (existsSync(dinouConfigPath)) {
80
+ try {
81
+ dinouConfig = require(dinouConfigPath);
82
+ } catch (err) {
83
+ console.error("[Dinou] Error loading dinou.config.js:", err);
84
+ }
85
+ }
86
+
75
87
  const renderAppToHtml = require("./render-app-to-html.js");
76
88
  const { revalidating, regenerating } = require("./revalidating.js");
77
89
  const isDevelopment = process.env.NODE_ENV !== "production";
78
- const outputFolder = isDevelopment ? "public" : "dist3";
90
+ const outputFolder = isDevelopment ? ".dinou/public" : ".dinou/dist3";
79
91
  const chokidar = require("chokidar");
80
92
  const { fileURLToPath, pathToFileURL } = require("url");
81
93
  const parseExports = require("./parse-exports.js");
@@ -89,11 +101,11 @@ if (isDevelopment) {
89
101
  process.cwd(),
90
102
  isWebpack
91
103
  ? `${outputFolder}/react-client-manifest.json`
92
- : `react_client_manifest/react-client-manifest.json`,
104
+ : `.dinou/react_client_manifest/react-client-manifest.json`,
93
105
  );
94
106
  const manifestFolderPath = path.resolve(
95
107
  process.cwd(),
96
- isWebpack ? outputFolder : "react_client_manifest",
108
+ isWebpack ? outputFolder : ".dinou/react_client_manifest",
97
109
  );
98
110
 
99
111
  let manifestWatcher = null;
@@ -266,7 +278,7 @@ if (!isDevelopment) {
266
278
  process.cwd(),
267
279
  isWebpack
268
280
  ? `${outputFolder}/server-functions-manifest.json`
269
- : `server_functions_manifest/server-functions-manifest.json`,
281
+ : `.dinou/server_functions_manifest/server-functions-manifest.json`,
270
282
  ); // Adjust 'dist/' to your outdir
271
283
  if (existsSync(manifestPath)) {
272
284
  serverFunctionsManifest = JSON.parse(readFileSync(manifestPath, "utf8"));
@@ -283,6 +295,21 @@ const cookieParser = require("cookie-parser");
283
295
  const appUseCookieParser = cookieParser();
284
296
  const app = express();
285
297
  app.use(appUseCookieParser);
298
+
299
+ // Run plugins onServerInit hook
300
+ if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
301
+ for (const plugin of dinouConfig.plugins) {
302
+ if (typeof plugin.onServerInit === "function") {
303
+ try {
304
+ plugin.onServerInit(app);
305
+ console.log(`[Dinou] Plugin initialized: "${plugin.name || "unnamed"}"`);
306
+ } catch (err) {
307
+ console.error(`[Dinou] Error initializing plugin "${plugin.name || "unnamed"}":`, err);
308
+ }
309
+ }
310
+ }
311
+ }
312
+
286
313
  app.use(express.json());
287
314
 
288
315
  // ============================================================
@@ -406,6 +433,20 @@ function getContext(req, res) {
406
433
  redirect: (...args) => safeResCall("redirect", ...args),
407
434
  },
408
435
  };
436
+
437
+ // Run plugins onRequestContext hook
438
+ if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
439
+ for (const plugin of dinouConfig.plugins) {
440
+ if (typeof plugin.onRequestContext === "function") {
441
+ try {
442
+ plugin.onRequestContext(req, res, context);
443
+ } catch (err) {
444
+ console.error(`[Dinou] Error running onRequestContext in plugin "${plugin.name || "unnamed"}":`, err);
445
+ }
446
+ }
447
+ }
448
+ }
449
+
409
450
  return context;
410
451
  }
411
452
 
@@ -534,6 +575,20 @@ function getContextForServerFunctionEndpoint(req, res) {
534
575
  },
535
576
  },
536
577
  };
578
+
579
+ // Run plugins onRequestContext hook
580
+ if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
581
+ for (const plugin of dinouConfig.plugins) {
582
+ if (typeof plugin.onRequestContext === "function") {
583
+ try {
584
+ plugin.onRequestContext(req, res, context);
585
+ } catch (err) {
586
+ console.error(`[Dinou] Error running onRequestContext in plugin "${plugin.name || "unnamed"}":`, err);
587
+ }
588
+ }
589
+ }
590
+ }
591
+
537
592
  return context;
538
593
  }
539
594
 
@@ -543,7 +598,7 @@ const clientManifestResolvedPath = path.resolve(
543
598
  process.cwd(),
544
599
  isWebpack
545
600
  ? `${outputFolder}/react-client-manifest.json`
546
- : `react_client_manifest/react-client-manifest.json`,
601
+ : `.dinou/react_client_manifest/react-client-manifest.json`,
547
602
  );
548
603
 
549
604
  function isManifestReady() {
@@ -583,7 +638,7 @@ if (!isDevelopment) {
583
638
  process.cwd(),
584
639
  isWebpack
585
640
  ? `${outputFolder}/react-client-manifest.json`
586
- : `react_client_manifest/react-client-manifest.json`,
641
+ : `.dinou/react_client_manifest/react-client-manifest.json`,
587
642
  ),
588
643
  "utf8",
589
644
  ),
@@ -624,7 +679,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
624
679
  if ((!isDevelopment && !dynamicState.value) || isStatic) {
625
680
  let currentGeneratedAt = null;
626
681
  try {
627
- const metadataPath = path.join("dist2", reqPath, "metadata.json");
682
+ const metadataPath = path.join(".dinou/dist2", reqPath, "metadata.json");
628
683
  if (existsSync(metadataPath)) {
629
684
  const metaObj = JSON.parse(readFileSync(metadataPath, "utf8"));
630
685
  currentGeneratedAt = metaObj.generatedAt || null;
@@ -639,12 +694,12 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
639
694
  req.query.buildId !== String(currentGeneratedAt));
640
695
 
641
696
  const payloadPath = path.resolve(
642
- "dist2",
697
+ ".dinou/dist2",
643
698
  reqPath.replace(/^\//, ""),
644
699
  useOld ? "rsc._old.rsc" : "rsc.rsc",
645
700
  );
646
701
 
647
- const distDir = path.resolve("dist2");
702
+ const distDir = path.resolve(".dinou/dist2");
648
703
 
649
704
  if (!payloadPath.startsWith(distDir)) {
650
705
  return res.status(403).end();
@@ -748,7 +803,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
748
803
  if (isDevelopment) {
749
804
  isPathBlocked = true;
750
805
  } else {
751
- const htmlPath = path.join("dist2", reqPath, "index.html");
806
+ const htmlPath = path.join(".dinou/dist2", reqPath, "index.html");
752
807
  if (!existsSync(htmlPath)) {
753
808
  isPathBlocked = true;
754
809
  }
@@ -784,7 +839,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
784
839
  process.cwd(),
785
840
  isWebpack
786
841
  ? `${outputFolder}/react-client-manifest.json`
787
- : `react_client_manifest/react-client-manifest.json`,
842
+ : `.dinou/react_client_manifest/react-client-manifest.json`,
788
843
  ),
789
844
  "utf8",
790
845
  ),
@@ -819,7 +874,7 @@ async function serveRSCPayload(req, res, isOld = false, isStatic = false) {
819
874
  process.cwd(),
820
875
  isWebpack
821
876
  ? `${outputFolder}/react-client-manifest.json`
822
- : `react_client_manifest/react-client-manifest.json`,
877
+ : `.dinou/react_client_manifest/react-client-manifest.json`,
823
878
  ),
824
879
  "utf8",
825
880
  ),
@@ -875,7 +930,7 @@ app.post(/^\/____rsc_payload_error____\/.*\/?$/, async (req, res) => {
875
930
  process.cwd(),
876
931
  isWebpack
877
932
  ? `${outputFolder}/react-client-manifest.json`
878
- : `react_client_manifest/react-client-manifest.json`,
933
+ : `.dinou/react_client_manifest/react-client-manifest.json`,
879
934
  ),
880
935
  "utf8",
881
936
  ),
@@ -990,7 +1045,7 @@ app.get(/^\/.*\/?$/, async (req, res) => {
990
1045
  if (isDevelopment) {
991
1046
  isPathBlocked = true;
992
1047
  } else {
993
- const htmlPath = path.join("dist2", req.path, "index.html");
1048
+ const htmlPath = path.join(".dinou/dist2", req.path, "index.html");
994
1049
  if (!existsSync(htmlPath)) {
995
1050
  isPathBlocked = true;
996
1051
  }
@@ -1017,9 +1072,9 @@ app.get(/^\/.*\/?$/, async (req, res) => {
1017
1072
  let htmlPathOld;
1018
1073
  if (regenerating.has(reqPath)) {
1019
1074
  // Still regenerating, serve old HTML if exists
1020
- htmlPathOld = path.join("dist2", reqPath, "index._old.html");
1075
+ htmlPathOld = path.join(".dinou/dist2", reqPath, "index._old.html");
1021
1076
  }
1022
- const htmlPath = path.join("dist2", reqPath, "index.html");
1077
+ const htmlPath = path.join(".dinou/dist2", reqPath, "index.html");
1023
1078
  // Decide which file to read
1024
1079
  const fileToRead = htmlPathOld || htmlPath;
1025
1080
 
@@ -1037,7 +1092,7 @@ app.get(/^\/.*\/?$/, async (req, res) => {
1037
1092
  let htmlContent = readFileSync(fileToRead, "utf8");
1038
1093
  let buildId = "";
1039
1094
  try {
1040
- const metadataPath = path.join("dist2", reqPath, "metadata.json");
1095
+ const metadataPath = path.join(".dinou/dist2", reqPath, "metadata.json");
1041
1096
  if (existsSync(metadataPath)) {
1042
1097
  const metaObj = JSON.parse(readFileSync(metadataPath, "utf8"));
1043
1098
  buildId = metaObj.generatedAt || "";
@@ -1084,6 +1139,20 @@ app.get(/^\/.*\/?$/, async (req, res) => {
1084
1139
  },
1085
1140
  // Do not include res here
1086
1141
  };
1142
+
1143
+ // Run plugins onRequestContext hook
1144
+ if (dinouConfig.plugins && Array.isArray(dinouConfig.plugins)) {
1145
+ for (const plugin of dinouConfig.plugins) {
1146
+ if (typeof plugin.onRequestContext === "function") {
1147
+ try {
1148
+ plugin.onRequestContext(req, res, contextForChild);
1149
+ } catch (err) {
1150
+ console.error(`[Dinou] Error running onRequestContext in plugin "${plugin.name || "unnamed"}":`, err);
1151
+ }
1152
+ }
1153
+ }
1154
+ }
1155
+
1087
1156
  processLimiter
1088
1157
  .run(async () => {
1089
1158
  const isDynamic = true;
@@ -1211,7 +1280,12 @@ app.post("/____server_function____", async (req, res) => {
1211
1280
  const formData = new FormData();
1212
1281
 
1213
1282
  for (const key in req.body) {
1214
- if (key === "__dinou_func_id" || key === "__dinou_args") continue;
1283
+ if (
1284
+ key === "__dinou_func_id" ||
1285
+ key === "__dinou_args" ||
1286
+ key === "__dinou_formData_index"
1287
+ )
1288
+ continue;
1215
1289
  formData.append(key, req.body[key]);
1216
1290
  }
1217
1291
 
@@ -1222,15 +1296,22 @@ app.post("/____server_function____", async (req, res) => {
1222
1296
  }
1223
1297
  }
1224
1298
 
1225
- args = [formData];
1226
-
1227
1299
  if (req.body.__dinou_args) {
1228
1300
  try {
1229
- const extraArgs = JSON.parse(req.body.__dinou_args);
1230
- args.push(...extraArgs);
1301
+ const parsedArgs = JSON.parse(req.body.__dinou_args);
1302
+ if (req.body.__dinou_formData_index !== undefined) {
1303
+ const formDataIndex = parseInt(req.body.__dinou_formData_index, 10);
1304
+ parsedArgs[formDataIndex] = formData;
1305
+ args = parsedArgs;
1306
+ } else {
1307
+ args = [formData, ...parsedArgs];
1308
+ }
1231
1309
  } catch (e) {
1232
- console.error("Error parsing extra args in multipart request");
1310
+ console.error("Error parsing extra args in multipart request", e);
1311
+ args = [formData];
1233
1312
  }
1313
+ } else {
1314
+ args = [formData];
1234
1315
  }
1235
1316
  } else {
1236
1317
  id = req.body.id;
@@ -1382,7 +1463,7 @@ app.post("/____server_function____", async (req, res) => {
1382
1463
  process.cwd(),
1383
1464
  isWebpack
1384
1465
  ? `${outputFolder}/react-client-manifest.json`
1385
- : `react_client_manifest/react-client-manifest.json`,
1466
+ : `.dinou/react_client_manifest/react-client-manifest.json`,
1386
1467
  );
1387
1468
  // Verify that the manifest exists to avoid errors
1388
1469
  if (!existsSync(manifestPath)) {
@@ -9,10 +9,10 @@ import { updateManifestForModule } from "./helpers-esbuild/update-manifest-for-m
9
9
  const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = path.dirname(__filename);
11
11
 
12
- const outdir = "dist3";
12
+ const outdir = ".dinou/dist3";
13
13
  await fs.rm(outdir, { recursive: true, force: true });
14
- await fs.rm("react_client_manifest", { recursive: true, force: true });
15
- await fs.rm("server_functions_manifest", { recursive: true, force: true });
14
+ await fs.rm(".dinou/react_client_manifest", { recursive: true, force: true });
15
+ await fs.rm(".dinou/server_functions_manifest", { recursive: true, force: true });
16
16
 
17
17
  const absPathToClientRedirect = path.resolve(
18
18
  __dirname,
@@ -13,10 +13,10 @@ import { useServerRegex } from "../constants.js";
13
13
  const __filename = fileURLToPath(import.meta.url);
14
14
  const __dirname = path.dirname(__filename);
15
15
 
16
- const outdir = "public";
16
+ const outdir = ".dinou/public";
17
17
  await fs.rm(outdir, { recursive: true, force: true });
18
- await fs.rm("react_client_manifest", { recursive: true, force: true });
19
- await fs.rm("server_functions_manifest", { recursive: true, force: true });
18
+ await fs.rm(".dinou/react_client_manifest", { recursive: true, force: true });
19
+ await fs.rm(".dinou/server_functions_manifest", { recursive: true, force: true });
20
20
 
21
21
  let currentCtx = null; // Track the active esbuild context
22
22
  let debounceTimer = null; // For debouncing recreations
@@ -13,7 +13,7 @@ const manifestData = {};
13
13
 
14
14
  export default function getConfigEsbuildProd({
15
15
  entryPoints,
16
- outdir = "dist3",
16
+ outdir = ".dinou/dist3",
17
17
  manifest = {},
18
18
  }) {
19
19
  let plugins = [
@@ -22,7 +22,7 @@ export default function getConfigEsbuildProd({
22
22
  cssProcessorPlugin({ outdir }),
23
23
  reactClientManifestPlugin({
24
24
  manifest,
25
- manifestPath: `react_client_manifest/react-client-manifest.json`,
25
+ manifestPath: `.dinou/react_client_manifest/react-client-manifest.json`,
26
26
  }),
27
27
  assetsPlugin(),
28
28
  manifestGeneratorPlugin(manifestData),
@@ -11,7 +11,7 @@ import { existsSync } from "node:fs";
11
11
 
12
12
  export default function getConfigEsbuild({
13
13
  entryPoints,
14
- outdir = "public",
14
+ outdir = ".dinou/public",
15
15
  manifest = {},
16
16
  changedIds,
17
17
  hmrEngine,
@@ -11,7 +11,7 @@ import { pathToFileURL } from "node:url";
11
11
  import resolve from "resolve";
12
12
  import createPostCSSExtractPlugin from "../plugins-postcss/postcss-extract-plugin.js";
13
13
 
14
- export default function cssProcessorPlugin({ outdir = "public" } = {}) {
14
+ export default function cssProcessorPlugin({ outdir = ".dinou/public" } = {}) {
15
15
  const { finalize, plugin: extractor } = createPostCSSExtractPlugin({
16
16
  outputFile: `${outdir}/styles.css`,
17
17
  });
@@ -7,7 +7,7 @@ import parseExports from "../../core/parse-exports.js";
7
7
  import { useClientRegex } from "../../constants.js";
8
8
 
9
9
  export default function reactClientManifestPlugin({
10
- manifestPath = "react_client_manifest/react-client-manifest.json",
10
+ manifestPath = ".dinou/react_client_manifest/react-client-manifest.json",
11
11
  manifest = {},
12
12
  } = {}) {
13
13
  return {
@@ -77,7 +77,7 @@ export default function serverFunctionsPlugin(manifestData = {}) {
77
77
 
78
78
  // Write the server functions manifest JSON file to the output directory
79
79
  const manifestPath = path.join(
80
- "server_functions_manifest",
80
+ ".dinou/server_functions_manifest",
81
81
  "server-functions-manifest.json"
82
82
  );
83
83
  await fs.mkdir(path.dirname(manifestPath), { recursive: true });
@@ -20,7 +20,7 @@ export default function esmHmrPlugin({
20
20
  name: "esm-hmr",
21
21
 
22
22
  setup(build) {
23
- const outdir = build.initialOptions.outdir || "public";
23
+ const outdir = build.initialOptions.outdir || ".dinou/public";
24
24
  const entryPoints = build.initialOptions.entryPoints;
25
25
 
26
26
  const entrySources = [];
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinou-ejected",
3
- "version": "5.1.2",
3
+ "version": "6.0.0",
4
4
  "main": "index.js",
5
5
  "private": true,
6
6
  "exports": {
@@ -39,7 +39,7 @@ function getDefaultExportName(code) {
39
39
 
40
40
  function reactClientManifestPlugin({
41
41
  srcDir = path.resolve("src"),
42
- manifestPath = "react_client_manifest/react-client-manifest.json",
42
+ manifestPath = ".dinou/react_client_manifest/react-client-manifest.json",
43
43
  assetInclude = regex,
44
44
  } = {}) {
45
45
  const manifest = {};
@@ -71,7 +71,7 @@ function serverFunctionsPlugin() {
71
71
 
72
72
  // Write the manifest to the specified folder (e.g. same place as other assets)
73
73
  const manifestPath = path.join(
74
- "server_functions_manifest",
74
+ ".dinou/server_functions_manifest",
75
75
  "server-functions-manifest.json"
76
76
  );
77
77
  try {
@@ -18,7 +18,7 @@ const { regex } = require("../core/asset-extensions.js");
18
18
  const manifestGeneratorPlugin = require("./rollup-plugins/manifest-generator-plugin.js");
19
19
 
20
20
  const isDevelopment = process.env.NODE_ENV !== "production";
21
- const outputDirectory = isDevelopment ? "public" : "dist3";
21
+ const outputDirectory = isDevelopment ? ".dinou/public" : ".dinou/dist3";
22
22
 
23
23
  const localDinouPath = path.resolve(process.cwd(), "dinou");
24
24
  const isEjected = fs.existsSync(localDinouPath);
@@ -96,8 +96,8 @@ module.exports = async function () {
96
96
  del({
97
97
  targets: [
98
98
  `${outputDirectory}/*`,
99
- "react_client_manifest/*",
100
- "server_functions_manifest/*",
99
+ ".dinou/react_client_manifest/*",
100
+ ".dinou/server_functions_manifest/*",
101
101
  ],
102
102
  runOnce: true,
103
103
  hook: "buildStart",
@@ -157,7 +157,7 @@ module.exports = async function () {
157
157
  }),
158
158
  reactClientManifest({
159
159
  manifestPath: path.join(
160
- "react_client_manifest",
160
+ ".dinou/react_client_manifest",
161
161
  "react-client-manifest.json",
162
162
  ),
163
163
  }),
@@ -168,9 +168,9 @@ module.exports = async function () {
168
168
  ].filter(Boolean),
169
169
  watch: {
170
170
  exclude: [
171
- "public/**",
172
- "react_client_manifest/**",
173
- "server_functions_manifest/**",
171
+ ".dinou/public/**",
172
+ ".dinou/react_client_manifest/**",
173
+ ".dinou/server_functions_manifest/**",
174
174
  ],
175
175
  },
176
176
  onwarn(warning, warn) {
@@ -13,7 +13,7 @@ const { regex } = require("../core/asset-extensions");
13
13
  const getCSSEntries = require("./helpers/get-webpack-entries");
14
14
 
15
15
  const isDevelopment = process.env.NODE_ENV !== "production";
16
- const outputDirectory = isDevelopment ? "public" : "dist3";
16
+ const outputDirectory = isDevelopment ? ".dinou/public" : ".dinou/dist3";
17
17
 
18
18
  function getConfigFileIfExists() {
19
19
  const tsconfigPath = path.resolve(process.cwd(), "tsconfig.json");
@@ -39,8 +39,8 @@ console.log(
39
39
  const projectRoot = process.cwd();
40
40
 
41
41
  const outputDirs = [
42
- path.resolve(projectRoot, "public"),
43
- path.resolve(projectRoot, "dist3"),
42
+ path.resolve(projectRoot, ".dinou/public"),
43
+ path.resolve(projectRoot, ".dinou/dist3"),
44
44
  ];
45
45
 
46
46
  function cleanDir(dir) {
@@ -54,7 +54,7 @@ function cleanDir(dir) {
54
54
  } catch (e) {
55
55
  try {
56
56
  fs.rmSync(dir, { recursive: true, force: true });
57
- } catch (err) {}
57
+ } catch (err) { }
58
58
  }
59
59
  }
60
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinou",
3
- "version": "5.1.2",
3
+ "version": "6.0.0",
4
4
  "description": "Lightweight-Ejectable Full-Stack React 19 Framework with support for React Server Components (RSC), Server Functions, Server-Side Rendering (SSR), Static Generation (SSG), Incremental Static Generation (ISG), and Incremental Static Regeneration (ISR)",
5
5
  "main": "index.js",
6
6
  "bin": {