dinou 4.0.8 → 4.0.10
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 +13 -0
- package/dinou/core/build-static-pages.js +37 -40
- package/dinou/core/css-require-hook.js +64 -64
- package/dinou/core/generating-isg.js +2 -3
- package/dinou/core/get-error-jsx.js +1 -3
- package/dinou/core/get-file-path-and-dynamic-params.js +0 -1
- package/dinou/core/get-jsx.js +1 -3
- package/dinou/core/get-ssg-jsx-or-jsx.js +2 -2
- package/dinou/core/render-app-to-html.js +1 -5
- package/dinou/core/render-html.js +23 -26
- package/dinou/core/server-function-proxy-webpack.js +2 -3
- package/dinou/core/server.js +22 -66
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +0 -1
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +0 -1
- package/dinou/esbuild/helpers-esbuild/get-esbuild-entries.mjs +8 -8
- package/dinou/esbuild/helpers-esbuild/write.mjs +6 -6
- package/dinou/esbuild/plugins-esbuild/assets-plugin.mjs +17 -17
- package/dinou/esbuild/plugins-esbuild/babel-react-compiler-plugin.mjs +11 -11
- package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +5 -5
- package/dinou/esbuild/plugins-esbuild/stable-chunk-names-and-maps-plugin.mjs +12 -12
- package/dinou/esbuild/plugins-postcss/postcss-extract-plugin.js +3 -3
- package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +12 -39
- package/dinou/esbuild/react-refresh/react-refresh-runtime.mjs +1 -2
- package/dinou/package.json +1 -2
- package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +4 -4
- package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +5 -5
- package/dinou/rollup/rollup.config.js +30 -58
- package/dinou/webpack/helpers/get-webpack-entries.js +7 -31
- package/dinou/webpack/loaders/server-functions-loader.js +4 -5
- package/dinou/webpack/plugins/manifest-generator-plugin.js +6 -6
- package/dinou/webpack/plugins/server-functions-plugin.js +7 -12
- package/dinou/webpack/webpack.config.js +21 -36
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ 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
|
+
## [4.0.10]
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Server Functions endpoint vulnerability.
|
|
13
|
+
|
|
14
|
+
## [4.0.9]
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Remove unused dependency '@pmmmwh/react-refresh-webpack-plugin'.
|
|
19
|
+
- Delete unnecessary commented code and translate comments to English.
|
|
20
|
+
|
|
8
21
|
## [4.0.8]
|
|
9
22
|
|
|
10
23
|
### Changed
|
|
@@ -69,6 +69,12 @@ function createBailoutProxy(target, label, onBailout) {
|
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Compiles all static pages in the application.
|
|
74
|
+
* Crawls the "src/" folder to collect all routes, resolves dynamic path segments,
|
|
75
|
+
* mock-renders them inside a server context, and serializes successful static renders
|
|
76
|
+
* into RSC JSON payloads.
|
|
77
|
+
*/
|
|
72
78
|
async function buildStaticPages() {
|
|
73
79
|
const srcFolder = path.resolve(process.cwd(), "src");
|
|
74
80
|
const distFolder = path.resolve(process.cwd(), "dist");
|
|
@@ -82,6 +88,11 @@ async function buildStaticPages() {
|
|
|
82
88
|
mkdirSync(distFolder, { recursive: true });
|
|
83
89
|
}
|
|
84
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Recursively traverses the page directory tree to collect all eligible static routes.
|
|
93
|
+
* Handles static folder names, route groups (e.g. "(group)"), and dynamic parameters
|
|
94
|
+
* like catch-all segments or optional segments by resolving their static paths.
|
|
95
|
+
*/
|
|
85
96
|
async function collectPages(
|
|
86
97
|
currentPath,
|
|
87
98
|
segments = [],
|
|
@@ -141,8 +152,7 @@ async function buildStaticPages() {
|
|
|
141
152
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
142
153
|
if (isLocalPage && !dynamic?.()) {
|
|
143
154
|
console.log(
|
|
144
|
-
`Found optional catch-all route: ${
|
|
145
|
-
segments.join("/") ?? ""
|
|
155
|
+
`Found optional catch-all route: ${segments.join("/") ?? ""
|
|
146
156
|
}/[[...${paramName}]]`,
|
|
147
157
|
);
|
|
148
158
|
try {
|
|
@@ -283,8 +293,7 @@ async function buildStaticPages() {
|
|
|
283
293
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
284
294
|
if (isLocalPage && !dynamic?.()) {
|
|
285
295
|
console.log(
|
|
286
|
-
`Found catch-all route: ${
|
|
287
|
-
segments.join("/") ?? ""
|
|
296
|
+
`Found catch-all route: ${segments.join("/") ?? ""
|
|
288
297
|
}/[...${paramName}]`,
|
|
289
298
|
);
|
|
290
299
|
try {
|
|
@@ -308,17 +317,13 @@ async function buildStaticPages() {
|
|
|
308
317
|
const val = pathItem[key];
|
|
309
318
|
|
|
310
319
|
// 🛡️ FIX 1: Relaxed validation.
|
|
311
|
-
//
|
|
312
|
-
// If parent keys are missing (key !== paramName), we allow undefined (assume optional).
|
|
320
|
+
// Mark the route as invalid (skipping its generation) if any parent parameter segment is missing.
|
|
313
321
|
if (
|
|
314
322
|
(val === undefined || val === null || val === "") &&
|
|
315
323
|
i < arr.length - 1
|
|
316
324
|
) {
|
|
317
325
|
notValidRoute = true;
|
|
318
326
|
}
|
|
319
|
-
// throw new Error(
|
|
320
|
-
// `[Dinou] The mandatory catch-all parameter '${paramName}' is undefined in ${dynamicPath}.`
|
|
321
|
-
// );
|
|
322
327
|
return val;
|
|
323
328
|
});
|
|
324
329
|
if (notValidRoute) continue;
|
|
@@ -329,7 +334,6 @@ async function buildStaticPages() {
|
|
|
329
334
|
// 🛡️ FIX 2: Segment filtering.
|
|
330
335
|
// Flatten (.flat) to handle the catch-all array and filter undefineds from parents.
|
|
331
336
|
const validSegmentsToAdd = segmentsToAdd.flat();
|
|
332
|
-
// .filter((s) => s !== undefined && s !== null && s !== "");
|
|
333
337
|
|
|
334
338
|
const paramsToAdd = isObject
|
|
335
339
|
? pathItem
|
|
@@ -393,8 +397,7 @@ async function buildStaticPages() {
|
|
|
393
397
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
394
398
|
if (isLocalPage && !dynamic?.()) {
|
|
395
399
|
console.log(
|
|
396
|
-
`Found optional dynamic route: ${
|
|
397
|
-
segments.join("/") ?? ""
|
|
400
|
+
`Found optional dynamic route: ${segments.join("/") ?? ""
|
|
398
401
|
}/[[${paramName}]]`,
|
|
399
402
|
);
|
|
400
403
|
try {
|
|
@@ -537,16 +540,12 @@ async function buildStaticPages() {
|
|
|
537
540
|
}
|
|
538
541
|
const val = pathItem[key];
|
|
539
542
|
|
|
540
|
-
// 🛡️ CHANGE:
|
|
541
|
-
// If a parent parameter is missing (key !== paramName), we assume it could be optional.
|
|
543
|
+
// 🛡️ CHANGE: If a parent parameter is missing, we mark the route as invalid to skip it.
|
|
542
544
|
if (
|
|
543
545
|
(val === undefined || val === null || val === "") &&
|
|
544
546
|
i < arr.length - 1
|
|
545
547
|
) {
|
|
546
548
|
notValidRoute = true;
|
|
547
|
-
// throw new Error(
|
|
548
|
-
// `[Dinou] The mandatory parameter '${paramName}' is undefined in ${dynamicPath}.`
|
|
549
|
-
// );
|
|
550
549
|
}
|
|
551
550
|
return val;
|
|
552
551
|
});
|
|
@@ -555,9 +554,7 @@ async function buildStaticPages() {
|
|
|
555
554
|
segmentsToAdd = [pathItem];
|
|
556
555
|
}
|
|
557
556
|
|
|
558
|
-
// 🛡️ CHANGE: We filter undefineds here too, because a parent could be optional
|
|
559
557
|
const validSegmentsToAdd = segmentsToAdd.flat();
|
|
560
|
-
// .filter((s) => s !== undefined && s !== null && s !== "");
|
|
561
558
|
|
|
562
559
|
const paramsToAdd = isObject
|
|
563
560
|
? pathItem
|
|
@@ -566,7 +563,7 @@ async function buildStaticPages() {
|
|
|
566
563
|
pages.push(
|
|
567
564
|
...(await collectPages(
|
|
568
565
|
dynamicPath,
|
|
569
|
-
[...segments, ...validSegmentsToAdd],
|
|
566
|
+
[...segments, ...validSegmentsToAdd],
|
|
570
567
|
{ ...params, ...paramsToAdd },
|
|
571
568
|
)),
|
|
572
569
|
);
|
|
@@ -639,16 +636,12 @@ async function buildStaticPages() {
|
|
|
639
636
|
}
|
|
640
637
|
const val = pathItem[key];
|
|
641
638
|
|
|
642
|
-
// 🛡️ CHANGE:
|
|
643
|
-
// If a parent parameter is missing (key !== paramName), we assume it could be optional.
|
|
639
|
+
// 🛡️ CHANGE: If a parent parameter is missing, we mark the route as invalid to skip it.
|
|
644
640
|
if (
|
|
645
641
|
(val === undefined || val === null || val === "") &&
|
|
646
642
|
i < arr.length - 1
|
|
647
643
|
) {
|
|
648
644
|
notValidRoute = true;
|
|
649
|
-
// throw new Error(
|
|
650
|
-
// `[Dinou] The mandatory parameter '${paramName}' is undefined in ${dynamicPath}.`
|
|
651
|
-
// );
|
|
652
645
|
}
|
|
653
646
|
return val;
|
|
654
647
|
});
|
|
@@ -657,9 +650,7 @@ async function buildStaticPages() {
|
|
|
657
650
|
segmentsToAdd = [pathItem];
|
|
658
651
|
}
|
|
659
652
|
|
|
660
|
-
// 🛡️ CHANGE: We filter undefineds here too, because a parent could be optional
|
|
661
653
|
const validSegmentsToAdd = segmentsToAdd.flat();
|
|
662
|
-
// .filter((s) => s !== undefined && s !== null && s !== "");
|
|
663
654
|
|
|
664
655
|
const paramsToAdd = isObject
|
|
665
656
|
? pathItem
|
|
@@ -668,7 +659,7 @@ async function buildStaticPages() {
|
|
|
668
659
|
pages.push(
|
|
669
660
|
...(await collectPages(
|
|
670
661
|
dynamicPath,
|
|
671
|
-
[...segments, ...validSegmentsToAdd, entry.name],
|
|
662
|
+
[...segments, ...validSegmentsToAdd, entry.name],
|
|
672
663
|
{ ...params, ...paramsToAdd },
|
|
673
664
|
)),
|
|
674
665
|
);
|
|
@@ -742,6 +733,7 @@ async function buildStaticPages() {
|
|
|
742
733
|
return pages;
|
|
743
734
|
}
|
|
744
735
|
|
|
736
|
+
// Crawl complete, start rendering and serialization loop for all discovered static pages
|
|
745
737
|
const pages = await collectPages(srcFolder);
|
|
746
738
|
|
|
747
739
|
for (const { path: folderPath, segments, params } of pages) {
|
|
@@ -853,10 +845,8 @@ async function buildStaticPages() {
|
|
|
853
845
|
);
|
|
854
846
|
const pageModule = await importModule(pagePath);
|
|
855
847
|
const Page = pageModule.default ?? pageModule;
|
|
856
|
-
// Set displayName for better serialization
|
|
857
|
-
// if (!Page.displayName) Page.displayName = "Page";
|
|
858
848
|
|
|
859
|
-
let props = { params
|
|
849
|
+
let props = { params };
|
|
860
850
|
|
|
861
851
|
const [pageFunctionsPath] = getFilePathAndDynamicParams(
|
|
862
852
|
segments,
|
|
@@ -882,6 +872,7 @@ async function buildStaticPages() {
|
|
|
882
872
|
let jsx = React.createElement(Page, props);
|
|
883
873
|
jsx = { ...jsx, __modulePath: pagePath };
|
|
884
874
|
|
|
875
|
+
// Resolve and nest layout components from the page folder up to the source root
|
|
885
876
|
const noLayoutPath = path.join(folderPath, "no_layout");
|
|
886
877
|
if (!existsSync(noLayoutPath)) {
|
|
887
878
|
const layouts = getFilePathAndDynamicParams(
|
|
@@ -921,7 +912,7 @@ async function buildStaticPages() {
|
|
|
921
912
|
}
|
|
922
913
|
let props = {
|
|
923
914
|
params: dParams,
|
|
924
|
-
|
|
915
|
+
...updatedSlots,
|
|
925
916
|
};
|
|
926
917
|
if (index === layouts.length - 1 || resetLayoutPath) {
|
|
927
918
|
props = { ...props, ...(pageFunctionsProps?.layout ?? {}) };
|
|
@@ -936,6 +927,7 @@ async function buildStaticPages() {
|
|
|
936
927
|
}
|
|
937
928
|
}
|
|
938
929
|
|
|
930
|
+
// Render the layout-nested React element tree to client-side RSC JSON format
|
|
939
931
|
return await asyncRenderJSXToClientJSX(jsx);
|
|
940
932
|
});
|
|
941
933
|
|
|
@@ -950,16 +942,12 @@ async function buildStaticPages() {
|
|
|
950
942
|
continue;
|
|
951
943
|
}
|
|
952
944
|
|
|
953
|
-
// const outputPath = path.join(distFolder, segments.join("/"));
|
|
954
|
-
// mkdirSync(outputPath, { recursive: true });
|
|
955
|
-
|
|
956
|
-
// const jsonPath = path.join(outputPath, "index.json");
|
|
957
|
-
|
|
958
945
|
const sideEffects = {
|
|
959
946
|
redirect: mockRes._redirectUrl,
|
|
960
947
|
cookies: mockRes._cookies,
|
|
961
948
|
};
|
|
962
949
|
|
|
950
|
+
// Store the serialized RSC JSON, revalidation timer, and side effects (cookies/redirects)
|
|
963
951
|
setJSXJSON(reqPath, {
|
|
964
952
|
jsx: serializeReactElement(jsx),
|
|
965
953
|
revalidate: revalidate?.(),
|
|
@@ -976,6 +964,11 @@ async function buildStaticPages() {
|
|
|
976
964
|
console.log(`Static site generated with ${pages.length} pages`);
|
|
977
965
|
}
|
|
978
966
|
|
|
967
|
+
/**
|
|
968
|
+
* Renders and compiles a single page dynamically on-demand at runtime.
|
|
969
|
+
* Used for Incremental Static Regeneration (ISR) or on-demand page generation.
|
|
970
|
+
* Follows the same bailout detection and RSC serialization logic as the build compiler.
|
|
971
|
+
*/
|
|
979
972
|
async function buildStaticPage(reqPath, isDynamic = null) {
|
|
980
973
|
const srcFolder = path.resolve(process.cwd(), "src");
|
|
981
974
|
|
|
@@ -1130,7 +1123,7 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1130
1123
|
const pageModule = await importModule(pagePath);
|
|
1131
1124
|
const Page = pageModule.default ?? pageModule;
|
|
1132
1125
|
|
|
1133
|
-
let props = { params: dParams
|
|
1126
|
+
let props = { params: dParams };
|
|
1134
1127
|
const [pageFunctionsPath] = getFilePathAndDynamicParams(
|
|
1135
1128
|
segments,
|
|
1136
1129
|
{},
|
|
@@ -1194,7 +1187,6 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1194
1187
|
}
|
|
1195
1188
|
let layoutProps = {
|
|
1196
1189
|
params: dParams,
|
|
1197
|
-
// searchParams: {},
|
|
1198
1190
|
...updatedSlots,
|
|
1199
1191
|
};
|
|
1200
1192
|
if (index === layouts.length - 1 || resetLayoutPath) {
|
|
@@ -1268,6 +1260,11 @@ function filterProps(props_) {
|
|
|
1268
1260
|
return props_;
|
|
1269
1261
|
}
|
|
1270
1262
|
|
|
1263
|
+
/**
|
|
1264
|
+
* Recursively serializes a React element tree into a custom JSON format.
|
|
1265
|
+
* This format represents the React Server Component (RSC) payload sent to the client,
|
|
1266
|
+
* mapping HTML tags, React fragments, Suspense boundaries, and Client Component stubs.
|
|
1267
|
+
*/
|
|
1271
1268
|
function serializeReactElement(element) {
|
|
1272
1269
|
if (React.isValidElement(element)) {
|
|
1273
1270
|
let type;
|
|
@@ -1288,7 +1285,7 @@ function serializeReactElement(element) {
|
|
|
1288
1285
|
}
|
|
1289
1286
|
try {
|
|
1290
1287
|
componentName = element.type.displayName || element.type.name;
|
|
1291
|
-
} catch (e) {}
|
|
1288
|
+
} catch (e) { }
|
|
1292
1289
|
|
|
1293
1290
|
if (!modulePath && global.__DINOU_MODULE_MAP) {
|
|
1294
1291
|
const meta = global.__DINOU_MODULE_MAP.get(element.type);
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const postcss = require("postcss");
|
|
3
|
-
const createScopedName = require("./createScopedName");
|
|
4
|
-
|
|
5
|
-
function registerCSSRequireHook() {
|
|
6
|
-
require.extensions[".css"] = function (module, filename) {
|
|
7
|
-
const cssContent = fs.readFileSync(filename, "utf8");
|
|
8
|
-
const jsonResult = {};
|
|
9
|
-
|
|
10
|
-
const plugin = {
|
|
11
|
-
postcssPlugin: "extract-classes",
|
|
12
|
-
Rule(rule) {
|
|
13
|
-
//
|
|
14
|
-
if (rule.parent && rule.parent.name === "keyframes") {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const selector = rule.selector;
|
|
19
|
-
// Regex
|
|
20
|
-
const classRegex = /\.([_a-zA-Z0-9-]+)/g;
|
|
21
|
-
let match;
|
|
22
|
-
|
|
23
|
-
while ((match = classRegex.exec(selector)) !== null) {
|
|
24
|
-
const className = match[1];
|
|
25
|
-
|
|
26
|
-
//
|
|
27
|
-
const index = match.index;
|
|
28
|
-
const before = selector.slice(0, index);
|
|
29
|
-
const lastGlobal = before.lastIndexOf(":global");
|
|
30
|
-
const lastLocal = before.lastIndexOf(":local");
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
if (lastGlobal > lastLocal) {
|
|
34
|
-
const afterGlobal = before.slice(lastGlobal);
|
|
35
|
-
if (afterGlobal.includes("(")) {
|
|
36
|
-
const openParens = afterGlobal.split("(").length - 1;
|
|
37
|
-
const closeParens = afterGlobal.split(")").length - 1;
|
|
38
|
-
if (openParens > closeParens) {
|
|
39
|
-
jsonResult[className] = className;
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
} else {
|
|
43
|
-
//
|
|
44
|
-
jsonResult[className] = className;
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
if (!jsonResult[className]) {
|
|
51
|
-
jsonResult[className] = createScopedName(className, filename);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
//
|
|
58
|
-
postcss([plugin]).process(cssContent, { from: filename }).css;
|
|
59
|
-
|
|
60
|
-
module.exports = jsonResult;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
module.exports = registerCSSRequireHook;
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const postcss = require("postcss");
|
|
3
|
+
const createScopedName = require("./createScopedName");
|
|
4
|
+
|
|
5
|
+
function registerCSSRequireHook() {
|
|
6
|
+
require.extensions[".css"] = function (module, filename) {
|
|
7
|
+
const cssContent = fs.readFileSync(filename, "utf8");
|
|
8
|
+
const jsonResult = {};
|
|
9
|
+
|
|
10
|
+
const plugin = {
|
|
11
|
+
postcssPlugin: "extract-classes",
|
|
12
|
+
Rule(rule) {
|
|
13
|
+
// Ignore classes inside animations (@keyframes)
|
|
14
|
+
if (rule.parent && rule.parent.name === "keyframes") {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const selector = rule.selector;
|
|
19
|
+
// Regex to capture valid class names
|
|
20
|
+
const classRegex = /\.([_a-zA-Z0-9-]+)/g;
|
|
21
|
+
let match;
|
|
22
|
+
|
|
23
|
+
while ((match = classRegex.exec(selector)) !== null) {
|
|
24
|
+
const className = match[1];
|
|
25
|
+
|
|
26
|
+
// Handle :global and :local selectors
|
|
27
|
+
const index = match.index;
|
|
28
|
+
const before = selector.slice(0, index);
|
|
29
|
+
const lastGlobal = before.lastIndexOf(":global");
|
|
30
|
+
const lastLocal = before.lastIndexOf(":local");
|
|
31
|
+
|
|
32
|
+
// If the class is under an active :global scope, do not hash it
|
|
33
|
+
if (lastGlobal > lastLocal) {
|
|
34
|
+
const afterGlobal = before.slice(lastGlobal);
|
|
35
|
+
if (afterGlobal.includes("(")) {
|
|
36
|
+
const openParens = afterGlobal.split("(").length - 1;
|
|
37
|
+
const closeParens = afterGlobal.split(")").length - 1;
|
|
38
|
+
if (openParens > closeParens) {
|
|
39
|
+
jsonResult[className] = className;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// Example: :global .my-class (without parentheses)
|
|
44
|
+
jsonResult[className] = className;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// If it is a local class, generate the corresponding deterministic hash
|
|
50
|
+
if (!jsonResult[className]) {
|
|
51
|
+
jsonResult[className] = createScopedName(className, filename);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Process strictly synchronously (PostCSS is synchronous if its plugins are)
|
|
58
|
+
postcss([plugin]).process(cssContent, { from: filename }).css;
|
|
59
|
+
|
|
60
|
+
module.exports = jsonResult;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = registerCSSRequireHook;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// dinou/core/promote-to-static.js
|
|
2
1
|
const fs = require("fs").promises;
|
|
3
2
|
const path = require("path");
|
|
4
3
|
const { existsSync, copyFileSync } = require("fs");
|
|
@@ -65,8 +64,8 @@ function generatingISG(reqPath, isDynamicFromServer) {
|
|
|
65
64
|
console.log(`✅ [ISG] Successfully promoted ${reqPath} to static.`);
|
|
66
65
|
} else {
|
|
67
66
|
// Cleanup if failed
|
|
68
|
-
await fs.unlink(pageResult.tempPath).catch(() => {});
|
|
69
|
-
await fs.unlink(rscResult.tempPath).catch(() => {});
|
|
67
|
+
await fs.unlink(pageResult.tempPath).catch(() => { });
|
|
68
|
+
await fs.unlink(rscResult.tempPath).catch(() => { });
|
|
70
69
|
console.warn(`⚠️ [ISG] Failed to generate HTML/RSC for ${reqPath}`);
|
|
71
70
|
}
|
|
72
71
|
} catch (e) {
|
|
@@ -66,7 +66,6 @@ async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
|
|
|
66
66
|
const Page = pageModule.default ?? pageModule;
|
|
67
67
|
jsx = React.createElement(Page, {
|
|
68
68
|
params: dynamicParams ?? {},
|
|
69
|
-
// searchParams: query,
|
|
70
69
|
error,
|
|
71
70
|
});
|
|
72
71
|
|
|
@@ -152,7 +151,6 @@ async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
|
|
|
152
151
|
|
|
153
152
|
updatedSlotElement = React.createElement(SlotError, {
|
|
154
153
|
params: slotErrorParams, // Resolved params (if any)
|
|
155
|
-
// searchParams: query,
|
|
156
154
|
key: slotName,
|
|
157
155
|
error: serializedError, // We pass the captured error
|
|
158
156
|
});
|
|
@@ -176,7 +174,7 @@ async function getErrorJSX(reqPath, query, error, isDevelopment = false) {
|
|
|
176
174
|
}
|
|
177
175
|
let props = {
|
|
178
176
|
params: dParams,
|
|
179
|
-
|
|
177
|
+
...updatedSlots,
|
|
180
178
|
};
|
|
181
179
|
jsx = React.createElement(Layout, props, jsx);
|
|
182
180
|
const layoutFolderPath = path.dirname(layoutPath);
|
package/dinou/core/get-jsx.js
CHANGED
|
@@ -109,7 +109,6 @@ async function getJSX(
|
|
|
109
109
|
|
|
110
110
|
let props = {
|
|
111
111
|
params: dynamicParams,
|
|
112
|
-
// searchParams: query,
|
|
113
112
|
};
|
|
114
113
|
|
|
115
114
|
const pageFolder = path.dirname(pagePath);
|
|
@@ -207,7 +206,6 @@ async function getJSX(
|
|
|
207
206
|
|
|
208
207
|
updatedSlotElement = React.createElement(SlotError, {
|
|
209
208
|
params: slotErrorParams,
|
|
210
|
-
// searchParams: query,
|
|
211
209
|
key: slotName,
|
|
212
210
|
error: serializedError,
|
|
213
211
|
});
|
|
@@ -227,7 +225,7 @@ async function getJSX(
|
|
|
227
225
|
updatedSlots[slotName] = updatedSlotElement;
|
|
228
226
|
}
|
|
229
227
|
}
|
|
230
|
-
let props = { params: dParams,
|
|
228
|
+
let props = { params: dParams, ...updatedSlots };
|
|
231
229
|
if (index === layouts.length - 1 || resetLayoutPath) {
|
|
232
230
|
props = { ...props, ...(pageFunctionsProps?.layout ?? {}) };
|
|
233
231
|
}
|
|
@@ -4,10 +4,10 @@ const { getJSXJSON } = require("./jsx-json.js");
|
|
|
4
4
|
|
|
5
5
|
async function getSSGJSXOrJSX(reqPath, query, isDevelopment = false) {
|
|
6
6
|
const isNotFound = null;
|
|
7
|
-
const result =
|
|
7
|
+
const result = isDevelopment
|
|
8
8
|
? await getJSX(reqPath, query, isNotFound, isDevelopment)
|
|
9
9
|
: (await getSSGJSX(getJSXJSON(reqPath))) ??
|
|
10
|
-
|
|
10
|
+
(await getJSX(reqPath, query, isNotFound, isDevelopment));
|
|
11
11
|
return result;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -52,10 +52,6 @@ function renderAppToHtml(
|
|
|
52
52
|
renderHtmlPath, // ⬅️ CHANGE 2: The script (path) is the first argument of fork (no need for "node")
|
|
53
53
|
scriptArgs, // Positional arguments for the script (process.argv)
|
|
54
54
|
{
|
|
55
|
-
// env: {
|
|
56
|
-
// NODE_ENV: process.env.NODE_ENV,
|
|
57
|
-
// DINOU_BUILD_TOOL: process.env.DINOU_BUILD_TOOL,
|
|
58
|
-
// }, // You can pass other environment variables if necessary
|
|
59
55
|
// ⬅️ CHANGE 3: Apply Whitelist to execArgv, resetting inherited options
|
|
60
56
|
execArgv: childExecArgv,
|
|
61
57
|
// ⬅️ CHANGE 4: stdio needs 'ipc' for fork to work and for the future communication channel
|
|
@@ -129,7 +125,7 @@ function renderAppToHtml(
|
|
|
129
125
|
if (options && options.httpOnly) {
|
|
130
126
|
console.error(
|
|
131
127
|
`[Dinou Error] Cannot set HttpOnly cookie '${name}' because streaming has already started. ` +
|
|
132
|
-
|
|
128
|
+
`Headers are sent, and document.cookie cannot write HttpOnly cookies.`,
|
|
133
129
|
);
|
|
134
130
|
return; // We do nothing because it would fail silently in the browser
|
|
135
131
|
}
|
|
@@ -140,12 +140,12 @@ async function renderToStream(
|
|
|
140
140
|
try {
|
|
141
141
|
const isNotFound = {};
|
|
142
142
|
const jsx =
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
isDevelopment ||
|
|
144
|
+
isDynamic ||
|
|
145
|
+
!hasJsxJson
|
|
146
146
|
? renderJSXToClientJSX(
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
await getJSX(reqPath, query, isNotFound, isDevelopment),
|
|
148
|
+
)
|
|
149
149
|
: ((await getSSGJSX(jsxJson)) ??
|
|
150
150
|
renderJSXToClientJSX(
|
|
151
151
|
await getJSX(reqPath, query, isNotFound, isDevelopment),
|
|
@@ -160,7 +160,7 @@ async function renderToStream(
|
|
|
160
160
|
try {
|
|
161
161
|
stream.unpipe(process.stdout);
|
|
162
162
|
stream.destroy();
|
|
163
|
-
} catch {}
|
|
163
|
+
} catch { }
|
|
164
164
|
}
|
|
165
165
|
const isProd = process.env.NODE_ENV === "production";
|
|
166
166
|
|
|
@@ -188,28 +188,25 @@ async function renderToStream(
|
|
|
188
188
|
writeErrorOutput(error, isProd);
|
|
189
189
|
process.exit(1);
|
|
190
190
|
},
|
|
191
|
-
// bootstrapModules: [getAssetFromManifest("error.js")],
|
|
192
191
|
bootstrapModules: isDevelopment
|
|
193
192
|
? [
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
193
|
+
getAssetFromManifest("error.js"),
|
|
194
|
+
isWebpack
|
|
195
|
+
? undefined
|
|
196
|
+
: getAssetFromManifest("runtime.js"),
|
|
197
|
+
].filter(Boolean)
|
|
199
198
|
: [getAssetFromManifest("error.js")],
|
|
200
199
|
bootstrapScriptContent: `window.__DINOU_ERROR_MESSAGE__=${JSON.stringify(
|
|
201
200
|
error.message || "Unknown error",
|
|
202
|
-
)};window.__DINOU_ERROR_NAME__=${JSON.stringify(error.name)};${
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}${
|
|
209
|
-
isDevelopment
|
|
201
|
+
)};window.__DINOU_ERROR_NAME__=${JSON.stringify(error.name)};${isDevelopment
|
|
202
|
+
? `window.__DINOU_ERROR_STACK__=${JSON.stringify(
|
|
203
|
+
error.stack || "No stack trace available",
|
|
204
|
+
)};`
|
|
205
|
+
: ""
|
|
206
|
+
}${isDevelopment
|
|
210
207
|
? `window.HMR_WEBSOCKET_URL="ws://localhost:3001";`
|
|
211
208
|
: ""
|
|
212
|
-
|
|
209
|
+
}`,
|
|
213
210
|
});
|
|
214
211
|
} catch (err) {
|
|
215
212
|
console.error("Render error (no error.tsx?):", err);
|
|
@@ -223,14 +220,14 @@ async function renderToStream(
|
|
|
223
220
|
},
|
|
224
221
|
bootstrapModules: isDevelopment
|
|
225
222
|
? [
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
223
|
+
getAssetFromManifest("main.js"),
|
|
224
|
+
isWebpack ? undefined : getAssetFromManifest("runtime.js"),
|
|
225
|
+
].filter(Boolean)
|
|
229
226
|
: [getAssetFromManifest("main.js")],
|
|
230
227
|
...(isDevelopment
|
|
231
228
|
? {
|
|
232
|
-
|
|
233
|
-
|
|
229
|
+
bootstrapScriptContent: `window.HMR_WEBSOCKET_URL="ws://localhost:3001";`,
|
|
230
|
+
}
|
|
234
231
|
: {}),
|
|
235
232
|
});
|
|
236
233
|
} catch (error) {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
// public/server-function-proxy.js
|
|
2
1
|
import { createFromFetch } from "react-server-dom-webpack/client";
|
|
3
2
|
|
|
4
3
|
function createServerFunctionProxy(id) {
|
|
5
|
-
return new Proxy(() => {}, {
|
|
4
|
+
return new Proxy(() => { }, {
|
|
6
5
|
apply: async (_target, _thisArg, args) => {
|
|
7
6
|
let body;
|
|
8
7
|
const headers = {
|
|
@@ -39,7 +38,7 @@ function createServerFunctionProxy(id) {
|
|
|
39
38
|
const range = document.createRange();
|
|
40
39
|
const documentFragment = range.createContextualFragment(html);
|
|
41
40
|
document.body.appendChild(documentFragment);
|
|
42
|
-
return new Promise(() => {});
|
|
41
|
+
return new Promise(() => { });
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
// Case 2: RSC or Hybrid Stream (Buffered)
|