dinou 6.1.1 → 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.
- package/CHANGELOG.md +94 -0
- package/README.md +9461 -1080
- package/cli.js +392 -169
- package/dinou/adapters/bun.js +62 -0
- package/dinou/adapters/cloudflare.js +65 -0
- package/dinou/adapters/deno.js +48 -0
- package/dinou/adapters/netlify.js +85 -0
- package/dinou/adapters/node.mjs +31 -0
- package/dinou/bun/build.mjs +1077 -0
- package/dinou/cloudflare/build.mjs +1121 -0
- package/dinou/cloudflare/shims/child_process.js +14 -0
- package/dinou/cloudflare/shims/empty.js +2 -0
- package/dinou/cloudflare/shims/fs.js +99 -0
- package/dinou/cloudflare/shims/os.js +29 -0
- package/dinou/config.js +1 -0
- package/dinou/config.mjs +2 -0
- package/dinou/constants.js +29 -4
- package/dinou/core/babel-esm-loader.js +66 -37
- package/dinou/core/bailout-proxy.js +61 -0
- package/dinou/core/build-static-pages.js +309 -157
- package/dinou/core/cache-revalidate.js +471 -144
- package/dinou/core/cache-slot.js +387 -0
- package/dinou/core/client-redirect.jsx +12 -7
- package/dinou/core/client-webpack.jsx +457 -82
- package/dinou/core/client.jsx +452 -82
- package/dinou/core/config.js +11 -0
- package/dinou/core/dinou-paths.js +52 -0
- package/dinou/core/edge-ssr.js +122 -0
- package/dinou/core/export-static.mjs +64 -0
- package/dinou/core/generate-route-types.js +252 -0
- package/dinou/core/generate-static-page.js +55 -94
- package/dinou/core/generate-static-rsc.js +47 -15
- package/dinou/core/generate-static.js +212 -10
- package/dinou/core/generating-isg.js +5 -0
- package/dinou/core/get-asset-from-manifest.js +9 -3
- package/dinou/core/get-error-jsx.js +221 -41
- package/dinou/core/get-file-path-and-dynamic-params.js +9 -13
- package/dinou/core/get-jsx.js +172 -95
- package/dinou/core/handler.js +2296 -0
- package/dinou/core/http-adapter.js +115 -0
- package/dinou/core/import-module.js +83 -53
- package/dinou/core/layout-functions.js +181 -0
- package/dinou/core/link.jsx +18 -6
- package/dinou/core/load-dinou-config.js +60 -0
- package/dinou/core/manifest-provider.js +261 -0
- package/dinou/core/navigation-utils.js +4 -0
- package/dinou/core/navigation.js +50 -39
- package/dinou/core/parse-exports.js +207 -2
- package/dinou/core/ppr-context.js +105 -0
- package/dinou/core/ppr-runtime.js +263 -0
- package/dinou/core/redirect.jsx +20 -19
- package/dinou/core/render-jsx-to-client-jsx.js +133 -15
- package/dinou/core/request-context.js +47 -13
- package/dinou/core/resolve-module-ppr.js +32 -0
- package/dinou/core/revalidating.js +28 -9
- package/dinou/core/route-generator.js +107 -0
- package/dinou/core/rsc-renderer.js +90 -0
- package/dinou/core/run-ssg.js +19 -0
- package/dinou/core/scan-dependency-components.js +218 -0
- package/dinou/core/server-function-proxy-webpack.js +3 -0
- package/dinou/core/server-function-proxy.js +3 -0
- package/dinou/core/slot.js +302 -0
- package/dinou/core/status-manifest.js +41 -1
- package/dinou/core/storage-adapter.js +522 -0
- package/dinou/core/url-resolver.js +16 -16
- package/dinou/core/vfs.js +139 -68
- package/dinou/deno/build.mjs +1112 -0
- package/dinou/deno/seed-kv.js +115 -0
- package/dinou/esbuild/build.mjs +51 -1
- package/dinou/esbuild/dev.mjs +290 -224
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +3 -2
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +104 -16
- package/dinou/esbuild/helpers-esbuild/get-esbuild-entries.mjs +31 -19
- package/dinou/esbuild/helpers-esbuild/strip-namespace.mjs +9 -0
- package/dinou/esbuild/helpers-esbuild/swc-disk-cache.mjs +225 -0
- package/dinou/esbuild/helpers-esbuild/update-manifest-for-module.mjs +7 -0
- package/dinou/esbuild/helpers-esbuild/write.mjs +111 -2
- package/dinou/esbuild/plugins-esbuild/assets-plugin.mjs +236 -161
- package/dinou/esbuild/plugins-esbuild/css-processor-plugin.mjs +101 -5
- package/dinou/esbuild/plugins-esbuild/react-client-manifest-plugin.mjs +63 -24
- package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +177 -56
- package/dinou/esbuild/plugins-esbuild/skip-missing-entry-points-plugin.mjs +3 -0
- package/dinou/esbuild/plugins-esbuild/stable-chunk-names-and-maps-plugin.mjs +182 -137
- package/dinou/esbuild/plugins-postcss/postcss-extract-plugin.js +38 -11
- package/dinou/esbuild/react-refresh/esm-hmr/client.mjs +55 -8
- package/dinou/esbuild/react-refresh/esm-hmr/server.js +1 -1
- package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +238 -101
- package/dinou/esbuild/react-refresh/is-react-refresh-boundary.mjs +18 -4
- package/dinou/index.d.ts +315 -11
- package/dinou/index.js +12 -6
- package/dinou/index.mjs +9 -0
- package/dinou/node/build.mjs +195 -0
- package/dinou/node/bundle-dual-engine.mjs +1012 -0
- package/dinou/node/dev.mjs +2589 -0
- package/dinou/node/port-selector.mjs +164 -0
- package/dinou/node/terminal-status.mjs +345 -0
- package/dinou/package.json +16 -14
- package/dinou/rollup/react-refresh/esm-hmr/client.js +66 -10
- package/dinou/rollup/react-refresh/esm-hmr/server.js +1 -1
- package/dinou/rollup/react-refresh/is-react-refresh-boundary.js +24 -5
- package/dinou/rollup/react-refresh/react-refresh-runtime.js +13 -6
- package/dinou/rollup/react-refresh/react-refresh-wrap-modules.js +56 -11
- package/dinou/rollup/react-refresh/rollup-plugin-esm-hmr.js +176 -48
- package/dinou/rollup/rollup-plugins/dinou-asset-plugin.js +9 -5
- package/dinou/rollup/rollup-plugins/rollup-plugin-memory.js +66 -0
- package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +468 -123
- package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +44 -12
- package/dinou/rollup/rollup-plugins/rollup-plugin-swc.js +100 -0
- package/dinou/rollup/rollup.config.js +155 -43
- package/dinou/server.d.ts +114 -12
- package/dinou/server.js +35 -10
- package/dinou/server.mjs +30 -9
- package/dinou/webpack/helpers/get-webpack-entries.js +14 -19
- package/dinou/webpack/loaders/server-functions-loader.js +22 -1
- package/dinou/webpack/loaders/swc-loader.js +76 -0
- package/dinou/webpack/plugins/manifest-generator-plugin.js +1 -0
- package/dinou/webpack/plugins/server-functions-plugin.js +75 -19
- package/dinou/webpack/plugins/webpack-memory-plugin.js +66 -0
- package/dinou/webpack/webpack.config.js +227 -29
- package/eject.js +173 -94
- package/package.json +110 -108
- package/dinou/core/asset-require-hook.js +0 -58
- package/dinou/core/client-error-webpack.jsx +0 -432
- package/dinou/core/client-error.jsx +0 -432
- package/dinou/core/concurrency-manager.js +0 -48
- package/dinou/core/context-proxy.js +0 -68
- package/dinou/core/generate-static-pages.js +0 -130
- package/dinou/core/generate-static-rscs.js +0 -151
- package/dinou/core/get-ssg-metadata.js +0 -31
- package/dinou/core/register-loader.mjs +0 -11
- package/dinou/core/register-paths.js +0 -27
- package/dinou/core/render-app-to-html.js +0 -430
- package/dinou/core/render-html.js +0 -407
- package/dinou/core/server.js +0 -1542
- 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
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
191
|
+
if (
|
|
192
|
+
getFilePathAndDynamicParams(
|
|
93
193
|
reqSegments,
|
|
94
194
|
query,
|
|
95
195
|
srcFolder,
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
115
|
-
|
|
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
|
-
//
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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 =
|