dinou 6.1.0 → 7.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 (135) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/README.md +9461 -1080
  3. package/cli.js +392 -169
  4. package/dinou/adapters/bun.js +62 -0
  5. package/dinou/adapters/cloudflare.js +65 -0
  6. package/dinou/adapters/deno.js +48 -0
  7. package/dinou/adapters/netlify.js +85 -0
  8. package/dinou/adapters/node.mjs +31 -0
  9. package/dinou/bun/build.mjs +1077 -0
  10. package/dinou/cloudflare/build.mjs +1121 -0
  11. package/dinou/cloudflare/shims/child_process.js +14 -0
  12. package/dinou/cloudflare/shims/empty.js +2 -0
  13. package/dinou/cloudflare/shims/fs.js +99 -0
  14. package/dinou/cloudflare/shims/os.js +29 -0
  15. package/dinou/config.js +1 -0
  16. package/dinou/config.mjs +2 -0
  17. package/dinou/constants.js +29 -4
  18. package/dinou/core/babel-esm-loader.js +66 -37
  19. package/dinou/core/bailout-proxy.js +61 -0
  20. package/dinou/core/build-static-pages.js +309 -157
  21. package/dinou/core/cache-revalidate.js +471 -144
  22. package/dinou/core/cache-slot.js +387 -0
  23. package/dinou/core/client-redirect.jsx +12 -7
  24. package/dinou/core/client-webpack.jsx +457 -82
  25. package/dinou/core/client.jsx +452 -82
  26. package/dinou/core/config.js +11 -0
  27. package/dinou/core/dinou-paths.js +52 -0
  28. package/dinou/core/edge-ssr.js +122 -0
  29. package/dinou/core/export-static.mjs +64 -0
  30. package/dinou/core/generate-route-types.js +252 -0
  31. package/dinou/core/generate-static-page.js +55 -94
  32. package/dinou/core/generate-static-rsc.js +47 -15
  33. package/dinou/core/generate-static.js +212 -10
  34. package/dinou/core/generating-isg.js +5 -0
  35. package/dinou/core/get-asset-from-manifest.js +9 -3
  36. package/dinou/core/get-error-jsx.js +221 -41
  37. package/dinou/core/get-file-path-and-dynamic-params.js +9 -13
  38. package/dinou/core/get-jsx.js +172 -95
  39. package/dinou/core/handler.js +2296 -0
  40. package/dinou/core/http-adapter.js +115 -0
  41. package/dinou/core/import-module.js +83 -53
  42. package/dinou/core/layout-functions.js +181 -0
  43. package/dinou/core/link.jsx +18 -6
  44. package/dinou/core/load-dinou-config.js +60 -0
  45. package/dinou/core/manifest-provider.js +261 -0
  46. package/dinou/core/navigation-utils.js +4 -0
  47. package/dinou/core/navigation.js +50 -39
  48. package/dinou/core/parse-exports.js +207 -2
  49. package/dinou/core/ppr-context.js +105 -0
  50. package/dinou/core/ppr-runtime.js +263 -0
  51. package/dinou/core/redirect.jsx +20 -19
  52. package/dinou/core/render-jsx-to-client-jsx.js +133 -15
  53. package/dinou/core/request-context.js +47 -13
  54. package/dinou/core/resolve-module-ppr.js +32 -0
  55. package/dinou/core/revalidating.js +28 -9
  56. package/dinou/core/route-generator.js +107 -0
  57. package/dinou/core/rsc-renderer.js +90 -0
  58. package/dinou/core/run-ssg.js +19 -0
  59. package/dinou/core/scan-dependency-components.js +218 -0
  60. package/dinou/core/server-function-proxy-webpack.js +3 -0
  61. package/dinou/core/server-function-proxy.js +3 -0
  62. package/dinou/core/slot.js +302 -0
  63. package/dinou/core/status-manifest.js +41 -1
  64. package/dinou/core/storage-adapter.js +522 -0
  65. package/dinou/core/url-resolver.js +16 -16
  66. package/dinou/core/vfs.js +139 -68
  67. package/dinou/deno/build.mjs +1112 -0
  68. package/dinou/deno/seed-kv.js +115 -0
  69. package/dinou/esbuild/build.mjs +51 -1
  70. package/dinou/esbuild/dev.mjs +290 -224
  71. package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +3 -2
  72. package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +104 -16
  73. package/dinou/esbuild/helpers-esbuild/get-esbuild-entries.mjs +31 -19
  74. package/dinou/esbuild/helpers-esbuild/strip-namespace.mjs +9 -0
  75. package/dinou/esbuild/helpers-esbuild/swc-disk-cache.mjs +225 -0
  76. package/dinou/esbuild/helpers-esbuild/update-manifest-for-module.mjs +7 -0
  77. package/dinou/esbuild/helpers-esbuild/write.mjs +111 -2
  78. package/dinou/esbuild/plugins-esbuild/assets-plugin.mjs +236 -161
  79. package/dinou/esbuild/plugins-esbuild/css-processor-plugin.mjs +101 -5
  80. package/dinou/esbuild/plugins-esbuild/react-client-manifest-plugin.mjs +63 -24
  81. package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +177 -56
  82. package/dinou/esbuild/plugins-esbuild/skip-missing-entry-points-plugin.mjs +3 -0
  83. package/dinou/esbuild/plugins-esbuild/stable-chunk-names-and-maps-plugin.mjs +182 -137
  84. package/dinou/esbuild/plugins-postcss/postcss-extract-plugin.js +38 -11
  85. package/dinou/esbuild/react-refresh/esm-hmr/client.mjs +55 -8
  86. package/dinou/esbuild/react-refresh/esm-hmr/server.js +1 -1
  87. package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +238 -101
  88. package/dinou/esbuild/react-refresh/is-react-refresh-boundary.mjs +18 -4
  89. package/dinou/index.d.ts +315 -11
  90. package/dinou/index.js +12 -6
  91. package/dinou/index.mjs +9 -0
  92. package/dinou/node/build.mjs +195 -0
  93. package/dinou/node/bundle-dual-engine.mjs +1012 -0
  94. package/dinou/node/dev.mjs +2589 -0
  95. package/dinou/node/port-selector.mjs +164 -0
  96. package/dinou/node/terminal-status.mjs +345 -0
  97. package/dinou/package.json +17 -14
  98. package/dinou/rollup/react-refresh/esm-hmr/client.js +66 -10
  99. package/dinou/rollup/react-refresh/esm-hmr/server.js +1 -1
  100. package/dinou/rollup/react-refresh/is-react-refresh-boundary.js +24 -5
  101. package/dinou/rollup/react-refresh/react-refresh-runtime.js +13 -6
  102. package/dinou/rollup/react-refresh/react-refresh-wrap-modules.js +56 -11
  103. package/dinou/rollup/react-refresh/rollup-plugin-esm-hmr.js +176 -48
  104. package/dinou/rollup/rollup-plugins/dinou-asset-plugin.js +9 -5
  105. package/dinou/rollup/rollup-plugins/rollup-plugin-memory.js +66 -0
  106. package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +468 -123
  107. package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +44 -12
  108. package/dinou/rollup/rollup-plugins/rollup-plugin-swc.js +100 -0
  109. package/dinou/rollup/rollup.config.js +155 -43
  110. package/dinou/server.d.ts +114 -12
  111. package/dinou/server.js +35 -10
  112. package/dinou/server.mjs +30 -9
  113. package/dinou/webpack/helpers/get-webpack-entries.js +14 -19
  114. package/dinou/webpack/loaders/server-functions-loader.js +22 -1
  115. package/dinou/webpack/loaders/swc-loader.js +76 -0
  116. package/dinou/webpack/plugins/manifest-generator-plugin.js +1 -0
  117. package/dinou/webpack/plugins/server-functions-plugin.js +75 -19
  118. package/dinou/webpack/plugins/webpack-memory-plugin.js +66 -0
  119. package/dinou/webpack/webpack.config.js +227 -29
  120. package/eject.js +173 -94
  121. package/package.json +110 -107
  122. package/dinou/core/asset-require-hook.js +0 -58
  123. package/dinou/core/client-error-webpack.jsx +0 -432
  124. package/dinou/core/client-error.jsx +0 -432
  125. package/dinou/core/concurrency-manager.js +0 -48
  126. package/dinou/core/context-proxy.js +0 -68
  127. package/dinou/core/generate-static-pages.js +0 -130
  128. package/dinou/core/generate-static-rscs.js +0 -151
  129. package/dinou/core/get-ssg-metadata.js +0 -31
  130. package/dinou/core/register-loader.mjs +0 -11
  131. package/dinou/core/register-paths.js +0 -27
  132. package/dinou/core/render-app-to-html.js +0 -430
  133. package/dinou/core/render-html.js +0 -407
  134. package/dinou/core/server.js +0 -1542
  135. package/dinou/esbuild/plugins-esbuild/write-metafile-plugin.mjs +0 -16
@@ -6,16 +6,67 @@ const {
6
6
  } = require("./get-file-path-and-dynamic-params");
7
7
  const importModule = require("./import-module");
8
8
  const { asyncRenderJSXToClientJSX } = require("./render-jsx-to-client-jsx");
9
+ const { getLayoutProps } = require("./layout-functions");
9
10
 
10
- async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
11
+ function cleanErrorStack(stack) {
12
+ if (!stack || typeof stack !== "string") return "";
13
+ const lines = stack.split("\n");
14
+ const filtered = [];
15
+
16
+ for (const line of lines) {
17
+ if (!line.trim().startsWith("at ")) {
18
+ filtered.push(line);
19
+ continue;
20
+ }
21
+
22
+ // Filter out client Flight / bundler runtime internals
23
+ if (
24
+ line.includes("resolveErrorDev") ||
25
+ line.includes("resolveErrorModel") ||
26
+ line.includes("processFullStringRow") ||
27
+ line.includes("processFullBinaryRow") ||
28
+ line.includes("processBinaryChunk") ||
29
+ line.includes("buildFakeCallStack") ||
30
+ line.includes("createFakeFunction") ||
31
+ line.includes("initializeFakeTask") ||
32
+ line.includes("getRootTask") ||
33
+ line.includes("progress (http") ||
34
+ line.includes("__hmr_client__") ||
35
+ (line.includes("http://") && line.includes("/chunk-"))
36
+ ) {
37
+ continue;
38
+ }
39
+
40
+ // Filter out server engine / Node internals
41
+ if (
42
+ line.includes("node_modules/@roggc/react-server-dom-esm") ||
43
+ line.includes("node_modules/react-dom") ||
44
+ line.includes("node_modules/react/") ||
45
+ line.includes("node:internal") ||
46
+ line.includes("asyncRenderJSXToClientJSX") ||
47
+ line.includes("renderModelDestructive") ||
48
+ line.includes("renderHtmlStream") ||
49
+ line.includes("pipeRSC")
50
+ ) {
51
+ continue;
52
+ }
53
+
54
+ filtered.push(line);
55
+ }
56
+
57
+ return (filtered.length > 0 ? filtered : lines).join("\n").trim();
58
+ }
59
+
60
+ async function getErrorJSX(reqPath, query, error, isDevelopment = false, options = {}) {
11
61
  const srcFolder = path.resolve(process.cwd(), "src");
12
62
  const reqSegments = reqPath.split("/").filter(Boolean);
13
63
  const hasRouterSyntax = reqSegments.some((seg) => {
14
64
  const isGroup = seg.startsWith("(") && seg.endsWith(")");
15
65
  const isDynamic = seg.startsWith("[") && seg.endsWith("]");
16
66
  const isSlot = seg.startsWith("@");
67
+ const isPrivate = seg.startsWith("_");
17
68
 
18
- return isGroup || isDynamic || isSlot;
69
+ return isGroup || isDynamic || isSlot || isPrivate;
19
70
  });
20
71
 
21
72
  let pagePath;
@@ -61,64 +112,140 @@ async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
61
112
  }
62
113
  }
63
114
 
64
- if (pagePath) {
115
+ if (!pagePath) {
116
+ const isDev = isDevelopment;
117
+ jsx = React.createElement(
118
+ "div",
119
+ {
120
+ style: {
121
+ fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
122
+ padding: "32px",
123
+ maxWidth: "960px",
124
+ margin: "40px auto",
125
+ backgroundColor: "#fff1f2",
126
+ border: "1px solid #fecdd3",
127
+ borderRadius: "12px",
128
+ color: "#9f1239",
129
+ boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.1)",
130
+ },
131
+ },
132
+ React.createElement(
133
+ "div",
134
+ { style: { display: "flex", alignItems: "center", gap: "10px", marginBottom: "12px" } },
135
+ React.createElement("span", { style: { background: "#e11d48", color: "white", padding: "2px 8px", borderRadius: "9999px", fontSize: "12px", fontWeight: "bold" } }, isDev ? "Dinou Dev Error" : "Application Error"),
136
+ React.createElement("h2", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 700, color: "#881337" } }, error?.message || "Unhandled Application Error")
137
+ ),
138
+ isDev && React.createElement(
139
+ "p",
140
+ { style: { margin: "0 0 16px 0", fontSize: "0.875rem", color: "#9f1239", lineHeight: 1.5 } },
141
+ "An unhandled error occurred during rendering. You can provide a custom error UI by creating an ",
142
+ React.createElement("code", { style: { background: "#ffe4e6", padding: "2px 6px", borderRadius: "4px", fontWeight: 600 } }, "error.tsx"),
143
+ " file in your route folder."
144
+ ),
145
+ isDev && error?.stack && React.createElement(
146
+ "pre",
147
+ {
148
+ style: {
149
+ background: "#0f172a",
150
+ color: "#f8fafc",
151
+ padding: "16px",
152
+ borderRadius: "8px",
153
+ overflowX: "auto",
154
+ fontSize: "0.8125rem",
155
+ lineHeight: 1.6,
156
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
157
+ },
158
+ },
159
+ error.stack
160
+ )
161
+ );
162
+ } else {
65
163
  const pageModule = await importModule(pagePath);
66
164
  const Page = pageModule.default ?? pageModule;
165
+ const sanitizedError = {
166
+ ...(typeof error === "object" && error !== null ? error : {}),
167
+ message: isDevelopment
168
+ ? (error?.message || "Unknown Error")
169
+ : (error?.message && !error.stack ? error.message : "An error occurred in the Server Components render"),
170
+ name: error?.name || "Error",
171
+ stack: isDevelopment ? error?.stack : undefined,
172
+ };
67
173
  jsx = React.createElement(Page, {
68
174
  params: dynamicParams ?? {},
69
- error,
175
+ error: sanitizedError,
70
176
  });
177
+ }
71
178
 
72
- const noLayoutErrorPath = path.join(
73
- path.dirname(pagePath),
74
- `no_layout_error`
75
- );
76
- if (existsSync(noLayoutErrorPath)) {
77
- return jsx;
78
- }
179
+ // Segmented handling for Page: If only the error for the page slot is requested
180
+ if (options && options.segment === "page") {
181
+ return jsx;
182
+ }
79
183
 
80
- if (
81
- getFilePathAndDynamicParams(
82
- reqSegments,
83
- query,
84
- srcFolder,
85
- "no_layout",
86
- false
87
- )[0]
88
- ) {
89
- return jsx;
90
- }
184
+ const noLayoutErrorPath = pagePath
185
+ ? path.join(path.dirname(pagePath), "no_layout_error")
186
+ : null;
187
+ if (noLayoutErrorPath && existsSync(noLayoutErrorPath)) {
188
+ return jsx;
189
+ }
91
190
 
92
- const layouts = getFilePathAndDynamicParams(
191
+ if (
192
+ getFilePathAndDynamicParams(
93
193
  reqSegments,
94
194
  query,
95
195
  srcFolder,
96
- "layout",
97
- true,
98
- false,
99
- undefined,
100
- 0,
101
- {},
102
- true
103
- );
196
+ "no_layout",
197
+ false
198
+ )[0]
199
+ ) {
200
+ return jsx;
201
+ }
104
202
 
203
+ const layouts = getFilePathAndDynamicParams(
204
+ reqSegments,
205
+ query,
206
+ srcFolder,
207
+ "layout",
208
+ true,
209
+ false,
210
+ undefined,
211
+ 0,
212
+ {},
213
+ true
214
+ );
215
+
216
+ const baseErrorJsx = jsx;
217
+ let layoutApplied = false;
218
+ let appliedLayoutKey = null;
105
219
  if (layouts && Array.isArray(layouts)) {
220
+ const reversedLayouts = [...layouts].reverse();
221
+ let outermostLayoutApplied = false;
106
222
  let index = 0;
107
- for (const [layoutPath, dParams, slots] of layouts.reverse()) {
223
+ for (const [layoutPath, dParams, slots] of reversedLayouts) {
108
224
  const layoutModule = await importModule(layoutPath);
109
225
  const Layout = layoutModule.default ?? layoutModule;
110
226
  const updatedSlots = {};
111
- for (const [slotName, slotElement] of Object.entries(slots)) {
227
+ for (const [slotName, slotValue] of Object.entries(slots)) {
112
228
  let updatedSlotElement;
229
+ const slotFilePath = slotValue?.slotPath || slotValue?.props?.__modulePath;
230
+ const slotParams = slotValue?.slotParams || slotValue?.props?.params || {};
113
231
  try {
114
- await asyncRenderJSXToClientJSX(slotElement);
115
- updatedSlotElement = slotElement;
232
+ let elementToRender;
233
+ if (slotValue && slotValue.slotPath) {
234
+ const slotModule = await importModule(slotValue.slotPath);
235
+ const Slot = slotModule.default ?? slotModule;
236
+ elementToRender = React.createElement(Slot, {
237
+ params: slotParams,
238
+ key: slotName,
239
+ __modulePath: slotValue.slotPath,
240
+ });
241
+ } else {
242
+ elementToRender = slotValue;
243
+ }
244
+ await asyncRenderJSXToClientJSX(elementToRender);
245
+ updatedSlotElement = elementToRender;
116
246
  } catch (e) {
117
247
  // 1. RECOVER THE REAL PATH
118
- // We use the "hack" (metadata) that we inject in getSlots.
119
- // This gives us the path to the file: .../src/(group)/@sidebar/page.tsx
120
- const slotFilePath = slotElement.props?.__modulePath;
121
-
248
+ // Gives us the path to the file: .../src/(group)/@sidebar/page.tsx
122
249
  if (slotFilePath) {
123
250
  // 2. GET THE SLOT FOLDER
124
251
  // Remove the file name to stay with the directory:
@@ -144,7 +271,9 @@ async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
144
271
  const SlotError = slotErrorModule.default ?? slotErrorModule;
145
272
 
146
273
  const serializedError = {
147
- message: e.message || "Unknown Error",
274
+ message: isDevelopment
275
+ ? (e.message || "Unknown Error")
276
+ : "An error occurred in the Server Components render",
148
277
  name: e.name,
149
278
  stack: isDevelopment ? e.stack : undefined,
150
279
  };
@@ -172,11 +301,29 @@ async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
172
301
  updatedSlots[slotName] = updatedSlotElement;
173
302
  }
174
303
  }
304
+ const layoutProps = await getLayoutProps(layoutPath, dParams);
175
305
  let props = {
176
306
  params: dParams,
177
307
  ...updatedSlots,
308
+ ...(layoutProps ?? {}),
178
309
  };
179
- jsx = React.createElement(Layout, props, jsx);
310
+ try {
311
+ const testElement = React.createElement(Layout, props, jsx);
312
+ await asyncRenderJSXToClientJSX(testElement);
313
+ jsx = testElement;
314
+ layoutApplied = true;
315
+ outermostLayoutApplied = true;
316
+ if (!appliedLayoutKey) {
317
+ const relDir = path.relative(srcFolder, path.dirname(layoutPath)).replace(/\\/g, "/");
318
+ appliedLayoutKey = relDir === "" ? "/" : "/" + relDir;
319
+ }
320
+ } catch (layoutErr) {
321
+ console.warn(
322
+ `[Dinou] Layout ${layoutPath} failed during error recovery, skipping this layout:`,
323
+ layoutErr?.message || layoutErr
324
+ );
325
+ outermostLayoutApplied = false;
326
+ }
180
327
  const layoutFolderPath = path.dirname(layoutPath);
181
328
  if (
182
329
  getFilePathAndDynamicParams(
@@ -191,7 +338,40 @@ async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
191
338
  }
192
339
  index++;
193
340
  }
341
+
342
+ // If the outermost (root) layout in this branch failed to apply, the layout chain cannot
343
+ // provide a root document shell (<html>/<body>) and client hydration cannot succeed.
344
+ // Revert to the standalone error JSX and mark hasLayout as false.
345
+ if (!outermostLayoutApplied) {
346
+ jsx = baseErrorJsx;
347
+ layoutApplied = false;
348
+ appliedLayoutKey = null;
349
+ }
194
350
  }
351
+
352
+ if (options) {
353
+ options.hasLayout = layoutApplied;
354
+ options.appliedLayoutKey = appliedLayoutKey;
355
+ }
356
+
357
+ const hasHtml = jsx?.type === "html" || (Array.isArray(jsx) && jsx.some((c) => c?.type === "html"));
358
+ if (!layoutApplied && !hasHtml) {
359
+ jsx = React.createElement(
360
+ "html",
361
+ { lang: "en" },
362
+ React.createElement(
363
+ "head",
364
+ null,
365
+ React.createElement("meta", { charSet: "UTF-8" }),
366
+ React.createElement("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
367
+ React.createElement("title", null, isDevelopment ? "Dinou Dev Error" : "Application Error")
368
+ ),
369
+ React.createElement(
370
+ "body",
371
+ { style: { margin: 0, background: "#fff1f2", padding: "20px" } },
372
+ jsx
373
+ )
374
+ );
195
375
  }
196
376
 
197
377
  return jsx;
@@ -1,6 +1,5 @@
1
1
  const path = require("path");
2
2
  const { existsSync, readdirSync } = require("./vfs");
3
- const React = require("react");
4
3
 
5
4
  function safeDecode(val) {
6
5
  try {
@@ -16,7 +15,7 @@ function getSlots(currentPath, reqSegments, query) {
16
15
  const entries = readdirSync(currentPath, { withFileTypes: true });
17
16
 
18
17
  for (const entry of entries) {
19
- if (!entry.isDirectory()) continue;
18
+ if (!entry.isDirectory() || entry.name.startsWith("_")) continue;
20
19
 
21
20
  if (entry.name.startsWith("@")) {
22
21
  const [slotPath, slotParams] = getFilePathAndDynamicParams(
@@ -31,15 +30,11 @@ function getSlots(currentPath, reqSegments, query) {
31
30
  );
32
31
 
33
32
  if (slotPath) {
34
- const slotModule = require(slotPath);
35
- const Slot = slotModule.default ?? slotModule;
36
33
  const slotName = entry.name.slice(1);
37
-
38
- slots[slotName] = React.createElement(Slot, {
39
- params: slotParams,
40
- key: slotName,
41
- __modulePath: slotPath ?? null,
42
- });
34
+ slots[slotName] = {
35
+ slotPath,
36
+ slotParams,
37
+ };
43
38
  }
44
39
  } else if (entry.name.startsWith("(") && entry.name.endsWith(")")) {
45
40
  const groupPath = path.join(currentPath, entry.name);
@@ -112,7 +107,7 @@ function getFilePathAndDynamicParams(
112
107
  if (index > reqSegments.length - 1) {
113
108
  const entries = readdirSync(currentPath, { withFileTypes: true });
114
109
  for (const entry of entries) {
115
- if (entry.isDirectory()) {
110
+ if (entry.isDirectory() && !entry.name.startsWith("_")) {
116
111
  if (entry.name.startsWith("[[...") && entry.name.endsWith("]]")) {
117
112
  const paramName = entry.name.slice(5, -2);
118
113
  const paramValue =
@@ -252,7 +247,8 @@ function getFilePathAndDynamicParams(
252
247
  ((reqSegments[index].startsWith("(") && reqSegments[index].endsWith(")")) ||
253
248
  (reqSegments[index].startsWith("[") &&
254
249
  reqSegments[index].endsWith("]")) ||
255
- reqSegments[index].startsWith("@"));
250
+ reqSegments[index].startsWith("@") ||
251
+ reqSegments[index].startsWith("_"));
256
252
  if (existsSync(staticPath) && !isRouterSyntaxInSegment) {
257
253
  return getFilePathAndDynamicParams(
258
254
  reqSegments,
@@ -271,7 +267,7 @@ function getFilePathAndDynamicParams(
271
267
  } else {
272
268
  const entries = readdirSync(currentPath, { withFileTypes: true });
273
269
  for (const entry of entries) {
274
- if (entry.isDirectory()) {
270
+ if (entry.isDirectory() && !entry.name.startsWith("_")) {
275
271
  if (entry.name.startsWith("[[...") && entry.name.endsWith("]]")) {
276
272
  const paramName = entry.name.slice(5, -2);
277
273
  const paramValue =