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
|
@@ -7,9 +7,60 @@ const {
|
|
|
7
7
|
} = require("./get-file-path-and-dynamic-params");
|
|
8
8
|
const importModule = require("./import-module");
|
|
9
9
|
const { requestStorage } = require("./request-context.js");
|
|
10
|
+
const { getLayoutProps, resolveLayoutFunctionsConfig } = require("./layout-functions");
|
|
11
|
+
const { runWithPprContext, getRegisteredHoles } = require("./ppr-context.js");
|
|
12
|
+
const { resolveModulePpr } = require("./resolve-module-ppr");
|
|
13
|
+
const { getDinouConfig } = require("./load-dinou-config");
|
|
14
|
+
|
|
15
|
+
async function resolveBuildPprForRoute(segments, pagePath, pageFunctionsPath, srcFolder) {
|
|
16
|
+
const globalCfg = await getDinouConfig();
|
|
17
|
+
let inheritedPpr = Boolean(globalCfg?.ppr);
|
|
18
|
+
try {
|
|
19
|
+
const parentLayouts = getFilePathAndDynamicParams(
|
|
20
|
+
segments || [],
|
|
21
|
+
{},
|
|
22
|
+
srcFolder,
|
|
23
|
+
"layout",
|
|
24
|
+
true,
|
|
25
|
+
false,
|
|
26
|
+
undefined,
|
|
27
|
+
0,
|
|
28
|
+
{},
|
|
29
|
+
true
|
|
30
|
+
);
|
|
31
|
+
if (parentLayouts && Array.isArray(parentLayouts)) {
|
|
32
|
+
for (const [lPath, lParams] of parentLayouts) {
|
|
33
|
+
const lConfig = await resolveLayoutFunctionsConfig(lPath, lParams);
|
|
34
|
+
if (lConfig && lConfig.ppr !== null && lConfig.ppr !== undefined) {
|
|
35
|
+
inheritedPpr = Boolean(lConfig.ppr);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
} catch (e) {}
|
|
40
|
+
|
|
41
|
+
let explicitPagePpr = null;
|
|
42
|
+
if (pageFunctionsPath) {
|
|
43
|
+
try {
|
|
44
|
+
const module = await importModule(pageFunctionsPath);
|
|
45
|
+
explicitPagePpr = await resolveModulePpr(module);
|
|
46
|
+
} catch (e) {}
|
|
47
|
+
}
|
|
48
|
+
if (explicitPagePpr === null && typeof globalThis !== "undefined" && globalThis.__DINOU_ROUTE_METADATA__) {
|
|
49
|
+
const normKey = pageFunctionsPath ? pageFunctionsPath.replace(/\\/g, "/") : "";
|
|
50
|
+
for (const [k, meta] of Object.entries(globalThis.__DINOU_ROUTE_METADATA__)) {
|
|
51
|
+
if (meta.ppr !== undefined && (normKey === k || normKey.endsWith("/" + k) || normKey.endsWith(k))) {
|
|
52
|
+
explicitPagePpr = Boolean(meta.ppr);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return explicitPagePpr !== null ? explicitPagePpr : inheritedPpr;
|
|
59
|
+
}
|
|
10
60
|
|
|
11
61
|
const staticRoutes = new Set();
|
|
12
62
|
const staticMetadata = new Map();
|
|
63
|
+
const staticLayouts = new Map();
|
|
13
64
|
|
|
14
65
|
function safeDecode(val) {
|
|
15
66
|
try {
|
|
@@ -19,65 +70,21 @@ function safeDecode(val) {
|
|
|
19
70
|
}
|
|
20
71
|
}
|
|
21
72
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* @param {Function} onBailout - Callback to execute when access is detected
|
|
27
|
-
*/
|
|
28
|
-
function createBailoutProxy(target, label, onBailout) {
|
|
29
|
-
// If there is no target, use an empty object to avoid crashes,
|
|
30
|
-
// but ideally pass whatever you have.
|
|
31
|
-
const safeTarget = target || {};
|
|
32
|
-
|
|
33
|
-
return new Proxy(safeTarget, {
|
|
34
|
-
get(t, prop, receiver) {
|
|
35
|
-
// Ignore internal Node/Console symbols
|
|
36
|
-
if (
|
|
37
|
-
typeof prop === "symbol" ||
|
|
38
|
-
prop === "inspect" ||
|
|
39
|
-
prop === "valueOf" ||
|
|
40
|
-
prop === "toString" // Sometimes useful to ignore
|
|
41
|
-
) {
|
|
42
|
-
return Reflect.get(t, prop, receiver);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// 🚨 ALARM: Access detected
|
|
46
|
-
console.log(
|
|
47
|
-
`[StaticBailout] Access to ${label} detected: "${String(prop)}".`,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
// Execute logic to mark as dynamic
|
|
51
|
-
onBailout();
|
|
52
|
-
|
|
53
|
-
// IMPORTANT: Return the real value of the original object
|
|
54
|
-
return Reflect.get(t, prop, receiver);
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
ownKeys(t) {
|
|
58
|
-
console.log(`[StaticBailout] Iteration of ${label} detected.`);
|
|
59
|
-
onBailout();
|
|
60
|
-
return Reflect.ownKeys(t);
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
// Optional: Detect if they try to ask "prop in headers"
|
|
64
|
-
has(t, prop) {
|
|
65
|
-
console.log(
|
|
66
|
-
`[StaticBailout] Existence check (IN) in ${label}: "${String(prop)}".`,
|
|
67
|
-
);
|
|
68
|
-
onBailout();
|
|
69
|
-
return Reflect.has(t, prop);
|
|
70
|
-
},
|
|
71
|
-
});
|
|
73
|
+
async function isDynamicRoute(revalidate) {
|
|
74
|
+
if (revalidate === undefined || revalidate === false) return false;
|
|
75
|
+
const val = typeof revalidate === "function" ? await revalidate() : revalidate;
|
|
76
|
+
return typeof val === "number" && val < 1;
|
|
72
77
|
}
|
|
73
78
|
|
|
79
|
+
const { createBailoutProxy } = require("./bailout-proxy.js");
|
|
80
|
+
|
|
74
81
|
/**
|
|
75
82
|
* Compiles all static pages in the application.
|
|
76
83
|
* Crawls the "src/" folder to collect all routes, resolves dynamic path segments,
|
|
77
84
|
* mock-renders them inside a server context, and serializes successful static renders
|
|
78
85
|
* into RSC JSON payloads.
|
|
79
86
|
*/
|
|
80
|
-
async function buildStaticPages() {
|
|
87
|
+
async function buildStaticPages(onProgress = null) {
|
|
81
88
|
const srcFolder = path.resolve(process.cwd(), "src");
|
|
82
89
|
|
|
83
90
|
/**
|
|
@@ -95,8 +102,32 @@ async function buildStaticPages() {
|
|
|
95
102
|
const entries = readdirSync(currentPath, { withFileTypes: true });
|
|
96
103
|
const pages = [];
|
|
97
104
|
|
|
105
|
+
// 🛡️ Descubrir layout en esta carpeta si existe
|
|
106
|
+
const layoutExtensions = [".tsx", ".jsx", ".ts", ".js"];
|
|
107
|
+
for (const ext of layoutExtensions) {
|
|
108
|
+
const candidateLayout = path.join(currentPath, `layout${ext}`);
|
|
109
|
+
if (existsSync(candidateLayout)) {
|
|
110
|
+
const routePath = segments.length ? "/" + segments.join("/") : "/";
|
|
111
|
+
const { resolveLayoutFunctionsConfig } = require("./layout-functions");
|
|
112
|
+
const layoutConfig = await resolveLayoutFunctionsConfig(candidateLayout, params);
|
|
113
|
+
if (!layoutConfig.isDynamic) {
|
|
114
|
+
staticLayouts.set(routePath, {
|
|
115
|
+
folderPath: currentPath,
|
|
116
|
+
layoutPath: candidateLayout,
|
|
117
|
+
routePath,
|
|
118
|
+
segments,
|
|
119
|
+
params,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
98
126
|
for (const entry of entries) {
|
|
99
127
|
if (entry.isDirectory()) {
|
|
128
|
+
if (entry.name.startsWith("_")) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
100
131
|
if (entry.name.startsWith("(") && entry.name.endsWith(")")) {
|
|
101
132
|
pages.push(
|
|
102
133
|
...(await collectPages(
|
|
@@ -134,22 +165,26 @@ async function buildStaticPages() {
|
|
|
134
165
|
segments.length,
|
|
135
166
|
);
|
|
136
167
|
|
|
137
|
-
let
|
|
168
|
+
let revalidate, getStaticPaths;
|
|
138
169
|
if (pageFunctionsPath) {
|
|
139
170
|
const module = await importModule(pageFunctionsPath);
|
|
140
171
|
getStaticPaths = module.getStaticPaths;
|
|
141
|
-
|
|
172
|
+
revalidate = module.revalidate;
|
|
142
173
|
}
|
|
143
174
|
const isLocalPage =
|
|
144
175
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
145
|
-
if (isLocalPage && !
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
176
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
177
|
+
if (process.env.DINOU_DEBUG) {
|
|
178
|
+
console.log(
|
|
179
|
+
`Found optional catch-all route: ${segments.join("/") ?? ""
|
|
180
|
+
}/[[...${paramName}]]`,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
150
183
|
try {
|
|
151
184
|
if (getStaticPaths) {
|
|
152
|
-
const paths = await getStaticPaths
|
|
185
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
186
|
+
? getStaticPaths()
|
|
187
|
+
: getStaticPaths);
|
|
153
188
|
for (const pathItem of paths) {
|
|
154
189
|
// 1. Preparation of Structure and Extraction
|
|
155
190
|
const currentStructure = [...dynamicStructure, paramName];
|
|
@@ -275,22 +310,26 @@ async function buildStaticPages() {
|
|
|
275
310
|
segments.length,
|
|
276
311
|
);
|
|
277
312
|
|
|
278
|
-
let
|
|
313
|
+
let revalidate, getStaticPaths;
|
|
279
314
|
if (pageFunctionsPath) {
|
|
280
315
|
const module = await importModule(pageFunctionsPath);
|
|
281
316
|
getStaticPaths = module.getStaticPaths;
|
|
282
|
-
|
|
317
|
+
revalidate = module.revalidate;
|
|
283
318
|
}
|
|
284
319
|
const isLocalPage =
|
|
285
320
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
286
|
-
if (isLocalPage && !
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
321
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
322
|
+
if (process.env.DINOU_DEBUG) {
|
|
323
|
+
console.log(
|
|
324
|
+
`Found catch-all route: ${segments.join("/") ?? ""
|
|
325
|
+
}/[...${paramName}]`,
|
|
326
|
+
);
|
|
327
|
+
}
|
|
291
328
|
try {
|
|
292
329
|
if (getStaticPaths) {
|
|
293
|
-
const paths = await getStaticPaths
|
|
330
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
331
|
+
? getStaticPaths()
|
|
332
|
+
: getStaticPaths);
|
|
294
333
|
for (const pathItem of paths) {
|
|
295
334
|
const currentStructure = [...dynamicStructure, paramName];
|
|
296
335
|
const isObject =
|
|
@@ -379,22 +418,26 @@ async function buildStaticPages() {
|
|
|
379
418
|
segments.length,
|
|
380
419
|
);
|
|
381
420
|
|
|
382
|
-
let
|
|
421
|
+
let revalidate, getStaticPaths;
|
|
383
422
|
if (pageFunctionsPath) {
|
|
384
423
|
const module = await importModule(pageFunctionsPath);
|
|
385
424
|
getStaticPaths = module.getStaticPaths;
|
|
386
|
-
|
|
425
|
+
revalidate = module.revalidate;
|
|
387
426
|
}
|
|
388
427
|
const isLocalPage =
|
|
389
428
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
390
|
-
if (isLocalPage && !
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
429
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
430
|
+
if (process.env.DINOU_DEBUG) {
|
|
431
|
+
console.log(
|
|
432
|
+
`Found optional dynamic route: ${segments.join("/") ?? ""
|
|
433
|
+
}/[[${paramName}]]`,
|
|
434
|
+
);
|
|
435
|
+
}
|
|
395
436
|
try {
|
|
396
437
|
if (getStaticPaths) {
|
|
397
|
-
const paths = await getStaticPaths
|
|
438
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
439
|
+
? getStaticPaths()
|
|
440
|
+
: getStaticPaths);
|
|
398
441
|
for (const pathItem of paths) {
|
|
399
442
|
// 1. Preparation of Structure and Extraction
|
|
400
443
|
const currentStructure = [...dynamicStructure, paramName];
|
|
@@ -502,20 +545,50 @@ async function buildStaticPages() {
|
|
|
502
545
|
);
|
|
503
546
|
let dynamic;
|
|
504
547
|
let getStaticPaths;
|
|
548
|
+
let revalidate;
|
|
505
549
|
if (pageFunctionsPath) {
|
|
506
550
|
const module = await importModule(pageFunctionsPath);
|
|
507
551
|
getStaticPaths = module.getStaticPaths;
|
|
508
|
-
|
|
552
|
+
revalidate = module.revalidate;
|
|
553
|
+
}
|
|
554
|
+
const { getLayoutFunctionsPath } = require("./layout-functions");
|
|
555
|
+
const lfPath = getLayoutFunctionsPath(dynamicPath);
|
|
556
|
+
if (lfPath) {
|
|
557
|
+
const lmod = await importModule(lfPath);
|
|
558
|
+
const lmodGetStaticPaths = lmod.getStaticPaths || lmod.default?.getStaticPaths;
|
|
559
|
+
const lmodRevalidate = lmod.revalidate || lmod.default?.revalidate;
|
|
560
|
+
if (!getStaticPaths && lmodGetStaticPaths) {
|
|
561
|
+
getStaticPaths = lmodGetStaticPaths;
|
|
562
|
+
}
|
|
563
|
+
if (revalidate === undefined && lmodRevalidate !== undefined) {
|
|
564
|
+
revalidate = lmodRevalidate;
|
|
565
|
+
}
|
|
509
566
|
}
|
|
510
567
|
const isLocalPage =
|
|
511
568
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
569
|
+
const [layoutPath] = getFilePathAndDynamicParams(
|
|
570
|
+
segments,
|
|
571
|
+
{},
|
|
572
|
+
dynamicPath,
|
|
573
|
+
"layout",
|
|
574
|
+
true,
|
|
575
|
+
true,
|
|
576
|
+
undefined,
|
|
577
|
+
segments.length,
|
|
578
|
+
);
|
|
579
|
+
const hasLocalLayout =
|
|
580
|
+
layoutPath && path.dirname(layoutPath) === dynamicPath;
|
|
581
|
+
if ((isLocalPage || hasLocalLayout) && !(await isDynamicRoute(revalidate))) {
|
|
582
|
+
if (process.env.DINOU_DEBUG) {
|
|
583
|
+
console.log(
|
|
584
|
+
`Found dynamic route: ${segments.join("/") ?? ""}/[${paramName}]`,
|
|
585
|
+
);
|
|
586
|
+
}
|
|
516
587
|
try {
|
|
517
588
|
if (getStaticPaths) {
|
|
518
|
-
const paths = await getStaticPaths
|
|
589
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
590
|
+
? getStaticPaths()
|
|
591
|
+
: getStaticPaths);
|
|
519
592
|
for (const pathItem of paths) {
|
|
520
593
|
const currentStructure = [...dynamicStructure, paramName];
|
|
521
594
|
const isObject =
|
|
@@ -598,19 +671,21 @@ async function buildStaticPages() {
|
|
|
598
671
|
undefined,
|
|
599
672
|
segments.length,
|
|
600
673
|
);
|
|
601
|
-
let
|
|
674
|
+
let revalidate;
|
|
602
675
|
let getStaticPaths;
|
|
603
676
|
if (pageFunctionsPath) {
|
|
604
677
|
const module = await importModule(pageFunctionsPath);
|
|
605
678
|
getStaticPaths = module.getStaticPaths;
|
|
606
|
-
|
|
679
|
+
revalidate = module.revalidate;
|
|
607
680
|
}
|
|
608
681
|
const isLocalPage =
|
|
609
682
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
610
|
-
if (isLocalPage && !
|
|
683
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
611
684
|
try {
|
|
612
685
|
if (getStaticPaths) {
|
|
613
|
-
const paths = await getStaticPaths
|
|
686
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
687
|
+
? getStaticPaths()
|
|
688
|
+
: getStaticPaths);
|
|
614
689
|
for (const pathItem of paths) {
|
|
615
690
|
const currentStructure = dynamicStructure;
|
|
616
691
|
const isObject =
|
|
@@ -707,19 +782,30 @@ async function buildStaticPages() {
|
|
|
707
782
|
undefined,
|
|
708
783
|
segments.length,
|
|
709
784
|
);
|
|
710
|
-
let
|
|
785
|
+
let revalidate;
|
|
711
786
|
if (pageFunctionsPath) {
|
|
712
|
-
|
|
713
|
-
|
|
787
|
+
try {
|
|
788
|
+
const module = await importModule(pageFunctionsPath);
|
|
789
|
+
revalidate = module.revalidate;
|
|
790
|
+
} catch (e) {}
|
|
714
791
|
}
|
|
715
792
|
|
|
716
|
-
|
|
793
|
+
const isPpr = await resolveBuildPprForRoute(segments, pagePath, pageFunctionsPath, srcFolder);
|
|
794
|
+
|
|
795
|
+
if (pagePath && (!(await isDynamicRoute(revalidate)) || isPpr) && !doNotPushAtEnd) {
|
|
717
796
|
pages.push({
|
|
718
797
|
path: currentPath,
|
|
719
798
|
segments,
|
|
720
799
|
params: dParams,
|
|
800
|
+
ppr: isPpr,
|
|
721
801
|
});
|
|
722
|
-
|
|
802
|
+
const routeName = segments.join("/") ? "/" + segments.join("/") : "/";
|
|
803
|
+
if (typeof onProgress === "function") {
|
|
804
|
+
onProgress({ phase: "crawling", route: routeName, count: pages.length });
|
|
805
|
+
}
|
|
806
|
+
if (process.env.DINOU_DEBUG) {
|
|
807
|
+
console.log(`Found static route: ${routeName}${isPpr ? " (PPR)" : ""}`);
|
|
808
|
+
}
|
|
723
809
|
}
|
|
724
810
|
|
|
725
811
|
return pages;
|
|
@@ -728,9 +814,14 @@ async function buildStaticPages() {
|
|
|
728
814
|
// Crawl complete, start rendering and serialization loop for all discovered static pages
|
|
729
815
|
const pages = await collectPages(srcFolder);
|
|
730
816
|
|
|
731
|
-
|
|
817
|
+
let pageIdx = 0;
|
|
818
|
+
for (const { path: folderPath, segments, params, ppr: pageIsPpr } of pages) {
|
|
819
|
+
pageIdx++;
|
|
732
820
|
try {
|
|
733
821
|
const reqPath = segments.length ? "/" + segments.join("/") + "/" : "/";
|
|
822
|
+
if (typeof onProgress === "function") {
|
|
823
|
+
onProgress({ phase: "discovering", route: reqPath, current: pageIdx, total: pages.length });
|
|
824
|
+
}
|
|
734
825
|
// ====================================================================
|
|
735
826
|
// 1. MOCK RES: Fulfilling ResponseProxy interface
|
|
736
827
|
// ====================================================================
|
|
@@ -780,9 +871,11 @@ async function buildStaticPages() {
|
|
|
780
871
|
this._redirectUrl = url;
|
|
781
872
|
|
|
782
873
|
// Log warning because a redirect in SSG is usually problematic
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
874
|
+
if (process.env.DINOU_DEBUG) {
|
|
875
|
+
console.warn(
|
|
876
|
+
`⚠️ [SSG] Redirect detected in ${reqPath} -> ${url} (${status})`,
|
|
877
|
+
);
|
|
878
|
+
}
|
|
786
879
|
},
|
|
787
880
|
};
|
|
788
881
|
|
|
@@ -826,7 +919,8 @@ async function buildStaticPages() {
|
|
|
826
919
|
let revalidate;
|
|
827
920
|
let cacheTags = [];
|
|
828
921
|
const jsx = await requestStorage.run(mockContext, async () => {
|
|
829
|
-
|
|
922
|
+
return await runWithPprContext({ isPpr: Boolean(pageIsPpr) }, async () => {
|
|
923
|
+
const [pagePath] = getFilePathAndDynamicParams(
|
|
830
924
|
segments,
|
|
831
925
|
{},
|
|
832
926
|
folderPath,
|
|
@@ -858,15 +952,18 @@ async function buildStaticPages() {
|
|
|
858
952
|
const pageFunctionsModule = await importModule(pageFunctionsPath);
|
|
859
953
|
const getProps = pageFunctionsModule.getProps;
|
|
860
954
|
revalidate = pageFunctionsModule.revalidate;
|
|
861
|
-
|
|
955
|
+
const rawTags = pageFunctionsModule.getCacheTags ?? pageFunctionsModule.default?.getCacheTags;
|
|
956
|
+
if (typeof rawTags === "function") {
|
|
862
957
|
try {
|
|
863
|
-
cacheTags = await
|
|
958
|
+
cacheTags = await rawTags(params);
|
|
864
959
|
} catch (e) {
|
|
865
960
|
console.error("Error running getCacheTags in buildStaticPages:", e);
|
|
866
961
|
}
|
|
962
|
+
} else if (Array.isArray(rawTags)) {
|
|
963
|
+
cacheTags = rawTags;
|
|
867
964
|
}
|
|
868
965
|
pageFunctionsProps = await getProps?.(params);
|
|
869
|
-
props = { ...props, ...(pageFunctionsProps
|
|
966
|
+
props = { ...props, ...(pageFunctionsProps ?? {}) };
|
|
870
967
|
}
|
|
871
968
|
|
|
872
969
|
let jsx = React.createElement(Page, props);
|
|
@@ -902,19 +999,30 @@ async function buildStaticPages() {
|
|
|
902
999
|
false,
|
|
903
1000
|
)[0];
|
|
904
1001
|
const updatedSlots = {};
|
|
905
|
-
for (const [slotName,
|
|
906
|
-
const alreadyFoundPath = slotElement.props?.__modulePath;
|
|
907
|
-
const slotElementWithModule = {
|
|
908
|
-
...slotElement,
|
|
909
|
-
__modulePath: alreadyFoundPath ?? null,
|
|
910
|
-
};
|
|
911
|
-
|
|
1002
|
+
for (const [slotName, slotValue] of Object.entries(slots)) {
|
|
912
1003
|
let updatedSlotElement;
|
|
1004
|
+
const slotFilePath = slotValue?.slotPath || slotValue?.props?.__modulePath;
|
|
1005
|
+
const slotParams = slotValue?.slotParams || slotValue?.props?.params || {};
|
|
1006
|
+
|
|
913
1007
|
try {
|
|
914
|
-
|
|
915
|
-
|
|
1008
|
+
let elementToRender;
|
|
1009
|
+
if (slotValue && slotValue.slotPath) {
|
|
1010
|
+
const slotModule = await importModule(slotValue.slotPath);
|
|
1011
|
+
const Slot = slotModule.default ?? slotModule;
|
|
1012
|
+
elementToRender = React.createElement(Slot, {
|
|
1013
|
+
params: slotParams,
|
|
1014
|
+
key: slotName,
|
|
1015
|
+
__modulePath: slotValue.slotPath,
|
|
1016
|
+
});
|
|
1017
|
+
} else {
|
|
1018
|
+
elementToRender = {
|
|
1019
|
+
...slotValue,
|
|
1020
|
+
__modulePath: slotFilePath ?? null,
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
await asyncRenderJSXToClientJSX(elementToRender);
|
|
1024
|
+
updatedSlotElement = elementToRender;
|
|
916
1025
|
} catch (e) {
|
|
917
|
-
const slotFilePath = alreadyFoundPath;
|
|
918
1026
|
if (slotFilePath) {
|
|
919
1027
|
const realSlotFolder = path.dirname(slotFilePath);
|
|
920
1028
|
const [slotErrorPath, slotErrorParams] =
|
|
@@ -959,13 +1067,12 @@ async function buildStaticPages() {
|
|
|
959
1067
|
}
|
|
960
1068
|
updatedSlots[slotName] = updatedSlotElement;
|
|
961
1069
|
}
|
|
1070
|
+
const layoutProps = await getLayoutProps(layoutPath, dParams);
|
|
962
1071
|
let props = {
|
|
963
1072
|
params: dParams,
|
|
964
1073
|
...updatedSlots,
|
|
1074
|
+
...(layoutProps ?? {}),
|
|
965
1075
|
};
|
|
966
|
-
if (index === layouts.length - 1 || resetLayoutPath) {
|
|
967
|
-
props = { ...props, ...(pageFunctionsProps?.layout ?? {}) };
|
|
968
|
-
}
|
|
969
1076
|
jsx = React.createElement(Layout, props, jsx);
|
|
970
1077
|
jsx = { ...jsx, __modulePath: layoutPath };
|
|
971
1078
|
if (resetLayoutPath) {
|
|
@@ -978,16 +1085,19 @@ async function buildStaticPages() {
|
|
|
978
1085
|
|
|
979
1086
|
// Render the layout-nested React element tree to client-side RSC JSON format
|
|
980
1087
|
return await asyncRenderJSXToClientJSX(jsx);
|
|
1088
|
+
});
|
|
981
1089
|
});
|
|
982
1090
|
|
|
983
|
-
if (!isStatic) {
|
|
1091
|
+
if (!isStatic && !pageIsPpr) {
|
|
984
1092
|
// ❌ DO NOT save file.
|
|
985
1093
|
// Will behave as pure SSR at runtime.
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1094
|
+
if (process.env.DINOU_DEBUG) {
|
|
1095
|
+
console.log(
|
|
1096
|
+
`Skipping static generation for ${segments.join(
|
|
1097
|
+
"/",
|
|
1098
|
+
)} due to dynamic usage.`,
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
991
1101
|
continue;
|
|
992
1102
|
}
|
|
993
1103
|
|
|
@@ -996,20 +1106,27 @@ async function buildStaticPages() {
|
|
|
996
1106
|
cookies: mockRes._cookies,
|
|
997
1107
|
};
|
|
998
1108
|
|
|
1109
|
+
const holes = pageIsPpr ? getRegisteredHoles() : [];
|
|
999
1110
|
staticRoutes.add(reqPath);
|
|
1000
1111
|
staticMetadata.set(reqPath, {
|
|
1001
|
-
revalidate: revalidate
|
|
1112
|
+
revalidate: typeof revalidate === "function" ? await revalidate() : revalidate,
|
|
1002
1113
|
effects: sideEffects,
|
|
1003
1114
|
tags: cacheTags,
|
|
1115
|
+
ppr: Boolean(pageIsPpr),
|
|
1116
|
+
holes,
|
|
1004
1117
|
});
|
|
1005
|
-
|
|
1118
|
+
if (process.env.DINOU_DEBUG) {
|
|
1119
|
+
console.log(`Registered static page at ${reqPath}${pageIsPpr ? " (PPR)" : ""}`);
|
|
1120
|
+
}
|
|
1006
1121
|
} catch (err) {
|
|
1007
1122
|
console.error(`Error building page ${segments.join("/")}:`, err);
|
|
1008
1123
|
continue;
|
|
1009
1124
|
}
|
|
1010
1125
|
}
|
|
1011
1126
|
|
|
1012
|
-
|
|
1127
|
+
if (process.env.DINOU_DEBUG) {
|
|
1128
|
+
console.log(`Static site generated with ${pages.length} pages`);
|
|
1129
|
+
}
|
|
1013
1130
|
}
|
|
1014
1131
|
|
|
1015
1132
|
/**
|
|
@@ -1031,7 +1148,8 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1031
1148
|
segment &&
|
|
1032
1149
|
((segment.startsWith("(") && segment.endsWith(")")) ||
|
|
1033
1150
|
(segment.startsWith("[") && segment.endsWith("]")) ||
|
|
1034
|
-
segment.startsWith("@")
|
|
1151
|
+
segment.startsWith("@") ||
|
|
1152
|
+
segment.startsWith("_"));
|
|
1035
1153
|
const currentPath = path.join(folderPath, segment);
|
|
1036
1154
|
if (existsSync(currentPath) && !isRouterSyntaxInSegment) {
|
|
1037
1155
|
folderPath = currentPath;
|
|
@@ -1110,9 +1228,11 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1110
1228
|
this._redirectUrl = url;
|
|
1111
1229
|
|
|
1112
1230
|
// We log a warning because a redirect in SSG is usually problematic
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1231
|
+
if (process.env.DINOU_DEBUG) {
|
|
1232
|
+
console.warn(
|
|
1233
|
+
`⚠️ [SSG] Redirect detected in ${reqPath} -> ${url} (${status})`,
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1116
1236
|
},
|
|
1117
1237
|
};
|
|
1118
1238
|
|
|
@@ -1155,6 +1275,7 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1155
1275
|
|
|
1156
1276
|
let revalidate;
|
|
1157
1277
|
let cacheTags = [];
|
|
1278
|
+
let pageIsPpr = false;
|
|
1158
1279
|
const jsx = await requestStorage.run(mockContext, async () => {
|
|
1159
1280
|
const [pagePath, dParams] = getFilePathAndDynamicParams(
|
|
1160
1281
|
segments,
|
|
@@ -1171,8 +1292,6 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1171
1292
|
|
|
1172
1293
|
const pageModule = await importModule(pagePath);
|
|
1173
1294
|
const Page = pageModule.default ?? pageModule;
|
|
1174
|
-
|
|
1175
|
-
let props = { params: dParams };
|
|
1176
1295
|
const [pageFunctionsPath] = getFilePathAndDynamicParams(
|
|
1177
1296
|
segments,
|
|
1178
1297
|
{},
|
|
@@ -1184,22 +1303,30 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1184
1303
|
segments.length,
|
|
1185
1304
|
);
|
|
1186
1305
|
|
|
1306
|
+
pageIsPpr = await resolveBuildPprForRoute(segments, pagePath, pageFunctionsPath, srcFolder);
|
|
1307
|
+
|
|
1308
|
+
return await runWithPprContext({ isPpr: pageIsPpr }, async () => {
|
|
1309
|
+
let props = { params: dParams };
|
|
1310
|
+
|
|
1187
1311
|
let pageFunctionsProps;
|
|
1188
1312
|
if (pageFunctionsPath) {
|
|
1189
1313
|
const pageFunctionsModule = await importModule(pageFunctionsPath);
|
|
1190
1314
|
const getProps = pageFunctionsModule.getProps;
|
|
1191
|
-
if (isDynamic && (isDynamic.value = pageFunctionsModule.dynamic?.()))
|
|
1192
|
-
return;
|
|
1193
1315
|
revalidate = pageFunctionsModule.revalidate;
|
|
1194
|
-
if (
|
|
1316
|
+
if (isDynamic && (isDynamic.value = await isDynamicRoute(revalidate)))
|
|
1317
|
+
return;
|
|
1318
|
+
const rawTags = pageFunctionsModule.getCacheTags ?? pageFunctionsModule.default?.getCacheTags;
|
|
1319
|
+
if (typeof rawTags === "function") {
|
|
1195
1320
|
try {
|
|
1196
|
-
cacheTags = await
|
|
1321
|
+
cacheTags = await rawTags(dParams);
|
|
1197
1322
|
} catch (e) {
|
|
1198
1323
|
console.error("Error running getCacheTags:", e);
|
|
1199
1324
|
}
|
|
1325
|
+
} else if (Array.isArray(rawTags)) {
|
|
1326
|
+
cacheTags = rawTags;
|
|
1200
1327
|
}
|
|
1201
1328
|
pageFunctionsProps = await getProps?.(dParams);
|
|
1202
|
-
props = { ...props, ...(pageFunctionsProps
|
|
1329
|
+
props = { ...props, ...(pageFunctionsProps ?? {}) };
|
|
1203
1330
|
}
|
|
1204
1331
|
|
|
1205
1332
|
let jsx = React.createElement(Page, props);
|
|
@@ -1233,19 +1360,30 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1233
1360
|
false,
|
|
1234
1361
|
)[0];
|
|
1235
1362
|
const updatedSlots = {};
|
|
1236
|
-
for (const [slotName,
|
|
1237
|
-
const alreadyFoundPath = slotElement.props?.__modulePath;
|
|
1238
|
-
const slotElementWithModule = {
|
|
1239
|
-
...slotElement,
|
|
1240
|
-
__modulePath: alreadyFoundPath ?? null,
|
|
1241
|
-
};
|
|
1242
|
-
|
|
1363
|
+
for (const [slotName, slotValue] of Object.entries(slots)) {
|
|
1243
1364
|
let updatedSlotElement;
|
|
1365
|
+
const slotFilePath = slotValue?.slotPath || slotValue?.props?.__modulePath;
|
|
1366
|
+
const slotParams = slotValue?.slotParams || slotValue?.props?.params || {};
|
|
1367
|
+
|
|
1244
1368
|
try {
|
|
1245
|
-
|
|
1246
|
-
|
|
1369
|
+
let elementToRender;
|
|
1370
|
+
if (slotValue && slotValue.slotPath) {
|
|
1371
|
+
const slotModule = await importModule(slotValue.slotPath);
|
|
1372
|
+
const Slot = slotModule.default ?? slotModule;
|
|
1373
|
+
elementToRender = React.createElement(Slot, {
|
|
1374
|
+
params: slotParams,
|
|
1375
|
+
key: slotName,
|
|
1376
|
+
__modulePath: slotValue.slotPath,
|
|
1377
|
+
});
|
|
1378
|
+
} else {
|
|
1379
|
+
elementToRender = {
|
|
1380
|
+
...slotValue,
|
|
1381
|
+
__modulePath: slotFilePath ?? null,
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
await asyncRenderJSXToClientJSX(elementToRender);
|
|
1385
|
+
updatedSlotElement = elementToRender;
|
|
1247
1386
|
} catch (e) {
|
|
1248
|
-
const slotFilePath = alreadyFoundPath;
|
|
1249
1387
|
if (slotFilePath) {
|
|
1250
1388
|
const realSlotFolder = path.dirname(slotFilePath);
|
|
1251
1389
|
const [slotErrorPath, slotErrorParams] =
|
|
@@ -1294,12 +1432,11 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1294
1432
|
params: dParams,
|
|
1295
1433
|
...updatedSlots,
|
|
1296
1434
|
};
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
}
|
|
1435
|
+
const customLayoutProps = await getLayoutProps(layoutPath, dParams);
|
|
1436
|
+
layoutProps = {
|
|
1437
|
+
...layoutProps,
|
|
1438
|
+
...(customLayoutProps ?? {}),
|
|
1439
|
+
};
|
|
1303
1440
|
jsx = React.createElement(Layout, layoutProps, jsx);
|
|
1304
1441
|
jsx = { ...jsx, __modulePath: layoutPath };
|
|
1305
1442
|
if (resetLayoutPath) {
|
|
@@ -1310,17 +1447,20 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1310
1447
|
}
|
|
1311
1448
|
}
|
|
1312
1449
|
|
|
1313
|
-
|
|
1450
|
+
return await asyncRenderJSXToClientJSX(jsx);
|
|
1451
|
+
});
|
|
1314
1452
|
});
|
|
1315
1453
|
|
|
1316
|
-
if (!isStatic) {
|
|
1454
|
+
if (!isStatic && !pageIsPpr) {
|
|
1317
1455
|
// ❌ DO NOT save file.
|
|
1318
1456
|
// It will behave as pure SSR at runtime.
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1457
|
+
if (process.env.DINOU_DEBUG) {
|
|
1458
|
+
console.log(
|
|
1459
|
+
`Skipping static generation for ${segments.join(
|
|
1460
|
+
"/",
|
|
1461
|
+
)} due to dynamic usage.`,
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1324
1464
|
if (isDynamic) {
|
|
1325
1465
|
isDynamic.value = true;
|
|
1326
1466
|
}
|
|
@@ -1332,13 +1472,16 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1332
1472
|
cookies: mockRes._cookies,
|
|
1333
1473
|
};
|
|
1334
1474
|
|
|
1475
|
+
const holes = pageIsPpr ? getRegisteredHoles() : [];
|
|
1335
1476
|
staticRoutes.add(reqPath);
|
|
1336
1477
|
staticMetadata.set(reqPath, {
|
|
1337
|
-
revalidate: revalidate
|
|
1478
|
+
revalidate: typeof revalidate === "function" ? await revalidate() : revalidate,
|
|
1338
1479
|
effects: sideEffects,
|
|
1339
1480
|
tags: cacheTags,
|
|
1481
|
+
ppr: pageIsPpr,
|
|
1482
|
+
holes,
|
|
1340
1483
|
});
|
|
1341
|
-
console.warn(`Registered rebuilt static page at ${reqPath}`);
|
|
1484
|
+
console.warn(`Registered rebuilt static page at ${reqPath}${pageIsPpr ? " (PPR)" : ""}`);
|
|
1342
1485
|
} catch (error) {
|
|
1343
1486
|
console.error(`Error building page ${reqPath}:`, error);
|
|
1344
1487
|
throw error;
|
|
@@ -1350,7 +1493,14 @@ function getStaticPaths() {
|
|
|
1350
1493
|
}
|
|
1351
1494
|
|
|
1352
1495
|
function getStaticMetadata(reqPath) {
|
|
1353
|
-
|
|
1496
|
+
if (!reqPath) return null;
|
|
1497
|
+
const noSlash = reqPath.endsWith("/") ? reqPath.slice(0, -1) : reqPath;
|
|
1498
|
+
const withSlash = noSlash + "/";
|
|
1499
|
+
return staticMetadata.get(reqPath) || staticMetadata.get(noSlash) || staticMetadata.get(withSlash) || null;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
function getStaticLayouts() {
|
|
1503
|
+
return Array.from(staticLayouts.values());
|
|
1354
1504
|
}
|
|
1355
1505
|
|
|
1356
1506
|
module.exports = {
|
|
@@ -1358,4 +1508,6 @@ module.exports = {
|
|
|
1358
1508
|
buildStaticPage,
|
|
1359
1509
|
getStaticPaths,
|
|
1360
1510
|
getStaticMetadata,
|
|
1511
|
+
getStaticLayouts,
|
|
1361
1512
|
};
|
|
1513
|
+
|