@finesoft/front 0.1.13 → 0.1.15
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/dist/app-MYBG3TGV.js +10 -0
- package/dist/app-MYBG3TGV.js.map +1 -0
- package/dist/browser.js +12 -10
- package/dist/chunk-2VETWTN5.js +88 -0
- package/dist/chunk-2VETWTN5.js.map +1 -0
- package/dist/chunk-FYP2ZYYV.js +25 -0
- package/dist/chunk-FYP2ZYYV.js.map +1 -0
- package/dist/{chunk-OVGQ4NUA.js → chunk-RVKDILGM.js} +2 -327
- package/dist/chunk-RVKDILGM.js.map +1 -0
- package/dist/chunk-T2AQHAYK.js +337 -0
- package/dist/chunk-T2AQHAYK.js.map +1 -0
- package/dist/chunk-Z4MHYAS3.js +108 -0
- package/dist/chunk-Z4MHYAS3.js.map +1 -0
- package/dist/index.cjs +1788 -839
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +202 -1
- package/dist/index.d.ts +202 -1
- package/dist/index.js +693 -180
- package/dist/index.js.map +1 -1
- package/dist/locale-YK3THSI6.js +7 -0
- package/dist/locale-YK3THSI6.js.map +1 -0
- package/dist/src-7D236CLJ.js +19 -0
- package/dist/src-7D236CLJ.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-OVGQ4NUA.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
History,
|
|
3
|
+
createPrefetchedIntentsFromDom,
|
|
4
|
+
deserializeServerData,
|
|
5
|
+
registerActionHandlers,
|
|
6
|
+
registerExternalUrlHandler,
|
|
7
|
+
registerFlowActionHandler,
|
|
8
|
+
startBrowserApp,
|
|
9
|
+
tryScroll
|
|
10
|
+
} from "./chunk-T2AQHAYK.js";
|
|
11
|
+
import {
|
|
12
|
+
createSSRApp
|
|
13
|
+
} from "./chunk-Z4MHYAS3.js";
|
|
14
|
+
import {
|
|
15
|
+
SSR_PLACEHOLDERS,
|
|
16
|
+
createSSRRender,
|
|
17
|
+
injectSSRContent,
|
|
18
|
+
serializeServerData,
|
|
19
|
+
ssrRender
|
|
20
|
+
} from "./chunk-2VETWTN5.js";
|
|
1
21
|
import {
|
|
2
22
|
ACTION_KINDS,
|
|
3
23
|
ActionDispatcher,
|
|
@@ -10,7 +30,6 @@ import {
|
|
|
10
30
|
Container,
|
|
11
31
|
DEP_KEYS,
|
|
12
32
|
Framework,
|
|
13
|
-
History,
|
|
14
33
|
HttpClient,
|
|
15
34
|
HttpError,
|
|
16
35
|
IntentDispatcher,
|
|
@@ -18,9 +37,7 @@ import {
|
|
|
18
37
|
PrefetchedIntents,
|
|
19
38
|
Router,
|
|
20
39
|
buildUrl,
|
|
21
|
-
createPrefetchedIntentsFromDom,
|
|
22
40
|
defineRoutes,
|
|
23
|
-
deserializeServerData,
|
|
24
41
|
generateUuid,
|
|
25
42
|
getBaseUrl,
|
|
26
43
|
isCompoundAction,
|
|
@@ -34,217 +51,460 @@ import {
|
|
|
34
51
|
mapEach,
|
|
35
52
|
pipe,
|
|
36
53
|
pipeAsync,
|
|
37
|
-
registerActionHandlers,
|
|
38
|
-
registerExternalUrlHandler,
|
|
39
|
-
registerFlowActionHandler,
|
|
40
54
|
removeHost,
|
|
41
55
|
removeQueryParams,
|
|
42
56
|
removeScheme,
|
|
43
57
|
resetFilterCache,
|
|
44
58
|
shouldLog,
|
|
45
|
-
stableStringify
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
stableStringify
|
|
60
|
+
} from "./chunk-RVKDILGM.js";
|
|
61
|
+
import {
|
|
62
|
+
parseAcceptLanguage
|
|
63
|
+
} from "./chunk-FYP2ZYYV.js";
|
|
49
64
|
|
|
50
|
-
// ../
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
// ../server/src/adapters/shared.ts
|
|
66
|
+
var BUILD_TOOL_EXTERNALS = [
|
|
67
|
+
"vite",
|
|
68
|
+
"esbuild",
|
|
69
|
+
"rollup",
|
|
70
|
+
"fsevents",
|
|
71
|
+
"lightningcss"
|
|
72
|
+
];
|
|
73
|
+
function generateSSREntry(ctx, opts) {
|
|
74
|
+
const setupImport = ctx.setupPath ? `import _setupDefault from "./${ctx.setupPath}";` : ``;
|
|
75
|
+
const setupCall = ctx.setupPath ? `if (typeof _setupDefault === "function") await _setupDefault(app);` : ``;
|
|
76
|
+
const locales = JSON.stringify(ctx.locales);
|
|
77
|
+
const defaultLocale = JSON.stringify(ctx.defaultLocale);
|
|
78
|
+
return `
|
|
79
|
+
import { Hono } from "hono";
|
|
80
|
+
${opts.platformImport}
|
|
81
|
+
import { render, serializeServerData } from "./${ctx.ssrEntry}";
|
|
82
|
+
${setupImport}
|
|
83
|
+
|
|
84
|
+
const TEMPLATE = ${JSON.stringify(ctx.templateHtml)};
|
|
85
|
+
const LOCALES = ${locales};
|
|
86
|
+
const DEFAULT_LOCALE = ${defaultLocale};
|
|
87
|
+
|
|
88
|
+
function parseAcceptLanguage(header) {
|
|
89
|
+
if (!header) return DEFAULT_LOCALE;
|
|
90
|
+
const langs = header.split(",").map(p => {
|
|
91
|
+
const [l, q] = p.trim().split(";q=");
|
|
92
|
+
return { l: l.trim().toLowerCase(), q: q ? +q : 1 };
|
|
93
|
+
}).sort((a, b) => b.q - a.q);
|
|
94
|
+
for (const { l } of langs) {
|
|
95
|
+
const prefix = l.split("-")[0];
|
|
96
|
+
if (LOCALES.includes(prefix)) return prefix;
|
|
69
97
|
}
|
|
70
|
-
|
|
71
|
-
framework.dispose();
|
|
72
|
-
return {
|
|
73
|
-
html: result.html,
|
|
74
|
-
head: result.head,
|
|
75
|
-
css: result.css,
|
|
76
|
-
serverData
|
|
77
|
-
};
|
|
98
|
+
return DEFAULT_LOCALE;
|
|
78
99
|
}
|
|
79
100
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
bootstrap,
|
|
87
|
-
getErrorPage,
|
|
88
|
-
renderApp: (page) => renderApp(page, locale)
|
|
89
|
-
});
|
|
101
|
+
function injectSSR(t, locale, head, css, html, data) {
|
|
102
|
+
return t
|
|
103
|
+
.replace("<!--ssr-lang-->", locale)
|
|
104
|
+
.replace("<!--ssr-head-->", head + "\\n<style>" + css + "</style>")
|
|
105
|
+
.replace("<!--ssr-body-->", html)
|
|
106
|
+
.replace("<!--ssr-data-->", '<script id="serialized-server-data" type="application/json">' + data + "</script>");
|
|
90
107
|
}
|
|
91
108
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
const app = new Hono();
|
|
110
|
+
${setupCall}
|
|
111
|
+
|
|
112
|
+
app.get("*", async (c) => {
|
|
113
|
+
const url = c.req.path + (c.req.url.includes("?") ? "?" + c.req.url.split("?")[1] : "");
|
|
114
|
+
try {
|
|
115
|
+
const locale = parseAcceptLanguage(c.req.header("accept-language"));
|
|
116
|
+
const { html: appHtml, head, css, serverData } = await render(url, locale);
|
|
117
|
+
const serializedData = serializeServerData(serverData);
|
|
118
|
+
return c.html(injectSSR(TEMPLATE, locale, head, css, appHtml, serializedData));
|
|
119
|
+
} catch (e) {
|
|
120
|
+
console.error("[SSR Error]", e);
|
|
121
|
+
return c.text("Internal Server Error", 500);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
${opts.platformExport}
|
|
126
|
+
`;
|
|
127
|
+
}
|
|
128
|
+
async function buildBundle(ctx, opts) {
|
|
129
|
+
await ctx.vite.build({
|
|
130
|
+
root: ctx.root,
|
|
131
|
+
build: {
|
|
132
|
+
ssr: opts.entry,
|
|
133
|
+
outDir: opts.outDir,
|
|
134
|
+
emptyOutDir: true,
|
|
135
|
+
target: opts.target ?? "node18",
|
|
136
|
+
rollupOptions: {
|
|
137
|
+
output: { entryFileNames: opts.fileName ?? "index.mjs" }
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
ssr: {
|
|
141
|
+
noExternal: opts.noExternal !== false,
|
|
142
|
+
external: opts.external ?? BUILD_TOOL_EXTERNALS
|
|
143
|
+
},
|
|
144
|
+
resolve: ctx.resolvedResolve,
|
|
145
|
+
css: ctx.resolvedCss
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function copyStaticAssets(ctx, destDir, opts) {
|
|
149
|
+
const { fs, path } = ctx;
|
|
150
|
+
fs.cpSync(path.resolve(ctx.root, "dist/client"), destDir, {
|
|
151
|
+
recursive: true
|
|
152
|
+
});
|
|
153
|
+
if (opts?.excludeHtml !== false) {
|
|
154
|
+
fs.rmSync(path.join(destDir, "index.html"), { force: true });
|
|
155
|
+
}
|
|
107
156
|
}
|
|
108
157
|
|
|
109
|
-
// ../
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
158
|
+
// ../server/src/adapters/cloudflare.ts
|
|
159
|
+
function cloudflareAdapter() {
|
|
160
|
+
return {
|
|
161
|
+
name: "cloudflare",
|
|
162
|
+
async build(ctx) {
|
|
163
|
+
const { fs, path, root } = ctx;
|
|
164
|
+
const outputDir = path.resolve(root, "dist/cloudflare");
|
|
165
|
+
fs.rmSync(outputDir, { recursive: true, force: true });
|
|
166
|
+
const entrySource = generateSSREntry(ctx, {
|
|
167
|
+
platformImport: ``,
|
|
168
|
+
platformExport: `export default app;`
|
|
169
|
+
});
|
|
170
|
+
const tempEntry = path.resolve(root, ".cf-entry.tmp.mjs");
|
|
171
|
+
fs.writeFileSync(tempEntry, entrySource);
|
|
172
|
+
try {
|
|
173
|
+
await buildBundle(ctx, {
|
|
174
|
+
entry: ".cf-entry.tmp.mjs",
|
|
175
|
+
outDir: outputDir,
|
|
176
|
+
target: "es2022",
|
|
177
|
+
fileName: "_worker.js"
|
|
178
|
+
// 使用默认 external(vite/esbuild/rollup/fsevents/lightningcss)
|
|
179
|
+
// 这些构建工具运行时不需要,且 fsevents 是 macOS .node 原生二进制无法打包
|
|
180
|
+
});
|
|
181
|
+
copyStaticAssets(ctx, path.resolve(outputDir, "assets"));
|
|
182
|
+
} finally {
|
|
183
|
+
fs.rmSync(tempEntry, { force: true });
|
|
184
|
+
}
|
|
185
|
+
console.log(" Cloudflare output \u2192 dist/cloudflare/\n");
|
|
186
|
+
}
|
|
187
|
+
};
|
|
124
188
|
}
|
|
125
189
|
|
|
126
|
-
// ../server/src/
|
|
127
|
-
|
|
190
|
+
// ../server/src/adapters/netlify.ts
|
|
191
|
+
function netlifyAdapter() {
|
|
192
|
+
return {
|
|
193
|
+
name: "netlify",
|
|
194
|
+
async build(ctx) {
|
|
195
|
+
const { fs, path, root } = ctx;
|
|
196
|
+
const funcDir = path.resolve(
|
|
197
|
+
root,
|
|
198
|
+
".netlify/functions-internal/ssr"
|
|
199
|
+
);
|
|
200
|
+
fs.rmSync(path.resolve(root, ".netlify"), {
|
|
201
|
+
recursive: true,
|
|
202
|
+
force: true
|
|
203
|
+
});
|
|
204
|
+
const entrySource = generateSSREntry(ctx, {
|
|
205
|
+
platformImport: `import { handle } from "hono/netlify";`,
|
|
206
|
+
platformExport: `export default handle(app);`
|
|
207
|
+
});
|
|
208
|
+
const tempEntry = path.resolve(root, ".netlify-entry.tmp.mjs");
|
|
209
|
+
fs.writeFileSync(tempEntry, entrySource);
|
|
210
|
+
try {
|
|
211
|
+
await buildBundle(ctx, {
|
|
212
|
+
entry: ".netlify-entry.tmp.mjs",
|
|
213
|
+
outDir: funcDir,
|
|
214
|
+
target: "node18"
|
|
215
|
+
});
|
|
216
|
+
} finally {
|
|
217
|
+
fs.rmSync(tempEntry, { force: true });
|
|
218
|
+
}
|
|
219
|
+
const redirects = `/* /.netlify/functions/ssr 200
|
|
220
|
+
`;
|
|
221
|
+
fs.writeFileSync(
|
|
222
|
+
path.resolve(root, "dist/client/_redirects"),
|
|
223
|
+
redirects
|
|
224
|
+
);
|
|
225
|
+
console.log(
|
|
226
|
+
" Netlify output \u2192 .netlify/functions-internal/ssr/\n Publish dir: dist/client/\n"
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
128
231
|
|
|
129
|
-
// ../server/src/
|
|
130
|
-
function
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
232
|
+
// ../server/src/adapters/node.ts
|
|
233
|
+
function nodeAdapter() {
|
|
234
|
+
return {
|
|
235
|
+
name: "node",
|
|
236
|
+
async build(ctx) {
|
|
237
|
+
const { fs, path, root } = ctx;
|
|
238
|
+
const entrySource = generateSSREntry(ctx, {
|
|
239
|
+
platformImport: `import { serve } from "@hono/node-server";`,
|
|
240
|
+
platformExport: `
|
|
241
|
+
const port = +(process.env.PORT || 3000);
|
|
242
|
+
serve({ fetch: app.fetch, port }, (info) => {
|
|
243
|
+
console.log(\`Server running at http://localhost:\${info.port}\`);
|
|
244
|
+
});
|
|
245
|
+
`
|
|
246
|
+
});
|
|
247
|
+
const tempEntry = path.resolve(root, ".node-entry.tmp.mjs");
|
|
248
|
+
fs.writeFileSync(tempEntry, entrySource);
|
|
249
|
+
try {
|
|
250
|
+
await buildBundle(ctx, {
|
|
251
|
+
entry: ".node-entry.tmp.mjs",
|
|
252
|
+
outDir: path.resolve(root, "dist/server"),
|
|
253
|
+
target: "node18"
|
|
254
|
+
});
|
|
255
|
+
} finally {
|
|
256
|
+
fs.rmSync(tempEntry, { force: true });
|
|
257
|
+
}
|
|
258
|
+
console.log(
|
|
259
|
+
" Node output \u2192 dist/server/index.mjs\n Run: node dist/server/index.mjs\n"
|
|
260
|
+
);
|
|
145
261
|
}
|
|
146
|
-
}
|
|
147
|
-
return effectiveFallback;
|
|
262
|
+
};
|
|
148
263
|
}
|
|
149
264
|
|
|
150
|
-
// ../server/src/
|
|
151
|
-
function
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
} = options;
|
|
161
|
-
const app = new Hono();
|
|
162
|
-
async function readTemplate(url) {
|
|
163
|
-
if (!isProduction && vite) {
|
|
164
|
-
const { readFileSync: readFileSync2 } = await import(
|
|
265
|
+
// ../server/src/adapters/static.ts
|
|
266
|
+
function staticAdapter(opts = {}) {
|
|
267
|
+
return {
|
|
268
|
+
name: "static",
|
|
269
|
+
async build(ctx) {
|
|
270
|
+
const { fs, path, root, vite } = ctx;
|
|
271
|
+
const outputDir = path.resolve(root, "dist/static");
|
|
272
|
+
fs.rmSync(outputDir, { recursive: true, force: true });
|
|
273
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
274
|
+
const { pathToFileURL } = await import(
|
|
165
275
|
/* @vite-ignore */
|
|
166
|
-
"
|
|
276
|
+
"url"
|
|
167
277
|
);
|
|
168
|
-
const
|
|
278
|
+
const ssrPath = pathToFileURL(
|
|
279
|
+
path.resolve(root, "dist/server/ssr.js")
|
|
280
|
+
).href;
|
|
281
|
+
const ssrModule = await import(
|
|
169
282
|
/* @vite-ignore */
|
|
170
|
-
|
|
283
|
+
ssrPath
|
|
171
284
|
);
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
285
|
+
const routePaths = await extractRoutes(ctx, opts);
|
|
286
|
+
const allUrls = [];
|
|
287
|
+
for (const routePath of routePaths) {
|
|
288
|
+
for (const locale of ctx.locales) {
|
|
289
|
+
const url = locale === ctx.defaultLocale ? routePath : `/${locale}${routePath === "/" ? "" : routePath}`;
|
|
290
|
+
allUrls.push(url);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
console.log(
|
|
294
|
+
` Pre-rendering ${allUrls.length} pages (${routePaths.length} routes \xD7 ${ctx.locales.length} locales)...
|
|
295
|
+
`
|
|
179
296
|
);
|
|
297
|
+
for (const url of allUrls) {
|
|
298
|
+
try {
|
|
299
|
+
const locale = inferLocale(
|
|
300
|
+
url,
|
|
301
|
+
ctx.locales,
|
|
302
|
+
ctx.defaultLocale
|
|
303
|
+
);
|
|
304
|
+
const {
|
|
305
|
+
html: appHtml,
|
|
306
|
+
head,
|
|
307
|
+
css,
|
|
308
|
+
serverData
|
|
309
|
+
} = await ssrModule.render(url, locale);
|
|
310
|
+
const serializedData = ssrModule.serializeServerData(serverData);
|
|
311
|
+
const finalHtml = injectSSRForStatic(
|
|
312
|
+
ctx.templateHtml,
|
|
313
|
+
locale,
|
|
314
|
+
head,
|
|
315
|
+
css,
|
|
316
|
+
appHtml,
|
|
317
|
+
serializedData
|
|
318
|
+
);
|
|
319
|
+
const filePath = url === "/" ? path.join(outputDir, "index.html") : path.join(outputDir, url, "index.html");
|
|
320
|
+
fs.mkdirSync(path.resolve(filePath, ".."), {
|
|
321
|
+
recursive: true
|
|
322
|
+
});
|
|
323
|
+
fs.writeFileSync(filePath, finalHtml);
|
|
324
|
+
} catch (e) {
|
|
325
|
+
console.warn(` [static] Failed to render ${url}:`, e);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
ctx.copyStaticAssets(outputDir, { excludeHtml: true });
|
|
329
|
+
console.log(` Static output \u2192 dist/static/
|
|
330
|
+
`);
|
|
180
331
|
}
|
|
181
|
-
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
async function extractRoutes(ctx, opts) {
|
|
335
|
+
const routesFile = opts.routesExport ?? "src/lib/bootstrap.ts";
|
|
336
|
+
const paths = [];
|
|
337
|
+
try {
|
|
338
|
+
const { pathToFileURL } = await import(
|
|
182
339
|
/* @vite-ignore */
|
|
183
|
-
"
|
|
340
|
+
"url"
|
|
184
341
|
);
|
|
185
|
-
|
|
342
|
+
await ctx.vite.build({
|
|
343
|
+
root: ctx.root,
|
|
344
|
+
build: {
|
|
345
|
+
ssr: routesFile,
|
|
346
|
+
outDir: ctx.path.resolve(ctx.root, "dist/server"),
|
|
347
|
+
emptyOutDir: false,
|
|
348
|
+
rollupOptions: {
|
|
349
|
+
output: { entryFileNames: "_routes.mjs" }
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
resolve: ctx.resolvedResolve
|
|
353
|
+
});
|
|
354
|
+
const routesPath = pathToFileURL(
|
|
355
|
+
ctx.path.resolve(ctx.root, "dist/server/_routes.mjs")
|
|
356
|
+
).href;
|
|
357
|
+
const routesMod = await import(
|
|
186
358
|
/* @vite-ignore */
|
|
187
|
-
|
|
359
|
+
routesPath
|
|
188
360
|
);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return import(ssrProductionModule);
|
|
361
|
+
const routes = routesMod.routes ?? routesMod.default;
|
|
362
|
+
if (Array.isArray(routes)) {
|
|
363
|
+
for (const r of routes) {
|
|
364
|
+
if (r.path && !r.path.includes(":")) {
|
|
365
|
+
paths.push(r.path);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
197
368
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
369
|
+
ctx.fs.rmSync(ctx.path.resolve(ctx.root, "dist/server/_routes.mjs"), {
|
|
370
|
+
force: true
|
|
371
|
+
});
|
|
372
|
+
} catch (e) {
|
|
373
|
+
console.warn(
|
|
374
|
+
` [static] Could not load routes from "${routesFile}". Using "/" only.`,
|
|
375
|
+
e
|
|
205
376
|
);
|
|
206
|
-
|
|
207
|
-
return import(absPath);
|
|
377
|
+
if (paths.length === 0) paths.push("/");
|
|
208
378
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
379
|
+
if (opts.dynamicRoutes) {
|
|
380
|
+
for (const r of opts.dynamicRoutes) {
|
|
381
|
+
if (!paths.includes(r)) paths.push(r);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (paths.length === 0) paths.push("/");
|
|
385
|
+
return paths;
|
|
386
|
+
}
|
|
387
|
+
function inferLocale(url, locales, defaultLocale) {
|
|
388
|
+
const segments = url.split("/").filter(Boolean);
|
|
389
|
+
if (segments.length > 0 && locales.includes(segments[0])) {
|
|
390
|
+
return segments[0];
|
|
391
|
+
}
|
|
392
|
+
return defaultLocale;
|
|
393
|
+
}
|
|
394
|
+
function injectSSRForStatic(template, locale, head, css, html, serializedData) {
|
|
395
|
+
return template.replace("<!--ssr-lang-->", locale).replace("<!--ssr-head-->", head + "\n<style>" + css + "</style>").replace("<!--ssr-body-->", html).replace(
|
|
396
|
+
"<!--ssr-data-->",
|
|
397
|
+
'<script id="serialized-server-data" type="application/json">' + serializedData + "</script>"
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// ../server/src/adapters/vercel.ts
|
|
402
|
+
function vercelAdapter() {
|
|
403
|
+
return {
|
|
404
|
+
name: "vercel",
|
|
405
|
+
async build(ctx) {
|
|
406
|
+
const { fs, path, root } = ctx;
|
|
407
|
+
const outputDir = path.resolve(root, ".vercel/output");
|
|
408
|
+
fs.rmSync(outputDir, { recursive: true, force: true });
|
|
409
|
+
const entrySource = generateSSREntry(ctx, {
|
|
410
|
+
platformImport: `import { handle } from "hono/vercel";`,
|
|
411
|
+
platformExport: `export default handle(app);`
|
|
233
412
|
});
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
413
|
+
const tempEntry = path.resolve(root, ".vercel-entry.tmp.mjs");
|
|
414
|
+
fs.writeFileSync(tempEntry, entrySource);
|
|
415
|
+
try {
|
|
416
|
+
const funcDir = path.resolve(
|
|
417
|
+
root,
|
|
418
|
+
".vercel/output/functions/ssr.func"
|
|
419
|
+
);
|
|
420
|
+
await buildBundle(ctx, {
|
|
421
|
+
entry: ".vercel-entry.tmp.mjs",
|
|
422
|
+
outDir: funcDir,
|
|
423
|
+
target: "node18"
|
|
424
|
+
});
|
|
425
|
+
fs.writeFileSync(
|
|
426
|
+
path.resolve(funcDir, ".vc-config.json"),
|
|
427
|
+
JSON.stringify(
|
|
428
|
+
{
|
|
429
|
+
runtime: "nodejs20.x",
|
|
430
|
+
handler: "index.mjs",
|
|
431
|
+
launcherType: "Nodejs"
|
|
432
|
+
},
|
|
433
|
+
null,
|
|
434
|
+
2
|
|
435
|
+
)
|
|
436
|
+
);
|
|
437
|
+
copyStaticAssets(
|
|
438
|
+
ctx,
|
|
439
|
+
path.resolve(root, ".vercel/output/static")
|
|
440
|
+
);
|
|
441
|
+
fs.writeFileSync(
|
|
442
|
+
path.resolve(root, ".vercel/output/config.json"),
|
|
443
|
+
JSON.stringify(
|
|
444
|
+
{
|
|
445
|
+
version: 3,
|
|
446
|
+
routes: [
|
|
447
|
+
{ handle: "filesystem" },
|
|
448
|
+
{ src: "/(.*)", dest: "/ssr" }
|
|
449
|
+
]
|
|
450
|
+
},
|
|
451
|
+
null,
|
|
452
|
+
2
|
|
453
|
+
)
|
|
454
|
+
);
|
|
455
|
+
} finally {
|
|
456
|
+
fs.rmSync(tempEntry, { force: true });
|
|
238
457
|
}
|
|
239
|
-
console.
|
|
240
|
-
return c.text("Internal Server Error", 500);
|
|
458
|
+
console.log(" Vercel output \u2192 .vercel/output/\n");
|
|
241
459
|
}
|
|
242
|
-
}
|
|
243
|
-
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// ../server/src/adapters/resolve.ts
|
|
464
|
+
function resolveAdapter(value) {
|
|
465
|
+
if (typeof value !== "string") return value;
|
|
466
|
+
switch (value) {
|
|
467
|
+
case "vercel":
|
|
468
|
+
return vercelAdapter();
|
|
469
|
+
case "cloudflare":
|
|
470
|
+
return cloudflareAdapter();
|
|
471
|
+
case "netlify":
|
|
472
|
+
return netlifyAdapter();
|
|
473
|
+
case "node":
|
|
474
|
+
return nodeAdapter();
|
|
475
|
+
case "static":
|
|
476
|
+
return staticAdapter();
|
|
477
|
+
case "auto":
|
|
478
|
+
return autoAdapter();
|
|
479
|
+
default:
|
|
480
|
+
throw new Error(
|
|
481
|
+
`[finesoft] Unknown adapter: "${value}". Available: vercel, cloudflare, netlify, node, static, auto`
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// ../server/src/adapters/auto.ts
|
|
487
|
+
function autoAdapter() {
|
|
488
|
+
return {
|
|
489
|
+
name: "auto",
|
|
490
|
+
async build(ctx) {
|
|
491
|
+
const detected = detectPlatform();
|
|
492
|
+
console.log(` [auto] Detected platform: ${detected}
|
|
493
|
+
`);
|
|
494
|
+
const adapter = resolveAdapter(detected);
|
|
495
|
+
return adapter.build(ctx);
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
function detectPlatform() {
|
|
500
|
+
if (process.env.VERCEL) return "vercel";
|
|
501
|
+
if (process.env.CF_PAGES) return "cloudflare";
|
|
502
|
+
if (process.env.NETLIFY) return "netlify";
|
|
503
|
+
return "node";
|
|
244
504
|
}
|
|
245
505
|
|
|
246
506
|
// ../server/src/create-server.ts
|
|
247
|
-
import { Hono as
|
|
507
|
+
import { Hono as Hono2 } from "hono";
|
|
248
508
|
|
|
249
509
|
// ../server/src/runtime.ts
|
|
250
510
|
function detectRuntime() {
|
|
@@ -280,7 +540,7 @@ async function resolveRoot(importMetaUrl, levelsUp = 0) {
|
|
|
280
540
|
}
|
|
281
541
|
|
|
282
542
|
// ../server/src/start.ts
|
|
283
|
-
import { Hono
|
|
543
|
+
import { Hono } from "hono";
|
|
284
544
|
async function startServer(options) {
|
|
285
545
|
const {
|
|
286
546
|
app,
|
|
@@ -362,7 +622,7 @@ async function startServer(options) {
|
|
|
362
622
|
/* @vite-ignore */
|
|
363
623
|
"path"
|
|
364
624
|
);
|
|
365
|
-
const prodApp = new
|
|
625
|
+
const prodApp = new Hono();
|
|
366
626
|
const clientDir = resolve(root, "dist/client");
|
|
367
627
|
prodApp.use(
|
|
368
628
|
"/*",
|
|
@@ -427,7 +687,7 @@ async function createServer(config = {}) {
|
|
|
427
687
|
appType: "custom"
|
|
428
688
|
});
|
|
429
689
|
}
|
|
430
|
-
const app = new
|
|
690
|
+
const app = new Hono2();
|
|
431
691
|
if (setup) {
|
|
432
692
|
await setup(app);
|
|
433
693
|
}
|
|
@@ -452,6 +712,251 @@ async function createServer(config = {}) {
|
|
|
452
712
|
});
|
|
453
713
|
return { app, vite, runtime };
|
|
454
714
|
}
|
|
715
|
+
|
|
716
|
+
// ../server/src/vite-plugin.ts
|
|
717
|
+
function resolveSetupFn(mod) {
|
|
718
|
+
if (typeof mod.default === "function") return mod.default;
|
|
719
|
+
if (typeof mod.setup === "function") return mod.setup;
|
|
720
|
+
const first = Object.values(mod).find((v) => typeof v === "function");
|
|
721
|
+
return first ?? null;
|
|
722
|
+
}
|
|
723
|
+
function finesoftFrontViteConfig(options = {}) {
|
|
724
|
+
const ssrEntry = options.ssr?.entry ?? "src/ssr.ts";
|
|
725
|
+
let root = process.cwd();
|
|
726
|
+
let resolvedCommand;
|
|
727
|
+
let resolvedResolve;
|
|
728
|
+
let resolvedCss;
|
|
729
|
+
return {
|
|
730
|
+
name: "finesoft-front",
|
|
731
|
+
config(userConfig, env) {
|
|
732
|
+
const overrides = {
|
|
733
|
+
appType: "custom"
|
|
734
|
+
};
|
|
735
|
+
if (env.command === "build" && !process.env.__FINESOFT_SUB_BUILD__) {
|
|
736
|
+
overrides.build = {
|
|
737
|
+
outDir: userConfig.build?.outDir ?? "dist/client"
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
return overrides;
|
|
741
|
+
},
|
|
742
|
+
configResolved(config) {
|
|
743
|
+
resolvedCommand = config.command;
|
|
744
|
+
resolvedResolve = config.resolve;
|
|
745
|
+
resolvedCss = config.css;
|
|
746
|
+
root = config.root;
|
|
747
|
+
},
|
|
748
|
+
// ─── Dev ───────────────────────────────────────────────
|
|
749
|
+
configureServer(server) {
|
|
750
|
+
return async () => {
|
|
751
|
+
const { Hono: HonoClass } = await import(
|
|
752
|
+
/* @vite-ignore */
|
|
753
|
+
"hono"
|
|
754
|
+
);
|
|
755
|
+
const { createSSRApp: createSSRApp2 } = await import("./app-MYBG3TGV.js");
|
|
756
|
+
const { getRequestListener } = await import(
|
|
757
|
+
/* @vite-ignore */
|
|
758
|
+
"@hono/node-server"
|
|
759
|
+
);
|
|
760
|
+
const app = new HonoClass();
|
|
761
|
+
if (typeof options.setup === "function") {
|
|
762
|
+
await options.setup(app);
|
|
763
|
+
} else if (typeof options.setup === "string") {
|
|
764
|
+
const mod = await server.ssrLoadModule("/" + options.setup);
|
|
765
|
+
const fn = resolveSetupFn(mod);
|
|
766
|
+
if (fn) await fn(app);
|
|
767
|
+
}
|
|
768
|
+
const ssrApp = createSSRApp2({
|
|
769
|
+
root,
|
|
770
|
+
vite: server,
|
|
771
|
+
isProduction: false,
|
|
772
|
+
ssrEntryPath: "/" + ssrEntry,
|
|
773
|
+
supportedLocales: options.locales,
|
|
774
|
+
defaultLocale: options.defaultLocale
|
|
775
|
+
});
|
|
776
|
+
app.route("/", ssrApp);
|
|
777
|
+
const listener = getRequestListener(app.fetch);
|
|
778
|
+
server.middlewares.use((req, res) => {
|
|
779
|
+
listener(req, res);
|
|
780
|
+
});
|
|
781
|
+
};
|
|
782
|
+
},
|
|
783
|
+
// ─── Preview ───────────────────────────────────────────
|
|
784
|
+
configurePreviewServer(server) {
|
|
785
|
+
return async () => {
|
|
786
|
+
const { readFileSync } = await import(
|
|
787
|
+
/* @vite-ignore */
|
|
788
|
+
"fs"
|
|
789
|
+
);
|
|
790
|
+
const { resolve } = await import(
|
|
791
|
+
/* @vite-ignore */
|
|
792
|
+
"path"
|
|
793
|
+
);
|
|
794
|
+
const { pathToFileURL } = await import(
|
|
795
|
+
/* @vite-ignore */
|
|
796
|
+
"url"
|
|
797
|
+
);
|
|
798
|
+
const { Hono: HonoClass } = await import(
|
|
799
|
+
/* @vite-ignore */
|
|
800
|
+
"hono"
|
|
801
|
+
);
|
|
802
|
+
const { injectSSRContent: injectSSRContent2 } = await import(
|
|
803
|
+
/* @vite-ignore */
|
|
804
|
+
"./src-7D236CLJ.js"
|
|
805
|
+
);
|
|
806
|
+
const { parseAcceptLanguage: parseAcceptLanguage2 } = await import("./locale-YK3THSI6.js");
|
|
807
|
+
const { getRequestListener } = await import(
|
|
808
|
+
/* @vite-ignore */
|
|
809
|
+
"@hono/node-server"
|
|
810
|
+
);
|
|
811
|
+
const app = new HonoClass();
|
|
812
|
+
if (typeof options.setup === "function") {
|
|
813
|
+
await options.setup(app);
|
|
814
|
+
} else if (typeof options.setup === "string") {
|
|
815
|
+
try {
|
|
816
|
+
const setupPath = pathToFileURL(
|
|
817
|
+
resolve(root, "dist/server/setup.mjs")
|
|
818
|
+
).href;
|
|
819
|
+
const mod = await import(
|
|
820
|
+
/* @vite-ignore */
|
|
821
|
+
setupPath
|
|
822
|
+
);
|
|
823
|
+
const fn = resolveSetupFn(
|
|
824
|
+
mod
|
|
825
|
+
);
|
|
826
|
+
if (fn) await fn(app);
|
|
827
|
+
} catch {
|
|
828
|
+
console.warn(
|
|
829
|
+
"[finesoft] Could not load setup module for preview. API routes disabled."
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
const templatePath = resolve(root, "dist/client/index.html");
|
|
834
|
+
const template = readFileSync(templatePath, "utf-8");
|
|
835
|
+
const ssrPath = pathToFileURL(
|
|
836
|
+
resolve(root, "dist/server/ssr.js")
|
|
837
|
+
).href;
|
|
838
|
+
const ssrModule = await import(
|
|
839
|
+
/* @vite-ignore */
|
|
840
|
+
ssrPath
|
|
841
|
+
);
|
|
842
|
+
app.get("*", async (c) => {
|
|
843
|
+
const url = c.req.path + (c.req.url.includes("?") ? "?" + c.req.url.split("?")[1] : "");
|
|
844
|
+
try {
|
|
845
|
+
const locale = parseAcceptLanguage2(
|
|
846
|
+
c.req.header("accept-language"),
|
|
847
|
+
options.locales,
|
|
848
|
+
options.defaultLocale
|
|
849
|
+
);
|
|
850
|
+
const {
|
|
851
|
+
html: appHtml,
|
|
852
|
+
head,
|
|
853
|
+
css,
|
|
854
|
+
serverData
|
|
855
|
+
} = await ssrModule.render(url, locale);
|
|
856
|
+
const serializedData = ssrModule.serializeServerData(serverData);
|
|
857
|
+
const finalHtml = injectSSRContent2({
|
|
858
|
+
template,
|
|
859
|
+
locale,
|
|
860
|
+
head,
|
|
861
|
+
css,
|
|
862
|
+
html: appHtml,
|
|
863
|
+
serializedData
|
|
864
|
+
});
|
|
865
|
+
return c.html(finalHtml);
|
|
866
|
+
} catch (e) {
|
|
867
|
+
console.error("[SSR Preview Error]", e);
|
|
868
|
+
return c.text("Internal Server Error", 500);
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
const listener = getRequestListener(app.fetch);
|
|
872
|
+
server.middlewares.use((req, res) => {
|
|
873
|
+
listener(req, res);
|
|
874
|
+
});
|
|
875
|
+
};
|
|
876
|
+
},
|
|
877
|
+
// ─── Build ─────────────────────────────────────────────
|
|
878
|
+
async closeBundle() {
|
|
879
|
+
if (process.env.__FINESOFT_SUB_BUILD__) return;
|
|
880
|
+
if (resolvedCommand !== "build") return;
|
|
881
|
+
process.env.__FINESOFT_SUB_BUILD__ = "1";
|
|
882
|
+
try {
|
|
883
|
+
const vite = await import(
|
|
884
|
+
/* @vite-ignore */
|
|
885
|
+
"vite"
|
|
886
|
+
);
|
|
887
|
+
const fs = await import(
|
|
888
|
+
/* @vite-ignore */
|
|
889
|
+
"fs"
|
|
890
|
+
);
|
|
891
|
+
const path = await import(
|
|
892
|
+
/* @vite-ignore */
|
|
893
|
+
"path"
|
|
894
|
+
);
|
|
895
|
+
console.log("\n Building SSR bundle...\n");
|
|
896
|
+
await vite.build({
|
|
897
|
+
root,
|
|
898
|
+
build: {
|
|
899
|
+
ssr: ssrEntry,
|
|
900
|
+
outDir: "dist/server"
|
|
901
|
+
},
|
|
902
|
+
resolve: resolvedResolve,
|
|
903
|
+
css: resolvedCss
|
|
904
|
+
});
|
|
905
|
+
if (typeof options.setup === "string") {
|
|
906
|
+
console.log(" Building setup module...\n");
|
|
907
|
+
await vite.build({
|
|
908
|
+
root,
|
|
909
|
+
build: {
|
|
910
|
+
ssr: options.setup,
|
|
911
|
+
outDir: "dist/server",
|
|
912
|
+
emptyOutDir: false,
|
|
913
|
+
rollupOptions: {
|
|
914
|
+
output: { entryFileNames: "setup.mjs" }
|
|
915
|
+
}
|
|
916
|
+
},
|
|
917
|
+
resolve: resolvedResolve
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
if (options.adapter) {
|
|
921
|
+
const adapter = resolveAdapter(options.adapter);
|
|
922
|
+
const locales = options.locales ?? ["zh", "en"];
|
|
923
|
+
const defaultLocale = options.defaultLocale ?? locales[0] ?? "en";
|
|
924
|
+
const templateHtml = fs.readFileSync(
|
|
925
|
+
path.resolve(root, "dist/client/index.html"),
|
|
926
|
+
"utf-8"
|
|
927
|
+
);
|
|
928
|
+
const ctx = {
|
|
929
|
+
root,
|
|
930
|
+
ssrEntry,
|
|
931
|
+
setupPath: typeof options.setup === "string" ? options.setup : void 0,
|
|
932
|
+
locales,
|
|
933
|
+
defaultLocale,
|
|
934
|
+
templateHtml,
|
|
935
|
+
resolvedResolve,
|
|
936
|
+
resolvedCss,
|
|
937
|
+
vite,
|
|
938
|
+
fs,
|
|
939
|
+
path,
|
|
940
|
+
generateSSREntry(opts) {
|
|
941
|
+
return generateSSREntry(ctx, opts);
|
|
942
|
+
},
|
|
943
|
+
buildBundle(opts) {
|
|
944
|
+
return buildBundle(ctx, opts);
|
|
945
|
+
},
|
|
946
|
+
copyStaticAssets(destDir, opts) {
|
|
947
|
+
return copyStaticAssets(ctx, destDir, opts);
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
console.log(` Running adapter: ${adapter.name}...
|
|
951
|
+
`);
|
|
952
|
+
await adapter.build(ctx);
|
|
953
|
+
}
|
|
954
|
+
} finally {
|
|
955
|
+
delete process.env.__FINESOFT_SUB_BUILD__;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
};
|
|
959
|
+
}
|
|
455
960
|
export {
|
|
456
961
|
ACTION_KINDS,
|
|
457
962
|
ActionDispatcher,
|
|
@@ -472,7 +977,9 @@ export {
|
|
|
472
977
|
PrefetchedIntents,
|
|
473
978
|
Router,
|
|
474
979
|
SSR_PLACEHOLDERS,
|
|
980
|
+
autoAdapter,
|
|
475
981
|
buildUrl,
|
|
982
|
+
cloudflareAdapter,
|
|
476
983
|
createPrefetchedIntentsFromDom,
|
|
477
984
|
createSSRApp,
|
|
478
985
|
createSSRRender,
|
|
@@ -480,6 +987,7 @@ export {
|
|
|
480
987
|
defineRoutes,
|
|
481
988
|
deserializeServerData,
|
|
482
989
|
detectRuntime,
|
|
990
|
+
finesoftFrontViteConfig,
|
|
483
991
|
generateUuid,
|
|
484
992
|
getBaseUrl,
|
|
485
993
|
injectSSRContent,
|
|
@@ -492,6 +1000,8 @@ export {
|
|
|
492
1000
|
makeExternalUrlAction,
|
|
493
1001
|
makeFlowAction,
|
|
494
1002
|
mapEach,
|
|
1003
|
+
netlifyAdapter,
|
|
1004
|
+
nodeAdapter,
|
|
495
1005
|
parseAcceptLanguage,
|
|
496
1006
|
pipe,
|
|
497
1007
|
pipeAsync,
|
|
@@ -502,6 +1012,7 @@ export {
|
|
|
502
1012
|
removeQueryParams,
|
|
503
1013
|
removeScheme,
|
|
504
1014
|
resetFilterCache,
|
|
1015
|
+
resolveAdapter,
|
|
505
1016
|
resolveRoot,
|
|
506
1017
|
serializeServerData,
|
|
507
1018
|
shouldLog,
|
|
@@ -509,6 +1020,8 @@ export {
|
|
|
509
1020
|
stableStringify,
|
|
510
1021
|
startBrowserApp,
|
|
511
1022
|
startServer,
|
|
512
|
-
|
|
1023
|
+
staticAdapter,
|
|
1024
|
+
tryScroll,
|
|
1025
|
+
vercelAdapter
|
|
513
1026
|
};
|
|
514
1027
|
//# sourceMappingURL=index.js.map
|