@withl5e/l5e 0.3.3-alpha.4 → 1.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/README.md +1 -1
- package/dist/action.js +10 -9
- package/dist/action.js.map +1 -1
- package/dist/defineMiddleware-D017PWDc.js +8 -0
- package/dist/defineMiddleware-D017PWDc.js.map +1 -0
- package/dist/entry-server.js +161 -176
- package/dist/entry-server.js.map +1 -1
- package/dist/exceptions-D4OdiQjY.js +30 -0
- package/dist/exceptions-D4OdiQjY.js.map +1 -0
- package/dist/generateMetadata-DcdY-XC1.js +303 -0
- package/dist/generateMetadata-DcdY-XC1.js.map +1 -0
- package/dist/global-style-BhiGjxVU.js +21 -0
- package/dist/global-style-BhiGjxVU.js.map +1 -0
- package/dist/i18n.js +8 -11
- package/dist/i18n.js.map +1 -1
- package/dist/index.js +9 -55
- package/dist/island/client.js +2 -5
- package/dist/island/runtime.js +90 -107
- package/dist/island/runtime.js.map +1 -1
- package/dist/island.js +38 -56
- package/dist/island.js.map +1 -1
- package/dist/jsx-runtime-CI0Jmr-C.js +275 -0
- package/dist/jsx-runtime-CI0Jmr-C.js.map +1 -0
- package/dist/jsx-runtime.js +2 -31
- package/dist/middleware-CnDqZobD.js +217 -0
- package/dist/middleware-CnDqZobD.js.map +1 -0
- package/dist/middleware.js +3 -8
- package/dist/render-hUQUreah.js +152 -0
- package/dist/render-hUQUreah.js.map +1 -0
- package/dist/rolldown-runtime-B0aSnxlc.js +20 -0
- package/dist/router.js +72 -68
- package/dist/router.js.map +1 -1
- package/dist/seo.js +3 -7
- package/dist/server-5BEwGAL4.js +461 -0
- package/dist/server-5BEwGAL4.js.map +1 -0
- package/dist/server.js +2 -515
- package/dist/strategy-registry-wmHnsHQb.js +9 -0
- package/dist/strategy-registry-wmHnsHQb.js.map +1 -0
- package/dist/swap/server.js +11 -14
- package/dist/swap/server.js.map +1 -1
- package/dist/swap.js +109 -116
- package/dist/swap.js.map +1 -1
- package/dist/tooltip.js +145 -141
- package/dist/tooltip.js.map +1 -1
- package/dist/vite-plugin.js +315 -372
- package/dist/vite-plugin.js.map +1 -1
- package/package.json +8 -8
- package/src/core/bundler.ts +41 -25
- package/src/core/vite-plugin.ts +14 -15
- package/dist/client-D67hK4Yy.js +0 -9
- package/dist/client-D67hK4Yy.js.map +0 -1
- package/dist/defineMiddleware-VdHQuiUc.js +0 -7
- package/dist/defineMiddleware-VdHQuiUc.js.map +0 -1
- package/dist/exceptions-CHPz01DJ.js +0 -39
- package/dist/exceptions-CHPz01DJ.js.map +0 -1
- package/dist/generateMetadata-Cn8BIxq6.js +0 -144
- package/dist/generateMetadata-Cn8BIxq6.js.map +0 -1
- package/dist/global-style-DFvaBcuR.js +0 -27
- package/dist/global-style-DFvaBcuR.js.map +0 -1
- package/dist/index-CybB8Tdk.js +0 -315
- package/dist/index-CybB8Tdk.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/island/client.js.map +0 -1
- package/dist/jsx-runtime-DqAp8xlt.js +0 -296
- package/dist/jsx-runtime-DqAp8xlt.js.map +0 -1
- package/dist/jsx-runtime.js.map +0 -1
- package/dist/middleware.js.map +0 -1
- package/dist/render-CRag-5V7.js +0 -202
- package/dist/render-CRag-5V7.js.map +0 -1
- package/dist/seo.js.map +0 -1
- package/dist/server.js.map +0 -1
package/README.md
CHANGED
package/dist/action.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
//#region src/action/define-action.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
return {
|
|
4
|
+
handler: e.handler,
|
|
5
|
+
method: e.method ?? "GET"
|
|
6
|
+
};
|
|
6
7
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
//# sourceMappingURL=action.js.map
|
|
8
|
+
//#endregion
|
|
9
|
+
export { e as defineAction };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=action.js.map
|
package/dist/action.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.js","sources":["../src/action/define-action.ts"],"sourcesContent":["import type { ActionOptions, Action } from './types';\n\nexport function defineAction(opts: ActionOptions): Action {\n return {\n handler: opts.handler,\n method: opts.method ?? 'GET',\n } as Action;\n}\n"],"
|
|
1
|
+
{"version":3,"file":"action.js","names":[],"sources":["../src/action/define-action.ts"],"sourcesContent":["import type { ActionOptions, Action } from './types';\n\nexport function defineAction(opts: ActionOptions): Action {\n return {\n handler: opts.handler,\n method: opts.method ?? 'GET',\n } as Action;\n}\n"],"mappings":";AAEA,SAAgB,EAAa,GAA6B;CACxD,OAAO;EACL,SAAS,EAAK;EACd,QAAQ,EAAK,UAAU;CACzB;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineMiddleware-D017PWDc.js","names":[],"sources":["../src/middleware/defineMiddleware.ts"],"sourcesContent":["import type { MiddlewareHandler } from './types';\n\nexport function defineMiddleware(fn: MiddlewareHandler): MiddlewareHandler {\n return fn;\n}\n"],"mappings":";AAEA,SAAgB,EAAiB,GAA0C;CACzE,OAAO;AACT"}
|
package/dist/entry-server.js
CHANGED
|
@@ -1,180 +1,165 @@
|
|
|
1
|
-
import { r as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
1
|
+
import { r as e } from "./rolldown-runtime-B0aSnxlc.js";
|
|
2
|
+
import { a as t, r as n } from "./render-hUQUreah.js";
|
|
3
|
+
import { C as r, S as i, _ as a, a as o, c as s, d as c, f as l, h as u, k as d, l as f, n as p, o as m, r as h, s as g, u as _, v } from "./jsx-runtime-CI0Jmr-C.js";
|
|
4
|
+
import { t as y } from "./generateMetadata-DcdY-XC1.js";
|
|
5
|
+
import { a as b, i as x, n as S, o as C, r as w } from "./exceptions-D4OdiQjY.js";
|
|
6
|
+
import { viewComponents as T, viewLoaders as E } from "virtual:l5e-views";
|
|
7
|
+
import D from "virtual:l5e-route";
|
|
7
8
|
import { globalLoader as O } from "virtual:l5e-global-loader";
|
|
8
|
-
import { loadMiddleware as
|
|
9
|
-
import { islandModules as
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
s = s.replace(`<!--${t.token}-->`, () => p).replace(`data-island-ssr="${t.token}"`, 'data-island-ssr="1"');
|
|
35
|
-
} catch (a) {
|
|
36
|
-
console.error(`[l5e-island] Failed to SSR island "${t.name}":`, a), s = s.replace(`<!--${t.token}-->`, "").replace(` data-island-ssr="${t.token}"`, "");
|
|
37
|
-
}
|
|
38
|
-
return s;
|
|
9
|
+
import { loadMiddleware as k } from "virtual:l5e-middleware";
|
|
10
|
+
import { islandModules as A } from "virtual:l5e-islands";
|
|
11
|
+
//#region src/core/entry-server.ts
|
|
12
|
+
var j = /* @__PURE__ */ e(t(), 1);
|
|
13
|
+
async function M(e) {
|
|
14
|
+
let t = l();
|
|
15
|
+
if (t.length === 0) return e;
|
|
16
|
+
let n, r;
|
|
17
|
+
try {
|
|
18
|
+
[{renderToString: n}, {createElement: r}] = await Promise.all([import("react-dom/server"), import("react")]);
|
|
19
|
+
} catch (n) {
|
|
20
|
+
console.error("[l5e-island] SSR requires react-dom/server + react:", n);
|
|
21
|
+
for (let n of t) e = e.replace(`<!--${n.token}-->`, "").replace(` data-island-ssr="${n.token}"`, "");
|
|
22
|
+
return e;
|
|
23
|
+
}
|
|
24
|
+
for (let i of t) try {
|
|
25
|
+
let t = A["/" + i.src];
|
|
26
|
+
if (!t) throw Error(`island module not found in glob: /${i.src}`);
|
|
27
|
+
let a = await t(), o = a[i.name] ?? a.default;
|
|
28
|
+
if (!o) throw Error(`no export "${i.name}" or default in /${i.src}`);
|
|
29
|
+
let s = n(r(o, i.props));
|
|
30
|
+
e = e.replace(`<!--${i.token}-->`, () => s).replace(`data-island-ssr="${i.token}"`, "data-island-ssr=\"1\"");
|
|
31
|
+
} catch (t) {
|
|
32
|
+
console.error(`[l5e-island] Failed to SSR island "${i.name}":`, t), e = e.replace(`<!--${i.token}-->`, "").replace(` data-island-ssr="${i.token}"`, "");
|
|
33
|
+
}
|
|
34
|
+
return e;
|
|
39
35
|
}
|
|
40
|
-
async function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
36
|
+
async function N(e, t) {
|
|
37
|
+
let i = "_error", a = `/src/views/${i}/index.tsx`;
|
|
38
|
+
r(i);
|
|
39
|
+
let o = T[a] ? await T[a]() : null;
|
|
40
|
+
if (o?.default) {
|
|
41
|
+
let r = {
|
|
42
|
+
statusCode: e.statusCode,
|
|
43
|
+
message: e.message,
|
|
44
|
+
data: e.data
|
|
45
|
+
}, i = o.default, a = n(u(i, r)), c = m(), l = g(), d = s(), f = d.length > 0 ? d.map((e) => n(e)).join("\n ") : void 0;
|
|
46
|
+
return {
|
|
47
|
+
html: a,
|
|
48
|
+
scripts: c.map((e) => e.path),
|
|
49
|
+
styles: l.map((e) => e.path),
|
|
50
|
+
head: f,
|
|
51
|
+
lang: t,
|
|
52
|
+
statusCode: e.statusCode
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
{
|
|
56
|
+
let t = u("div", {}, `${e.statusCode} - ${e.message}`);
|
|
57
|
+
return {
|
|
58
|
+
html: n(t),
|
|
59
|
+
statusCode: e.statusCode
|
|
60
|
+
};
|
|
61
|
+
}
|
|
66
62
|
}
|
|
67
|
-
async function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return await V(t);
|
|
166
|
-
console.error("Failed to render:", t);
|
|
167
|
-
const n = process.env.NODE_ENV === "production" ? new k("Internal Server Error") : new k(t.message || "Internal Server Error", {
|
|
168
|
-
originalError: t.name,
|
|
169
|
-
stack: t.stack,
|
|
170
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
171
|
-
});
|
|
172
|
-
return await V(n);
|
|
173
|
-
}
|
|
174
|
-
}, o, void 0, { externalizeIslandProps: d });
|
|
63
|
+
async function P(e, t = {}, l = {}) {
|
|
64
|
+
let k = l.externalizeIslandProps ?? !0;
|
|
65
|
+
return i(async () => {
|
|
66
|
+
try {
|
|
67
|
+
let e = await D(t);
|
|
68
|
+
if (!e) throw new x("Page not found", {
|
|
69
|
+
path: t.path,
|
|
70
|
+
pathname: t.pathname,
|
|
71
|
+
url: t.url?.href
|
|
72
|
+
});
|
|
73
|
+
let i = typeof e == "string" ? e : e.view;
|
|
74
|
+
t.params = typeof e == "string" ? {} : e.params ?? {}, r(i);
|
|
75
|
+
let l = {}, b, S = "/src/global-loader.ts", C = O[S] ? await O[S]() : null;
|
|
76
|
+
if (C?.loader) {
|
|
77
|
+
if (C.shouldIgnore?.(i)) console.info(`Global loader ignored for view: ${i}`);
|
|
78
|
+
else {
|
|
79
|
+
let e = await C.loader(t);
|
|
80
|
+
l = e.props || {}, b = e.lang, e.cacheTags && h(e.cacheTags);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let k = {}, A, N, P, F = !1, I = `/src/views/${i}/loader.ts`, L = E[I] ? await E[I]() : null;
|
|
84
|
+
if (L?.loader) {
|
|
85
|
+
let e = await L.loader(t);
|
|
86
|
+
if (e.rawResponse) return {
|
|
87
|
+
rawResponse: e.rawResponse,
|
|
88
|
+
statusCode: e.rawResponse.statusCode || 200
|
|
89
|
+
};
|
|
90
|
+
k = e.props || {}, A = e.maxAge, N = e.sMaxAge, P = e.swr, F = e.rawHtml || !1, e.cacheTags && h(e.cacheTags), e.lang && (b = e.lang);
|
|
91
|
+
} else console.info(`No loader for view: ${i}`);
|
|
92
|
+
let R = {
|
|
93
|
+
...l,
|
|
94
|
+
...k
|
|
95
|
+
};
|
|
96
|
+
if (C?.generateMetadata) {
|
|
97
|
+
let e = C.generateMetadata(t, R);
|
|
98
|
+
e && a(e);
|
|
99
|
+
}
|
|
100
|
+
if (L?.generateMetadata) {
|
|
101
|
+
let e = L.generateMetadata(t, R);
|
|
102
|
+
e && a(e);
|
|
103
|
+
}
|
|
104
|
+
if (C?.generateSchema) {
|
|
105
|
+
let e = C.generateSchema(t, R);
|
|
106
|
+
e && v(e);
|
|
107
|
+
}
|
|
108
|
+
if (L?.generateSchema) {
|
|
109
|
+
let e = L.generateSchema(t, R);
|
|
110
|
+
e && v(e);
|
|
111
|
+
}
|
|
112
|
+
let z = `/src/views/${i}/index.tsx`, B = (T[z] ? await T[z]() : null)?.default;
|
|
113
|
+
if (!B) throw console.error(`View component not found: ${i}`), process.env.NODE_ENV === "production" ? new w("Internal Server Error") : new w(`View component not found: "${i}"`, {
|
|
114
|
+
viewName: i,
|
|
115
|
+
expectedPath: z,
|
|
116
|
+
availableViews: Object.keys(T),
|
|
117
|
+
hint: `Make sure the view component exists at ${z} and exports a default component`,
|
|
118
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
119
|
+
});
|
|
120
|
+
n(u(y, {})), c().forEach((e) => {
|
|
121
|
+
let t = (0, j.default)(e, { isJSON: !0 });
|
|
122
|
+
p({
|
|
123
|
+
priority: d.SEO,
|
|
124
|
+
children: u("script", {
|
|
125
|
+
type: "application/ld+json",
|
|
126
|
+
setHtml: t
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
let V = n(u(B, R));
|
|
131
|
+
V = await M(V);
|
|
132
|
+
let H = m(), U = g(), W = f(), G = _(), K = o(), q = s(), J = q.length > 0 ? q.map((e) => n(e)).join("\n ") : void 0;
|
|
133
|
+
return {
|
|
134
|
+
html: V,
|
|
135
|
+
scripts: H.map((e) => e.path),
|
|
136
|
+
styles: U.map((e) => e.path),
|
|
137
|
+
islands: W.length > 0 ? W : void 0,
|
|
138
|
+
islandData: G.length > 0 ? G : void 0,
|
|
139
|
+
head: J,
|
|
140
|
+
lang: b,
|
|
141
|
+
maxAge: A,
|
|
142
|
+
sMaxAge: N,
|
|
143
|
+
swr: P,
|
|
144
|
+
cacheTags: K,
|
|
145
|
+
rawHtml: F
|
|
146
|
+
};
|
|
147
|
+
} catch (e) {
|
|
148
|
+
return e instanceof b ? {
|
|
149
|
+
html: "",
|
|
150
|
+
redirect: {
|
|
151
|
+
url: e.url,
|
|
152
|
+
statusCode: e.statusCode
|
|
153
|
+
}
|
|
154
|
+
} : e instanceof S ? await N(e) : (console.error("Failed to render:", e), await N(process.env.NODE_ENV === "production" ? new C("Internal Server Error") : new C(e.message || "Internal Server Error", {
|
|
155
|
+
originalError: e.name,
|
|
156
|
+
stack: e.stack,
|
|
157
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
158
|
+
})));
|
|
159
|
+
}
|
|
160
|
+
}, t, void 0, { externalizeIslandProps: k });
|
|
175
161
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
//# sourceMappingURL=entry-server.js.map
|
|
162
|
+
//#endregion
|
|
163
|
+
export { k as loadMiddleware, P as render };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=entry-server.js.map
|
package/dist/entry-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-server.js","sources":["../src/core/entry-server.ts"],"sourcesContent":["/// <reference path=\"./jsx-types.d.ts\" />\nimport serialize from 'serialize-javascript';\nimport { MetadataRenderer } from '../seo/generateMetadata';\nimport type { Metadata } from '../seo/types';\nimport {\n HttpException,\n InternalServerErrorException,\n NotFoundException,\n RedirectException,\n ServiceUnavailableException,\n} from './exceptions';\nimport { HEAD_PRIORITY } from './head-priority';\nimport {\n addCacheTag,\n getCacheTags,\n getClientJsEntries,\n getCssEntries,\n getHeadContent,\n getIslandEntries,\n getIslandProps,\n getSchemas,\n getSsrIslands,\n jsxFactory as h,\n Head,\n pushMetadata,\n pushSchema,\n runInRenderContext,\n setViewName,\n} from './jsx-runtime';\nimport { renderJsxToHtmlString } from './render';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { viewComponents, viewLoaders } from 'virtual:l5e-views';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport routeHandler from 'virtual:l5e-route';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { globalLoader } from 'virtual:l5e-global-loader';\n// @ts-ignore - Virtual modules provided by Vite plugin\nexport { loadMiddleware } from 'virtual:l5e-middleware';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { islandModules } from 'virtual:l5e-islands';\n\n/**\n * Fill `ssr` island placeholders with server-rendered HTML.\n *\n * During the synchronous render pass, each `<ClientIsland ssr>` emits a unique\n * token (as `<!--token-->` body + `data-island-ssr=\"token\"`). Here — after the\n * pass — we can `await import()` the actual React component and renderToString it,\n * then string-replace the token. Only islands present on this page are imported.\n *\n * On failure we strip both the token and the `data-island-ssr` attribute so the\n * client cleanly falls back to a client-only mount (no hydration mismatch).\n */\nasync function fillSsrIslands(htmlBody: string): Promise<string> {\n const pending = getSsrIslands();\n if (pending.length === 0) return htmlBody;\n\n let renderToString: (el: any) => string;\n let createElement: (type: any, props: any) => any;\n try {\n [{ renderToString }, { createElement }] = await Promise.all([\n import('react-dom/server'),\n import('react'),\n ]);\n } catch (err) {\n console.error('[l5e-island] SSR requires react-dom/server + react:', err);\n // Strip every pending token/attr → client-only fallback for all.\n for (const island of pending) {\n htmlBody = htmlBody\n .replace(`<!--${island.token}-->`, '')\n .replace(` data-island-ssr=\"${island.token}\"`, '');\n }\n return htmlBody;\n }\n\n for (const island of pending) {\n try {\n const loader = islandModules['/' + island.src];\n if (!loader) {\n throw new Error(`island module not found in glob: /${island.src}`);\n }\n const mod: any = await loader();\n const Component = mod[island.name] ?? mod.default;\n if (!Component) {\n throw new Error(`no export \"${island.name}\" or default in /${island.src}`);\n }\n const out = renderToString(createElement(Component, island.props));\n // Replacer fn (not a string) so `$`-sequences in `out` (e.g. \"$&\", \"$$\")\n // aren't interpreted as special replacement patterns.\n htmlBody = htmlBody\n .replace(`<!--${island.token}-->`, () => out)\n .replace(`data-island-ssr=\"${island.token}\"`, 'data-island-ssr=\"1\"');\n } catch (err) {\n console.error(`[l5e-island] Failed to SSR island \"${island.name}\":`, err);\n htmlBody = htmlBody\n .replace(`<!--${island.token}-->`, '')\n .replace(` data-island-ssr=\"${island.token}\"`, '');\n }\n }\n\n return htmlBody;\n}\n\nexport interface RawResponse {\n body: string | Buffer;\n contentType: string;\n statusCode?: number;\n headers?: Record<string, string>;\n}\n\nexport interface RenderResult {\n html?: string;\n scripts?: string[];\n styles?: string[];\n islands?: Array<{ key: string; src: string; name: string }>;\n /**\n * Externalized island props (index === element's `data-island-idx`). Present\n * only in externalized mode; createPageResponse serializes it into the\n * `<script id=\"_l5e_data_\">` at the end of the document.\n */\n islandData?: unknown[];\n head?: string;\n lang?: string;\n statusCode?: number;\n maxAge?: number;\n sMaxAge?: number;\n swr?: number;\n cacheTags?: string[];\n redirect?: { url: string; statusCode: number };\n rawResponse?: RawResponse;\n rawHtml?: boolean;\n}\n\nexport interface RequestInfo {\n url?: URL;\n path?: string;\n pathname?: string;\n method?: string;\n headers?: Record<string, any>;\n cookies?: Record<string, string>;\n query?: Record<string, any>;\n ip?: string;\n locals?: Record<string, unknown>;\n params?: Record<string, any>;\n}\n\nexport type RouteResult =\n | string\n | null\n | { view: string; params?: Record<string, any> };\n\n// SchemaMarkup type - có thể là single schema hoặc array of schemas\n// Sử dụng any để tương thích với schema-dts types từ frontend\nexport type SchemaMarkup = any | Array<any>;\n\nexport interface LoaderResult {\n props?: Record<string, any>;\n lang?: string;\n\n /**\n * Browser, CDN max-age\n */\n maxAge?: number;\n\n /**\n * CDN max-age\n */\n sMaxAge?: number;\n\n /**\n * CDN stale-while-revalidate, browser must revalidate\n */\n swr?: number;\n cacheTags?: string[] | Record<string, boolean>;\n rawResponse?: RawResponse;\n rawHtml?: boolean;\n}\n\nexport type LoaderFunction = (requestInfo: RequestInfo) => Promise<LoaderResult>;\n\nexport type GenerateMetadataFunction = (requestInfo: RequestInfo, props: any) => Metadata | null;\n\nexport type GenerateSchemaFunction = (requestInfo: RequestInfo, props: any) => SchemaMarkup | null;\n\nexport interface GlobalLoaderModule {\n loader: LoaderFunction;\n generateMetadata?: GenerateMetadataFunction;\n generateSchema?: GenerateSchemaFunction;\n shouldIgnore?: (viewName: string) => boolean;\n}\n\n/**\n * Helper function to render error view\n */\nasync function renderErrorView(err: HttpException, lang?: string): Promise<RenderResult> {\n const errorViewName = `_error`;\n const errorComponentPath = `/src/views/${errorViewName}/index.tsx`;\n\n // Set error view name in context\n setViewName(errorViewName);\n\n // Try to load error view\n const errorComponentModule = viewComponents[errorComponentPath]\n ? await viewComponents[errorComponentPath]()\n : null;\n\n if (errorComponentModule?.default) {\n // Render error view with exception data\n const errorProps = {\n statusCode: err.statusCode,\n message: err.message,\n data: err.data,\n };\n\n const Component = errorComponentModule.default;\n const htmlBody = renderJsxToHtmlString(h(Component, errorProps));\n const clientEntries = getClientJsEntries();\n const cssEntries = getCssEntries();\n const headContent = getHeadContent();\n\n const headHtml =\n headContent.length > 0\n ? headContent.map((content) => renderJsxToHtmlString(content)).join('\\n ')\n : undefined;\n\n return {\n html: htmlBody,\n scripts: clientEntries.map((entry) => entry.path),\n styles: cssEntries.map((entry) => entry.path),\n head: headHtml,\n lang,\n statusCode: err.statusCode,\n };\n } else {\n // No error view found, render default error message\n const html = h('div', {}, `${err.statusCode} - ${err.message}`);\n return {\n html: renderJsxToHtmlString(html),\n statusCode: err.statusCode,\n };\n }\n}\n\nexport interface RenderOptions {\n /**\n * Externalize island props into the trailing `_l5e_data_` script instead of\n * inlining `data-island-props` on each element. Default true.\n */\n externalizeIslandProps?: boolean;\n}\n\nexport async function render(\n url: string,\n requestInfo: RequestInfo = {},\n options: RenderOptions = {},\n): Promise<RenderResult> {\n const externalizeIslandProps = options.externalizeIslandProps ?? true;\n return runInRenderContext(async () => {\n try {\n // Step 1: Call route handler to get view name\n const rawRouteResult: RouteResult = await routeHandler(requestInfo);\n\n if (!rawRouteResult) {\n // Throw NotFoundException to render error_404 view\n throw new NotFoundException('Page not found', {\n path: requestInfo.path,\n pathname: requestInfo.pathname,\n url: requestInfo.url?.href,\n });\n }\n\n const viewName =\n typeof rawRouteResult === 'string' ? rawRouteResult : rawRouteResult.view;\n requestInfo.params =\n typeof rawRouteResult === 'string' ? {} : (rawRouteResult.params ?? {});\n\n // Set view name in render context\n setViewName(viewName);\n\n // Step 2: Load global loader (optional)\n let globalProps: Record<string, any> = {};\n let lang: string | undefined;\n\n // Try to load global loader\n const globalLoaderPathTs = '/src/global-loader.ts';\n\n const globalLoaderModule: GlobalLoaderModule | null = globalLoader[globalLoaderPathTs]\n ? await globalLoader[globalLoaderPathTs]()\n : null;\n\n // Run global loader if exists and not ignored\n if (globalLoaderModule?.loader) {\n const shouldIgnore = globalLoaderModule.shouldIgnore?.(viewName) || false;\n\n if (!shouldIgnore) {\n const globalLoaderResult = await globalLoaderModule.loader(requestInfo);\n\n globalProps = globalLoaderResult.props || {};\n lang = globalLoaderResult.lang; // Extract lang from global loader\n\n if (globalLoaderResult.cacheTags) {\n addCacheTag(globalLoaderResult.cacheTags);\n }\n\n // generateMetadata và generateSchema sẽ được gọi sau khi có props\n } else {\n console.info(`Global loader ignored for view: ${viewName}`);\n }\n }\n\n // Step 3: Dynamic import view loader (optional)\n let viewProps: Record<string, any> = {};\n let maxAge: number | undefined;\n let sMaxAge: number | undefined;\n let swr: number | undefined;\n let rawHtml: boolean = false;\n const loaderPathTs = `/src/views/${viewName}/loader.ts`;\n\n // Try TypeScript loader formats only\n const loaderModule = viewLoaders[loaderPathTs] ? await viewLoaders[loaderPathTs]() : null;\n\n if (loaderModule?.loader) {\n const loaderResult = await loaderModule.loader(requestInfo);\n\n // Check if loader returns raw response\n if (loaderResult.rawResponse) {\n return {\n rawResponse: loaderResult.rawResponse,\n statusCode: loaderResult.rawResponse.statusCode || 200,\n };\n }\n\n viewProps = loaderResult.props || {};\n maxAge = loaderResult.maxAge;\n sMaxAge = loaderResult.sMaxAge;\n swr = loaderResult.swr;\n rawHtml = loaderResult.rawHtml || false;\n\n if (loaderResult.cacheTags) {\n addCacheTag(loaderResult.cacheTags);\n }\n\n // View loader lang overrides global loader lang\n if (loaderResult.lang) {\n lang = loaderResult.lang;\n }\n } else {\n console.info(`No loader for view: ${viewName}`);\n }\n\n // Merge props: global props first, then view props (view can override)\n const props = { ...globalProps, ...viewProps };\n\n // Step 3.5: Generate metadata và schema từ generateMetadata và generateSchema functions\n // Global generateMetadata (parent metadata)\n if (globalLoaderModule?.generateMetadata) {\n const globalMetadata = globalLoaderModule.generateMetadata(requestInfo, props);\n if (globalMetadata) {\n pushMetadata(globalMetadata);\n }\n }\n\n // View generateMetadata (child metadata, sẽ merge với parent)\n if (loaderModule?.generateMetadata) {\n const viewMetadata = loaderModule.generateMetadata(requestInfo, props);\n if (viewMetadata) {\n pushMetadata(viewMetadata);\n }\n }\n\n // Global generateSchema (base schemas)\n if (globalLoaderModule?.generateSchema) {\n const globalSchema = globalLoaderModule.generateSchema(requestInfo, props);\n if (globalSchema) {\n pushSchema(globalSchema);\n }\n }\n\n // View generateSchema (view-specific schemas)\n if (loaderModule?.generateSchema) {\n const viewSchema = loaderModule.generateSchema(requestInfo, props);\n if (viewSchema) {\n pushSchema(viewSchema);\n }\n }\n\n // Step 4: Dynamic import component (required)\n const componentPathTsx = `/src/views/${viewName}/index.tsx`;\n\n const componentModule = viewComponents[componentPathTsx]\n ? await viewComponents[componentPathTsx]()\n : null;\n\n const Component = componentModule?.default;\n\n if (!Component) {\n console.error(`View component not found: ${viewName}`);\n\n // Check if in development or production mode\n const isDevelopment = process.env.NODE_ENV !== 'production';\n\n if (isDevelopment) {\n // Development: provide detailed error information\n throw new InternalServerErrorException(`View component not found: \"${viewName}\"`, {\n viewName,\n expectedPath: componentPathTsx,\n availableViews: Object.keys(viewComponents),\n hint: `Make sure the view component exists at ${componentPathTsx} and exports a default component`,\n timestamp: new Date().toISOString(),\n });\n } else {\n // Production: simple error message\n throw new InternalServerErrorException('Internal Server Error');\n }\n }\n\n // Auto-render MetadataRenderer trước khi render component\n // MetadataRenderer sẽ push metadata vào headRegistry thông qua Head component\n renderJsxToHtmlString(h(MetadataRenderer, {}));\n\n // Auto-render schemas vào headRegistry\n const schemas = getSchemas();\n schemas.forEach((schema) => {\n // serialize-javascript escapes HTML-sensitive chars (<, >, &, U+2028/2029)\n // so schema values cannot break out of the <script> block (XSS).\n const schemaJson = serialize(schema, { isJSON: true });\n // Push schema vào headRegistry thông qua Head component\n // Head component chỉ push vào registry, không cần renderJsxToHtmlString\n Head({\n priority: HEAD_PRIORITY.SEO,\n children: h('script', {\n type: 'application/ld+json',\n setHtml: schemaJson,\n }),\n });\n });\n\n // Render component (có thể có Head components khác)\n let htmlBody = renderJsxToHtmlString(h(Component, props));\n // Fill any opt-in `ssr` island placeholders with server-rendered React HTML.\n htmlBody = await fillSsrIslands(htmlBody);\n const clientEntries = getClientJsEntries();\n const cssEntries = getCssEntries();\n const islandEntries = getIslandEntries();\n const islandData = getIslandProps();\n const cacheTags = getCacheTags();\n const headContent = getHeadContent();\n\n // Render head content to HTML string\n const headHtml =\n headContent.length > 0\n ? headContent.map((content) => renderJsxToHtmlString(content)).join('\\n ')\n : undefined;\n\n return {\n html: htmlBody,\n scripts: clientEntries.map((entry) => entry.path),\n styles: cssEntries.map((entry) => entry.path),\n islands: islandEntries.length > 0 ? islandEntries : undefined,\n islandData: islandData.length > 0 ? islandData : undefined,\n head: headHtml,\n lang,\n maxAge,\n sMaxAge,\n swr,\n cacheTags,\n rawHtml,\n };\n } catch (err: any) {\n // Handle RedirectException\n if (err instanceof RedirectException) {\n return {\n html: '',\n redirect: {\n url: err.url,\n statusCode: err.statusCode,\n },\n };\n }\n\n // Handle HttpException\n if (err instanceof HttpException) {\n return await renderErrorView(err);\n }\n\n // For other (unexpected) errors, convert to ServiceUnavailableException.\n // Intentional HttpExceptions above keep their developer-authored message;\n // but an unexpected error's raw message/stack must not leak to the client\n // in production (it can carry internals, secrets, etc.). Dev keeps detail.\n console.error(`Failed to render:`, err);\n const isProduction = process.env.NODE_ENV === 'production';\n const serviceError = isProduction\n ? new ServiceUnavailableException('Internal Server Error')\n : new ServiceUnavailableException(err.message || 'Internal Server Error', {\n originalError: err.name,\n stack: err.stack,\n timestamp: new Date().toISOString(),\n });\n return await renderErrorView(serviceError);\n }\n }, requestInfo, undefined, { externalizeIslandProps });\n}\n"],"names":["fillSsrIslands","htmlBody","pending","getSsrIslands","renderToString","createElement","err","island","loader","islandModules","mod","Component","out","renderErrorView","lang","errorViewName","errorComponentPath","setViewName","errorComponentModule","viewComponents","errorProps","renderJsxToHtmlString","h","clientEntries","getClientJsEntries","cssEntries","getCssEntries","headContent","getHeadContent","headHtml","content","entry","html","render","url","requestInfo","options","externalizeIslandProps","runInRenderContext","rawRouteResult","routeHandler","NotFoundException","viewName","globalProps","globalLoaderPathTs","globalLoaderModule","globalLoader","globalLoaderResult","addCacheTag","viewProps","maxAge","sMaxAge","swr","rawHtml","loaderPathTs","loaderModule","viewLoaders","loaderResult","props","globalMetadata","pushMetadata","viewMetadata","globalSchema","pushSchema","viewSchema","componentPathTsx","InternalServerErrorException","MetadataRenderer","getSchemas","schema","schemaJson","serialize","Head","HEAD_PRIORITY","islandEntries","getIslandEntries","islandData","getIslandProps","cacheTags","getCacheTags","RedirectException","HttpException","serviceError","ServiceUnavailableException"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"entry-server.js","names":["h","serialize"],"sources":["../src/core/entry-server.ts"],"sourcesContent":["/// <reference path=\"./jsx-types.d.ts\" />\nimport serialize from 'serialize-javascript';\nimport { MetadataRenderer } from '../seo/generateMetadata';\nimport type { Metadata } from '../seo/types';\nimport {\n HttpException,\n InternalServerErrorException,\n NotFoundException,\n RedirectException,\n ServiceUnavailableException,\n} from './exceptions';\nimport { HEAD_PRIORITY } from './head-priority';\nimport {\n addCacheTag,\n getCacheTags,\n getClientJsEntries,\n getCssEntries,\n getHeadContent,\n getIslandEntries,\n getIslandProps,\n getSchemas,\n getSsrIslands,\n jsxFactory as h,\n Head,\n pushMetadata,\n pushSchema,\n runInRenderContext,\n setViewName,\n} from './jsx-runtime';\nimport { renderJsxToHtmlString } from './render';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { viewComponents, viewLoaders } from 'virtual:l5e-views';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport routeHandler from 'virtual:l5e-route';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { globalLoader } from 'virtual:l5e-global-loader';\n// @ts-ignore - Virtual modules provided by Vite plugin\nexport { loadMiddleware } from 'virtual:l5e-middleware';\n// @ts-ignore - Virtual modules provided by Vite plugin\nimport { islandModules } from 'virtual:l5e-islands';\n\n/**\n * Fill `ssr` island placeholders with server-rendered HTML.\n *\n * During the synchronous render pass, each `<ClientIsland ssr>` emits a unique\n * token (as `<!--token-->` body + `data-island-ssr=\"token\"`). Here — after the\n * pass — we can `await import()` the actual React component and renderToString it,\n * then string-replace the token. Only islands present on this page are imported.\n *\n * On failure we strip both the token and the `data-island-ssr` attribute so the\n * client cleanly falls back to a client-only mount (no hydration mismatch).\n */\nasync function fillSsrIslands(htmlBody: string): Promise<string> {\n const pending = getSsrIslands();\n if (pending.length === 0) return htmlBody;\n\n let renderToString: (el: any) => string;\n let createElement: (type: any, props: any) => any;\n try {\n [{ renderToString }, { createElement }] = await Promise.all([\n import('react-dom/server'),\n import('react'),\n ]);\n } catch (err) {\n console.error('[l5e-island] SSR requires react-dom/server + react:', err);\n // Strip every pending token/attr → client-only fallback for all.\n for (const island of pending) {\n htmlBody = htmlBody\n .replace(`<!--${island.token}-->`, '')\n .replace(` data-island-ssr=\"${island.token}\"`, '');\n }\n return htmlBody;\n }\n\n for (const island of pending) {\n try {\n const loader = islandModules['/' + island.src];\n if (!loader) {\n throw new Error(`island module not found in glob: /${island.src}`);\n }\n const mod: any = await loader();\n const Component = mod[island.name] ?? mod.default;\n if (!Component) {\n throw new Error(`no export \"${island.name}\" or default in /${island.src}`);\n }\n const out = renderToString(createElement(Component, island.props));\n // Replacer fn (not a string) so `$`-sequences in `out` (e.g. \"$&\", \"$$\")\n // aren't interpreted as special replacement patterns.\n htmlBody = htmlBody\n .replace(`<!--${island.token}-->`, () => out)\n .replace(`data-island-ssr=\"${island.token}\"`, 'data-island-ssr=\"1\"');\n } catch (err) {\n console.error(`[l5e-island] Failed to SSR island \"${island.name}\":`, err);\n htmlBody = htmlBody\n .replace(`<!--${island.token}-->`, '')\n .replace(` data-island-ssr=\"${island.token}\"`, '');\n }\n }\n\n return htmlBody;\n}\n\nexport interface RawResponse {\n body: string | Buffer;\n contentType: string;\n statusCode?: number;\n headers?: Record<string, string>;\n}\n\nexport interface RenderResult {\n html?: string;\n scripts?: string[];\n styles?: string[];\n islands?: Array<{ key: string; src: string; name: string }>;\n /**\n * Externalized island props (index === element's `data-island-idx`). Present\n * only in externalized mode; createPageResponse serializes it into the\n * `<script id=\"_l5e_data_\">` at the end of the document.\n */\n islandData?: unknown[];\n head?: string;\n lang?: string;\n statusCode?: number;\n maxAge?: number;\n sMaxAge?: number;\n swr?: number;\n cacheTags?: string[];\n redirect?: { url: string; statusCode: number };\n rawResponse?: RawResponse;\n rawHtml?: boolean;\n}\n\nexport interface RequestInfo {\n url?: URL;\n path?: string;\n pathname?: string;\n method?: string;\n headers?: Record<string, any>;\n cookies?: Record<string, string>;\n query?: Record<string, any>;\n ip?: string;\n locals?: Record<string, unknown>;\n params?: Record<string, any>;\n}\n\nexport type RouteResult =\n | string\n | null\n | { view: string; params?: Record<string, any> };\n\n// SchemaMarkup type - có thể là single schema hoặc array of schemas\n// Sử dụng any để tương thích với schema-dts types từ frontend\nexport type SchemaMarkup = any | Array<any>;\n\nexport interface LoaderResult {\n props?: Record<string, any>;\n lang?: string;\n\n /**\n * Browser, CDN max-age\n */\n maxAge?: number;\n\n /**\n * CDN max-age\n */\n sMaxAge?: number;\n\n /**\n * CDN stale-while-revalidate, browser must revalidate\n */\n swr?: number;\n cacheTags?: string[] | Record<string, boolean>;\n rawResponse?: RawResponse;\n rawHtml?: boolean;\n}\n\nexport type LoaderFunction = (requestInfo: RequestInfo) => Promise<LoaderResult>;\n\nexport type GenerateMetadataFunction = (requestInfo: RequestInfo, props: any) => Metadata | null;\n\nexport type GenerateSchemaFunction = (requestInfo: RequestInfo, props: any) => SchemaMarkup | null;\n\nexport interface GlobalLoaderModule {\n loader: LoaderFunction;\n generateMetadata?: GenerateMetadataFunction;\n generateSchema?: GenerateSchemaFunction;\n shouldIgnore?: (viewName: string) => boolean;\n}\n\n/**\n * Helper function to render error view\n */\nasync function renderErrorView(err: HttpException, lang?: string): Promise<RenderResult> {\n const errorViewName = `_error`;\n const errorComponentPath = `/src/views/${errorViewName}/index.tsx`;\n\n // Set error view name in context\n setViewName(errorViewName);\n\n // Try to load error view\n const errorComponentModule = viewComponents[errorComponentPath]\n ? await viewComponents[errorComponentPath]()\n : null;\n\n if (errorComponentModule?.default) {\n // Render error view with exception data\n const errorProps = {\n statusCode: err.statusCode,\n message: err.message,\n data: err.data,\n };\n\n const Component = errorComponentModule.default;\n const htmlBody = renderJsxToHtmlString(h(Component, errorProps));\n const clientEntries = getClientJsEntries();\n const cssEntries = getCssEntries();\n const headContent = getHeadContent();\n\n const headHtml =\n headContent.length > 0\n ? headContent.map((content) => renderJsxToHtmlString(content)).join('\\n ')\n : undefined;\n\n return {\n html: htmlBody,\n scripts: clientEntries.map((entry) => entry.path),\n styles: cssEntries.map((entry) => entry.path),\n head: headHtml,\n lang,\n statusCode: err.statusCode,\n };\n } else {\n // No error view found, render default error message\n const html = h('div', {}, `${err.statusCode} - ${err.message}`);\n return {\n html: renderJsxToHtmlString(html),\n statusCode: err.statusCode,\n };\n }\n}\n\nexport interface RenderOptions {\n /**\n * Externalize island props into the trailing `_l5e_data_` script instead of\n * inlining `data-island-props` on each element. Default true.\n */\n externalizeIslandProps?: boolean;\n}\n\nexport async function render(\n url: string,\n requestInfo: RequestInfo = {},\n options: RenderOptions = {},\n): Promise<RenderResult> {\n const externalizeIslandProps = options.externalizeIslandProps ?? true;\n return runInRenderContext(async () => {\n try {\n // Step 1: Call route handler to get view name\n const rawRouteResult: RouteResult = await routeHandler(requestInfo);\n\n if (!rawRouteResult) {\n // Throw NotFoundException to render error_404 view\n throw new NotFoundException('Page not found', {\n path: requestInfo.path,\n pathname: requestInfo.pathname,\n url: requestInfo.url?.href,\n });\n }\n\n const viewName =\n typeof rawRouteResult === 'string' ? rawRouteResult : rawRouteResult.view;\n requestInfo.params =\n typeof rawRouteResult === 'string' ? {} : (rawRouteResult.params ?? {});\n\n // Set view name in render context\n setViewName(viewName);\n\n // Step 2: Load global loader (optional)\n let globalProps: Record<string, any> = {};\n let lang: string | undefined;\n\n // Try to load global loader\n const globalLoaderPathTs = '/src/global-loader.ts';\n\n const globalLoaderModule: GlobalLoaderModule | null = globalLoader[globalLoaderPathTs]\n ? await globalLoader[globalLoaderPathTs]()\n : null;\n\n // Run global loader if exists and not ignored\n if (globalLoaderModule?.loader) {\n const shouldIgnore = globalLoaderModule.shouldIgnore?.(viewName) || false;\n\n if (!shouldIgnore) {\n const globalLoaderResult = await globalLoaderModule.loader(requestInfo);\n\n globalProps = globalLoaderResult.props || {};\n lang = globalLoaderResult.lang; // Extract lang from global loader\n\n if (globalLoaderResult.cacheTags) {\n addCacheTag(globalLoaderResult.cacheTags);\n }\n\n // generateMetadata và generateSchema sẽ được gọi sau khi có props\n } else {\n console.info(`Global loader ignored for view: ${viewName}`);\n }\n }\n\n // Step 3: Dynamic import view loader (optional)\n let viewProps: Record<string, any> = {};\n let maxAge: number | undefined;\n let sMaxAge: number | undefined;\n let swr: number | undefined;\n let rawHtml: boolean = false;\n const loaderPathTs = `/src/views/${viewName}/loader.ts`;\n\n // Try TypeScript loader formats only\n const loaderModule = viewLoaders[loaderPathTs] ? await viewLoaders[loaderPathTs]() : null;\n\n if (loaderModule?.loader) {\n const loaderResult = await loaderModule.loader(requestInfo);\n\n // Check if loader returns raw response\n if (loaderResult.rawResponse) {\n return {\n rawResponse: loaderResult.rawResponse,\n statusCode: loaderResult.rawResponse.statusCode || 200,\n };\n }\n\n viewProps = loaderResult.props || {};\n maxAge = loaderResult.maxAge;\n sMaxAge = loaderResult.sMaxAge;\n swr = loaderResult.swr;\n rawHtml = loaderResult.rawHtml || false;\n\n if (loaderResult.cacheTags) {\n addCacheTag(loaderResult.cacheTags);\n }\n\n // View loader lang overrides global loader lang\n if (loaderResult.lang) {\n lang = loaderResult.lang;\n }\n } else {\n console.info(`No loader for view: ${viewName}`);\n }\n\n // Merge props: global props first, then view props (view can override)\n const props = { ...globalProps, ...viewProps };\n\n // Step 3.5: Generate metadata và schema từ generateMetadata và generateSchema functions\n // Global generateMetadata (parent metadata)\n if (globalLoaderModule?.generateMetadata) {\n const globalMetadata = globalLoaderModule.generateMetadata(requestInfo, props);\n if (globalMetadata) {\n pushMetadata(globalMetadata);\n }\n }\n\n // View generateMetadata (child metadata, sẽ merge với parent)\n if (loaderModule?.generateMetadata) {\n const viewMetadata = loaderModule.generateMetadata(requestInfo, props);\n if (viewMetadata) {\n pushMetadata(viewMetadata);\n }\n }\n\n // Global generateSchema (base schemas)\n if (globalLoaderModule?.generateSchema) {\n const globalSchema = globalLoaderModule.generateSchema(requestInfo, props);\n if (globalSchema) {\n pushSchema(globalSchema);\n }\n }\n\n // View generateSchema (view-specific schemas)\n if (loaderModule?.generateSchema) {\n const viewSchema = loaderModule.generateSchema(requestInfo, props);\n if (viewSchema) {\n pushSchema(viewSchema);\n }\n }\n\n // Step 4: Dynamic import component (required)\n const componentPathTsx = `/src/views/${viewName}/index.tsx`;\n\n const componentModule = viewComponents[componentPathTsx]\n ? await viewComponents[componentPathTsx]()\n : null;\n\n const Component = componentModule?.default;\n\n if (!Component) {\n console.error(`View component not found: ${viewName}`);\n\n // Check if in development or production mode\n const isDevelopment = process.env.NODE_ENV !== 'production';\n\n if (isDevelopment) {\n // Development: provide detailed error information\n throw new InternalServerErrorException(`View component not found: \"${viewName}\"`, {\n viewName,\n expectedPath: componentPathTsx,\n availableViews: Object.keys(viewComponents),\n hint: `Make sure the view component exists at ${componentPathTsx} and exports a default component`,\n timestamp: new Date().toISOString(),\n });\n } else {\n // Production: simple error message\n throw new InternalServerErrorException('Internal Server Error');\n }\n }\n\n // Auto-render MetadataRenderer trước khi render component\n // MetadataRenderer sẽ push metadata vào headRegistry thông qua Head component\n renderJsxToHtmlString(h(MetadataRenderer, {}));\n\n // Auto-render schemas vào headRegistry\n const schemas = getSchemas();\n schemas.forEach((schema) => {\n // serialize-javascript escapes HTML-sensitive chars (<, >, &, U+2028/2029)\n // so schema values cannot break out of the <script> block (XSS).\n const schemaJson = serialize(schema, { isJSON: true });\n // Push schema vào headRegistry thông qua Head component\n // Head component chỉ push vào registry, không cần renderJsxToHtmlString\n Head({\n priority: HEAD_PRIORITY.SEO,\n children: h('script', {\n type: 'application/ld+json',\n setHtml: schemaJson,\n }),\n });\n });\n\n // Render component (có thể có Head components khác)\n let htmlBody = renderJsxToHtmlString(h(Component, props));\n // Fill any opt-in `ssr` island placeholders with server-rendered React HTML.\n htmlBody = await fillSsrIslands(htmlBody);\n const clientEntries = getClientJsEntries();\n const cssEntries = getCssEntries();\n const islandEntries = getIslandEntries();\n const islandData = getIslandProps();\n const cacheTags = getCacheTags();\n const headContent = getHeadContent();\n\n // Render head content to HTML string\n const headHtml =\n headContent.length > 0\n ? headContent.map((content) => renderJsxToHtmlString(content)).join('\\n ')\n : undefined;\n\n return {\n html: htmlBody,\n scripts: clientEntries.map((entry) => entry.path),\n styles: cssEntries.map((entry) => entry.path),\n islands: islandEntries.length > 0 ? islandEntries : undefined,\n islandData: islandData.length > 0 ? islandData : undefined,\n head: headHtml,\n lang,\n maxAge,\n sMaxAge,\n swr,\n cacheTags,\n rawHtml,\n };\n } catch (err: any) {\n // Handle RedirectException\n if (err instanceof RedirectException) {\n return {\n html: '',\n redirect: {\n url: err.url,\n statusCode: err.statusCode,\n },\n };\n }\n\n // Handle HttpException\n if (err instanceof HttpException) {\n return await renderErrorView(err);\n }\n\n // For other (unexpected) errors, convert to ServiceUnavailableException.\n // Intentional HttpExceptions above keep their developer-authored message;\n // but an unexpected error's raw message/stack must not leak to the client\n // in production (it can carry internals, secrets, etc.). Dev keeps detail.\n console.error(`Failed to render:`, err);\n const isProduction = process.env.NODE_ENV === 'production';\n const serviceError = isProduction\n ? new ServiceUnavailableException('Internal Server Error')\n : new ServiceUnavailableException(err.message || 'Internal Server Error', {\n originalError: err.name,\n stack: err.stack,\n timestamp: new Date().toISOString(),\n });\n return await renderErrorView(serviceError);\n }\n }, requestInfo, undefined, { externalizeIslandProps });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/core/exceptions.ts
|
|
2
|
+
var e = class extends Error {
|
|
3
|
+
constructor(e, t, n) {
|
|
4
|
+
super(t), this.name = "HttpException", this.statusCode = e, this.data = n, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
5
|
+
}
|
|
6
|
+
}, t = class extends e {
|
|
7
|
+
constructor(e = "Bad Request", t) {
|
|
8
|
+
super(400, e, t), this.name = "BadRequestException";
|
|
9
|
+
}
|
|
10
|
+
}, n = class extends e {
|
|
11
|
+
constructor(e = "Not Found", t) {
|
|
12
|
+
super(404, e, t), this.name = "NotFoundException";
|
|
13
|
+
}
|
|
14
|
+
}, r = class extends e {
|
|
15
|
+
constructor(e = "Internal Server Error", t) {
|
|
16
|
+
super(500, e, t), this.name = "InternalServerErrorException";
|
|
17
|
+
}
|
|
18
|
+
}, i = class extends e {
|
|
19
|
+
constructor(e = "Service Unavailable", t) {
|
|
20
|
+
super(503, e, t), this.name = "ServiceUnavailableException";
|
|
21
|
+
}
|
|
22
|
+
}, a = class extends Error {
|
|
23
|
+
constructor(e, t = 302, n) {
|
|
24
|
+
super(`Redirect to ${e}`), this.name = "RedirectException", this.url = e, this.statusCode = t, this.data = n, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { a, n as i, e as n, i as o, r, t };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=exceptions-D4OdiQjY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions-D4OdiQjY.js","names":[],"sources":["../src/core/exceptions.ts"],"sourcesContent":["/**\n * Base HTTP Exception class\n */\nexport class HttpException extends Error {\n public readonly statusCode: number;\n public readonly data?: Record<string, any>;\n\n constructor(statusCode: number, message: string, data?: Record<string, any>) {\n super(message);\n this.name = 'HttpException';\n this.statusCode = statusCode;\n this.data = data;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * 400 Bad Request Exception\n */\nexport class BadRequestException extends HttpException {\n constructor(message: string = 'Bad Request', data?: Record<string, any>) {\n super(400, message, data);\n this.name = 'BadRequestException';\n }\n}\n\n/**\n * 404 Not Found Exception\n */\nexport class NotFoundException extends HttpException {\n constructor(message: string = 'Not Found', data?: Record<string, any>) {\n super(404, message, data);\n this.name = 'NotFoundException';\n }\n}\n\n/**\n * 500 Internal Server Error Exception\n */\nexport class InternalServerErrorException extends HttpException {\n constructor(message: string = 'Internal Server Error', data?: Record<string, any>) {\n super(500, message, data);\n this.name = 'InternalServerErrorException';\n }\n}\n\n/**\n * 503 Service Unavailable Exception\n */\nexport class ServiceUnavailableException extends HttpException {\n constructor(message: string = 'Service Unavailable', data?: Record<string, any>) {\n super(503, message, data);\n this.name = 'ServiceUnavailableException';\n }\n}\n\n/**\n * Redirect Exception - for HTTP redirects (301/302)\n */\nexport class RedirectException extends Error {\n public readonly url: string;\n public readonly statusCode: number;\n public readonly data?: Record<string, any>;\n\n constructor(url: string, statusCode: number = 302, data?: Record<string, any>) {\n super(`Redirect to ${url}`);\n this.name = 'RedirectException';\n this.url = url;\n this.statusCode = statusCode;\n this.data = data;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n"],"mappings":";AAGA,IAAa,IAAb,cAAmC,MAAM;CAIvC,YAAY,GAAoB,GAAiB,GAA4B;EAO3E,AANA,MAAM,CAAO,GACb,KAAK,OAAO,iBACZ,KAAK,aAAa,GAClB,KAAK,OAAO,GAGR,MAAM,qBACR,MAAM,kBAAkB,MAAM,KAAK,WAAW;CAElD;AACF,GAKa,IAAb,cAAyC,EAAc;CACrD,YAAY,IAAkB,eAAe,GAA4B;EAEvE,AADA,MAAM,KAAK,GAAS,CAAI,GACxB,KAAK,OAAO;CACd;AACF,GAKa,IAAb,cAAuC,EAAc;CACnD,YAAY,IAAkB,aAAa,GAA4B;EAErE,AADA,MAAM,KAAK,GAAS,CAAI,GACxB,KAAK,OAAO;CACd;AACF,GAKa,IAAb,cAAkD,EAAc;CAC9D,YAAY,IAAkB,yBAAyB,GAA4B;EAEjF,AADA,MAAM,KAAK,GAAS,CAAI,GACxB,KAAK,OAAO;CACd;AACF,GAKa,IAAb,cAAiD,EAAc;CAC7D,YAAY,IAAkB,uBAAuB,GAA4B;EAE/E,AADA,MAAM,KAAK,GAAS,CAAI,GACxB,KAAK,OAAO;CACd;AACF,GAKa,IAAb,cAAuC,MAAM;CAK3C,YAAY,GAAa,IAAqB,KAAK,GAA4B;EAO7E,AANA,MAAM,eAAe,GAAK,GAC1B,KAAK,OAAO,qBACZ,KAAK,MAAM,GACX,KAAK,aAAa,GAClB,KAAK,OAAO,GAER,MAAM,qBACR,MAAM,kBAAkB,MAAM,KAAK,WAAW;CAElD;AACF"}
|