@finesoft/front 0.1.20 → 0.1.21
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-Z3EFLAP2.js → app-BPO26FAD.js} +2 -2
- package/dist/{chunk-SN3OO3DU.js → chunk-IITKGRCO.js} +10 -2
- package/dist/chunk-IITKGRCO.js.map +1 -0
- package/dist/index.cjs +121 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +114 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-SN3OO3DU.js.map +0 -1
- /package/dist/{app-Z3EFLAP2.js.map → app-BPO26FAD.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../server/src/adapters/shared.ts","../../server/src/adapters/cloudflare.ts","../../server/src/adapters/netlify.ts","../../server/src/adapters/node.ts","../../server/src/adapters/static.ts","../../server/src/adapters/vercel.ts","../../server/src/adapters/resolve.ts","../../server/src/adapters/auto.ts","../../server/src/create-server.ts","../../server/src/runtime.ts","../../server/src/start.ts","../../server/src/vite-plugin.ts"],"sourcesContent":["/**\n * 适配器共享工具函数\n *\n * 提供 generateSSREntry / buildBundle / copyStaticAssets 三个方法,\n * 避免各适配器重复实现相同逻辑。\n */\n\nimport type {\n\tAdapterContext,\n\tBuildBundleOptions,\n\tCopyStaticAssetsOptions,\n\tGenerateSSREntryOptions,\n} from \"./types\";\n\nconst BUILD_TOOL_EXTERNALS = [\n\t\"vite\",\n\t\"esbuild\",\n\t\"rollup\",\n\t\"fsevents\",\n\t\"lightningcss\",\n];\n\n/**\n * 生成 SSR serverless/edge 入口源码\n *\n * 内联 parseAcceptLanguage / injectSSR 以避免\n * @finesoft/front → @finesoft/server → vite-plugin → import(\"vite\") 依赖链。\n */\nexport function generateSSREntry(\n\tctx: AdapterContext,\n\topts: GenerateSSREntryOptions,\n): string {\n\tconst setupImport = ctx.setupPath\n\t\t? `import _setupDefault from \"./${ctx.setupPath}\";`\n\t\t: ``;\n\tconst setupCall = ctx.setupPath\n\t\t? `if (typeof _setupDefault === \"function\") await _setupDefault(app);`\n\t\t: ``;\n\n\tconst locales = JSON.stringify(ctx.locales);\n\tconst defaultLocale = JSON.stringify(ctx.defaultLocale);\n\tconst renderModes = JSON.stringify(ctx.renderModes ?? {});\n\n\treturn `\nimport { Hono } from \"hono\";\n${opts.platformImport}\nimport { render, serializeServerData } from \"./${ctx.ssrEntry}\";\n${setupImport}\n\nconst TEMPLATE = ${JSON.stringify(ctx.templateHtml)};\nconst LOCALES = ${locales};\nconst DEFAULT_LOCALE = ${defaultLocale};\nconst RENDER_MODES = ${renderModes};\n\nfunction parseAcceptLanguage(header) {\n if (!header) return DEFAULT_LOCALE;\n const langs = header.split(\",\").map(p => {\n const [l, q] = p.trim().split(\";q=\");\n return { l: l.trim().toLowerCase(), q: q ? +q : 1 };\n }).sort((a, b) => b.q - a.q);\n for (const { l } of langs) {\n const prefix = l.split(\"-\")[0];\n if (LOCALES.includes(prefix)) return prefix;\n }\n return DEFAULT_LOCALE;\n}\n\nfunction injectSSR(t, locale, head, css, html, data) {\n return t\n .replace(\"<!--ssr-lang-->\", locale)\n .replace(\"<!--ssr-head-->\", head + \"\\\\n<style>\" + css + \"</style>\")\n .replace(\"<!--ssr-body-->\", html)\n .replace(\"<!--ssr-data-->\", '<script id=\"serialized-server-data\" type=\"application/json\">' + data + \"</script>\");\n}\n\nfunction injectCSRShell(t, locale) {\n return t\n .replace(\"<!--ssr-lang-->\", locale)\n .replace(\"<!--ssr-head-->\", \"\")\n .replace(\"<!--ssr-body-->\", \"\")\n .replace(\"<!--ssr-data-->\", \"\");\n}\n\nfunction matchRenderMode(url) {\n const path = url.split(\"?\")[0];\n if (RENDER_MODES[path]) return RENDER_MODES[path];\n for (const [pattern, mode] of Object.entries(RENDER_MODES)) {\n if (pattern.includes(\"*\")) {\n const re = new RegExp(\"^\" + pattern.replace(/\\\\*/g, \".*\") + \"$\");\n if (re.test(path)) return mode;\n }\n }\n return null;\n}\n\nconst isrCache = new Map();\n\nconst app = new Hono();\n${setupCall}\n\napp.get(\"*\", async (c) => {\n const url = c.req.path + (c.req.url.includes(\"?\") ? \"?\" + c.req.url.split(\"?\")[1] : \"\");\n try {\n const locale = parseAcceptLanguage(c.req.header(\"accept-language\"));\n\n // Vite 配置级别覆盖: CSR 直接返回空壳\n const overrideMode = matchRenderMode(url);\n if (overrideMode === \"csr\") {\n return c.html(injectCSRShell(TEMPLATE, locale));\n }\n\n // ISR 缓存命中\n const cached = isrCache.get(url);\n if (cached) return c.html(cached);\n\n const { html: appHtml, head, css, serverData, renderMode } = await render(url, locale);\n\n // 路由级 CSR\n if (renderMode === \"csr\") {\n return c.html(injectCSRShell(TEMPLATE, locale));\n }\n\n const serializedData = serializeServerData(serverData);\n const finalHtml = injectSSR(TEMPLATE, locale, head, css, appHtml, serializedData);\n\n // Prerender ISR 缓存(包括 Vite 配置覆盖和路由级)\n if (renderMode === \"prerender\" || overrideMode === \"prerender\") {\n isrCache.set(url, finalHtml);\n }\n\n return c.html(finalHtml);\n } catch (e) {\n console.error(\"[SSR Error]\", e);\n return c.text(\"Internal Server Error\", 500);\n }\n});\n\n${opts.platformExport}\n`;\n}\n\n/** 用 Vite SSR 模式构建 bundle */\nexport async function buildBundle(\n\tctx: AdapterContext,\n\topts: BuildBundleOptions,\n): Promise<void> {\n\tawait ctx.vite.build({\n\t\troot: ctx.root,\n\t\tbuild: {\n\t\t\tssr: opts.entry,\n\t\t\toutDir: opts.outDir,\n\t\t\temptyOutDir: true,\n\t\t\ttarget: opts.target ?? \"node18\",\n\t\t\trollupOptions: {\n\t\t\t\toutput: { entryFileNames: opts.fileName ?? \"index.mjs\" },\n\t\t\t},\n\t\t},\n\t\tssr: {\n\t\t\tnoExternal: opts.noExternal !== false,\n\t\t\texternal: opts.external ?? BUILD_TOOL_EXTERNALS,\n\t\t},\n\t\tresolve: ctx.resolvedResolve,\n\t\tcss: ctx.resolvedCss,\n\t});\n}\n\n/** 复制 dist/client 静态资源到目标目录 */\nexport function copyStaticAssets(\n\tctx: AdapterContext,\n\tdestDir: string,\n\topts?: CopyStaticAssetsOptions,\n): void {\n\tconst { fs, path } = ctx;\n\tfs.cpSync(path.resolve(ctx.root, \"dist/client\"), destDir, {\n\t\trecursive: true,\n\t});\n\tif (opts?.excludeHtml !== false) {\n\t\tfs.rmSync(path.join(destDir, \"index.html\"), { force: true });\n\t}\n}\n\nexport interface PrerenderResult {\n\turl: string;\n\thtml: string;\n}\n\n/**\n * 构建时预渲染 prerender 路由。\n *\n * 1. 加载路由定义文件,找出 renderMode === \"prerender\" 的路由\n * 2. 合并 ctx.renderModes 配置覆盖\n * 3. 渲染每个 URL × locale\n *\n * @param routesExport 导出 routes 数组的文件路径(相对项目根),默认 \"src/lib/bootstrap.ts\"\n */\nexport async function prerenderRoutes(\n\tctx: AdapterContext,\n\troutesExport = \"src/lib/bootstrap.ts\",\n): Promise<PrerenderResult[]> {\n\tconst { fs, path, root, vite } = ctx;\n\tconst { pathToFileURL } = await import(/* @vite-ignore */ \"node:url\");\n\n\t// ── 1. 构建并加载路由定义 ──\n\tawait vite.build({\n\t\troot,\n\t\tbuild: {\n\t\t\tssr: routesExport,\n\t\t\toutDir: path.resolve(root, \"dist/server\"),\n\t\t\temptyOutDir: false,\n\t\t\trollupOptions: {\n\t\t\t\toutput: { entryFileNames: \"_routes_prerender.mjs\" },\n\t\t\t},\n\t\t},\n\t\tresolve: ctx.resolvedResolve,\n\t});\n\n\tconst routesPath = pathToFileURL(\n\t\tpath.resolve(root, \"dist/server/_routes_prerender.mjs\"),\n\t).href;\n\tconst routesMod = await import(/* @vite-ignore */ routesPath);\n\tconst routes: Array<{ path: string; renderMode?: string }> =\n\t\troutesMod.routes ?? routesMod.default ?? [];\n\n\t// 清理临时文件\n\tfs.rmSync(path.resolve(root, \"dist/server/_routes_prerender.mjs\"), {\n\t\tforce: true,\n\t});\n\n\t// ── 2. 收集 prerender 路径 ──\n\tconst prerenderPaths = new Set<string>();\n\n\t// 路由定义级别\n\tfor (const r of routes) {\n\t\tif (r.renderMode === \"prerender\" && r.path && !r.path.includes(\":\")) {\n\t\t\tprerenderPaths.add(r.path);\n\t\t}\n\t}\n\n\t// Vite 配置覆盖级别\n\tif (ctx.renderModes) {\n\t\tfor (const [pattern, mode] of Object.entries(ctx.renderModes)) {\n\t\t\tif (\n\t\t\t\tmode === \"prerender\" &&\n\t\t\t\t!pattern.includes(\"*\") &&\n\t\t\t\t!pattern.includes(\":\")\n\t\t\t) {\n\t\t\t\tprerenderPaths.add(pattern);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (prerenderPaths.size === 0) return [];\n\n\t// ── 3. 加载 SSR 模块 ──\n\tconst ssrPath = pathToFileURL(\n\t\tpath.resolve(root, \"dist/server/ssr.js\"),\n\t).href;\n\tconst ssrModule = await import(/* @vite-ignore */ ssrPath);\n\n\t// ── 4. 渲染每个 URL × locale ──\n\tconst results: PrerenderResult[] = [];\n\n\tfor (const routePath of prerenderPaths) {\n\t\tfor (const locale of ctx.locales) {\n\t\t\tconst url =\n\t\t\t\tlocale === ctx.defaultLocale\n\t\t\t\t\t? routePath\n\t\t\t\t\t: `/${locale}${routePath === \"/\" ? \"\" : routePath}`;\n\t\t\ttry {\n\t\t\t\tconst {\n\t\t\t\t\thtml: appHtml,\n\t\t\t\t\thead,\n\t\t\t\t\tcss,\n\t\t\t\t\tserverData,\n\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\tconst serializedData =\n\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\tconst finalHtml = ctx.templateHtml\n\t\t\t\t\t.replace(\"<!--ssr-lang-->\", locale)\n\t\t\t\t\t.replace(\n\t\t\t\t\t\t\"<!--ssr-head-->\",\n\t\t\t\t\t\thead + \"\\n<style>\" + css + \"</style>\",\n\t\t\t\t\t)\n\t\t\t\t\t.replace(\"<!--ssr-body-->\", appHtml)\n\t\t\t\t\t.replace(\n\t\t\t\t\t\t\"<!--ssr-data-->\",\n\t\t\t\t\t\t'<script id=\"serialized-server-data\" type=\"application/json\">' +\n\t\t\t\t\t\t\tserializedData +\n\t\t\t\t\t\t\t\"</script>\",\n\t\t\t\t\t);\n\n\t\t\t\tresults.push({ url, html: finalHtml });\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn(` [prerender] Failed to render ${url}:`, e);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (results.length > 0) {\n\t\tconsole.log(\n\t\t\t` Pre-rendered ${results.length} pages (${prerenderPaths.size} routes × ${ctx.locales.length} locales)\\n`,\n\t\t);\n\t}\n\n\treturn results;\n}\n","/**\n * Cloudflare Pages 适配器\n *\n * 生成 dist/cloudflare/ 目录:\n * - _worker.js — Workers 入口(Hono 原生支持 CF fetch 接口)\n * - assets/ — 静态资源\n *\n * 注意:Cloudflare Workers 不支持原生 Node.js API。\n * 若 setup 代理使用了 process.env,需在 wrangler.toml 启用 nodejs_compat。\n */\n\nimport {\n\tbuildBundle,\n\tcopyStaticAssets,\n\tgenerateSSREntry,\n\tprerenderRoutes,\n} from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function cloudflareAdapter(): Adapter {\n\treturn {\n\t\tname: \"cloudflare\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \"dist/cloudflare\");\n\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\n\t\t\t// Hono 原生支持 CF Workers 的 fetch 接口,直接 export default app\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: ``,\n\t\t\t\tplatformExport: `export default app;`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".cf-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".cf-entry.tmp.mjs\",\n\t\t\t\t\toutDir: outputDir,\n\t\t\t\t\ttarget: \"es2022\",\n\t\t\t\t\tfileName: \"_worker.js\",\n\t\t\t\t\t// 使用默认 external(vite/esbuild/rollup/fsevents/lightningcss)\n\t\t\t\t\t// 这些构建工具运行时不需要,且 fsevents 是 macOS .node 原生二进制无法打包\n\t\t\t\t});\n\n\t\t\t\t// 静态资源\n\t\t\t\tcopyStaticAssets(ctx, path.resolve(outputDir, \"assets\"));\n\n\t\t\t\t// 构建时预渲染\n\t\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\t\tconst filePath =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? path.join(outputDir, \"assets\", \"index.html\")\n\t\t\t\t\t\t\t: path.join(outputDir, \"assets\", url, \"index.html\");\n\t\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), {\n\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t});\n\t\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\tconsole.log(\" Cloudflare output → dist/cloudflare/\\n\");\n\t\t},\n\t};\n}\n","/**\n * Netlify 适配器 — Netlify Functions v2\n *\n * 生成:\n * - .netlify/functions-internal/ssr/index.mjs — Serverless Function\n * - dist/client/_redirects — 路由重写规则\n */\n\nimport { buildBundle, generateSSREntry, prerenderRoutes } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function netlifyAdapter(): Adapter {\n\treturn {\n\t\tname: \"netlify\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst funcDir = path.resolve(\n\t\t\t\troot,\n\t\t\t\t\".netlify/functions-internal/ssr\",\n\t\t\t);\n\n\t\t\tfs.rmSync(path.resolve(root, \".netlify\"), {\n\t\t\t\trecursive: true,\n\t\t\t\tforce: true,\n\t\t\t});\n\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { handle } from \"hono/netlify\";`,\n\t\t\t\tplatformExport: `export default handle(app);`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".netlify-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".netlify-entry.tmp.mjs\",\n\t\t\t\t\toutDir: funcDir,\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\t// _redirects — 静态文件优先,其余走 SSR function\n\t\t\tconst redirects = `/* /.netlify/functions/ssr 200\\n`;\n\t\t\tfs.writeFileSync(\n\t\t\t\tpath.resolve(root, \"dist/client/_redirects\"),\n\t\t\t\tredirects,\n\t\t\t);\n\n\t\t\t// 构建时预渲染\n\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\tconst clientDir = path.resolve(root, \"dist/client\");\n\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\tconst filePath =\n\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t? path.join(clientDir, \"index.html\")\n\t\t\t\t\t\t: path.join(clientDir, url, \"index.html\");\n\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), { recursive: true });\n\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t\" Netlify output → .netlify/functions-internal/ssr/\\n\" +\n\t\t\t\t\t\" Publish dir: dist/client/\\n\",\n\t\t\t);\n\t\t},\n\t};\n}\n","/**\n * Node 适配器 — 独立 HTTP 服务器\n *\n * 生成 dist/server/index.mjs,使用 @hono/node-server 监听端口。\n * 运行:node dist/server/index.mjs\n */\n\nimport { buildBundle, generateSSREntry, prerenderRoutes } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function nodeAdapter(): Adapter {\n\treturn {\n\t\tname: \"node\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { serve } from \"@hono/node-server\";`,\n\t\t\t\tplatformExport: `\nconst port = +(process.env.PORT || 3000);\nserve({ fetch: app.fetch, port }, (info) => {\n console.log(\\`Server running at http://localhost:\\${info.port}\\`);\n});\n`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".node-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".node-entry.tmp.mjs\",\n\t\t\t\t\toutDir: path.resolve(root, \"dist/server\"),\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\t// 构建时预渲染 prerender 路由\n\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\tif (prerendered.length > 0) {\n\t\t\t\tconst prerenderDir = path.resolve(root, \"dist/prerender\");\n\t\t\t\tfs.mkdirSync(prerenderDir, { recursive: true });\n\t\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\t\tconst filePath =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? path.join(prerenderDir, \"index.html\")\n\t\t\t\t\t\t\t: path.join(prerenderDir, url, \"index.html\");\n\t\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), {\n\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t});\n\t\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t\" Node output → dist/server/index.mjs\\n\" +\n\t\t\t\t\t\" Run: node dist/server/index.mjs\\n\",\n\t\t\t);\n\t\t},\n\t};\n}\n","/**\n * Static 适配器 — 构建时预渲染\n *\n * 加载 SSR 模块和路由定义,将无参数路由自动预渲染为静态 HTML。\n * 动态参数路由通过 dynamicRoutes 选项补充具体 URL。\n *\n * 输出:dist/static/ — 纯静态站点,可部署到任何静态托管。\n */\n\nimport type { Adapter, AdapterContext } from \"./types\";\n\nexport interface StaticAdapterOptions {\n\t/**\n\t * 导出 routes 数组的文件路径(相对于项目根目录)。\n\t * 默认 \"src/lib/bootstrap.ts\"。\n\t * 文件需 export 一个 RouteDefinition[] 类型的 routes 变量。\n\t */\n\troutesExport?: string;\n\t/**\n\t * 额外的动态路由 URL(带具体参数值),如:\n\t * [\"/product/123\", \"/list/games\"]\n\t */\n\tdynamicRoutes?: string[];\n}\n\nexport function staticAdapter(opts: StaticAdapterOptions = {}): Adapter {\n\treturn {\n\t\tname: \"static\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root, vite } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \"dist/static\");\n\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\t\t\tfs.mkdirSync(outputDir, { recursive: true });\n\n\t\t\t// 加载 SSR 模块\n\t\t\tconst { pathToFileURL } = await import(\n\t\t\t\t/* @vite-ignore */ \"node:url\"\n\t\t\t);\n\t\t\tconst ssrPath = pathToFileURL(\n\t\t\t\tpath.resolve(root, \"dist/server/ssr.js\"),\n\t\t\t).href;\n\t\t\tconst ssrModule = await import(/* @vite-ignore */ ssrPath);\n\n\t\t\t// 先复制静态资源(JS/CSS 等),排除模板 index.html\n\t\t\tctx.copyStaticAssets(outputDir, { excludeHtml: true });\n\n\t\t\t// 提取路由列表(含 renderMode)\n\t\t\tconst { paths: routePaths, defs: routeDefs } =\n\t\t\t\tawait extractRoutesWithModes(ctx, opts);\n\t\t\tconst allUrls: string[] = [];\n\n\t\t\t// 对每个路由 × 每个 locale 生成 URL\n\t\t\tfor (const routePath of routePaths) {\n\t\t\t\tfor (const locale of ctx.locales) {\n\t\t\t\t\tconst url =\n\t\t\t\t\t\tlocale === ctx.defaultLocale\n\t\t\t\t\t\t\t? routePath\n\t\t\t\t\t\t\t: `/${locale}${routePath === \"/\" ? \"\" : routePath}`;\n\t\t\t\t\tallUrls.push(url);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t` Pre-rendering ${allUrls.length} pages (${routePaths.length} routes × ${ctx.locales.length} locales)...\\n`,\n\t\t\t);\n\n\t\t\t// 预渲染每个 URL\n\t\t\tfor (const url of allUrls) {\n\t\t\t\ttry {\n\t\t\t\t\t// 从 URL 推断 locale\n\t\t\t\t\tconst locale = inferLocale(\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tctx.locales,\n\t\t\t\t\t\tctx.defaultLocale,\n\t\t\t\t\t);\n\n\t\t\t\t\t// 检查渲染模式:路由级 + Vite 配置覆盖\n\t\t\t\t\tconst routeDef = routeDefs.find(\n\t\t\t\t\t\t(r) => r.path === stripLocalePrefix(url, ctx.locales),\n\t\t\t\t\t);\n\t\t\t\t\tconst mode = resolveRenderMode(\n\t\t\t\t\t\tstripLocalePrefix(url, ctx.locales),\n\t\t\t\t\t\trouteDef?.renderMode,\n\t\t\t\t\t\tctx.renderModes,\n\t\t\t\t\t);\n\n\t\t\t\t\tlet finalHtml: string;\n\n\t\t\t\t\tif (mode === \"csr\") {\n\t\t\t\t\t\t// CSR: 空壳 HTML,客户端 JS 渲染\n\t\t\t\t\t\tfinalHtml = injectCSRShellForStatic(\n\t\t\t\t\t\t\tctx.templateHtml,\n\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\tserverData,\n\t\t\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\t\t\tconst serializedData =\n\t\t\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\t\t\tfinalHtml = injectSSRForStatic(\n\t\t\t\t\t\t\tctx.templateHtml,\n\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\tappHtml,\n\t\t\t\t\t\t\tserializedData,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// 写入文件:/foo → dist/static/foo/index.html\n\t\t\t\t\tconst filePath =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? path.join(outputDir, \"index.html\")\n\t\t\t\t\t\t\t: path.join(outputDir, url, \"index.html\");\n\n\t\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), {\n\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t});\n\t\t\t\t\tfs.writeFileSync(filePath, finalHtml);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.warn(` [static] Failed to render ${url}:`, e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(` Static output → dist/static/\\n`);\n\t\t},\n\t};\n}\n\n/** 从路由文件提取无参数路由 + 合并 dynamicRoutes(含 renderMode) */\nasync function extractRoutesWithModes(\n\tctx: AdapterContext,\n\topts: StaticAdapterOptions,\n): Promise<{\n\tpaths: string[];\n\tdefs: Array<{ path: string; renderMode?: string }>;\n}> {\n\tconst routesFile = opts.routesExport ?? \"src/lib/bootstrap.ts\";\n\tconst paths: string[] = [];\n\tconst defs: Array<{ path: string; renderMode?: string }> = [];\n\n\ttry {\n\t\t// 使用 Vite SSR 构建加载路由文件\n\t\tconst { pathToFileURL } = await import(/* @vite-ignore */ \"node:url\");\n\n\t\t// 先构建路由文件\n\t\tawait ctx.vite.build({\n\t\t\troot: ctx.root,\n\t\t\tbuild: {\n\t\t\t\tssr: routesFile,\n\t\t\t\toutDir: ctx.path.resolve(ctx.root, \"dist/server\"),\n\t\t\t\temptyOutDir: false,\n\t\t\t\trollupOptions: {\n\t\t\t\t\toutput: { entryFileNames: \"_routes.mjs\" },\n\t\t\t\t},\n\t\t\t},\n\t\t\tresolve: ctx.resolvedResolve,\n\t\t});\n\n\t\tconst routesPath = pathToFileURL(\n\t\t\tctx.path.resolve(ctx.root, \"dist/server/_routes.mjs\"),\n\t\t).href;\n\t\tconst routesMod = await import(/* @vite-ignore */ routesPath);\n\n\t\t// 查找导出的 routes 数组\n\t\tconst routes: Array<{ path: string; renderMode?: string }> =\n\t\t\troutesMod.routes ?? routesMod.default;\n\n\t\tif (Array.isArray(routes)) {\n\t\t\tfor (const r of routes) {\n\t\t\t\tif (r.path && !r.path.includes(\":\")) {\n\t\t\t\t\tpaths.push(r.path);\n\t\t\t\t\tdefs.push({ path: r.path, renderMode: r.renderMode });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 清理临时文件\n\t\tctx.fs.rmSync(ctx.path.resolve(ctx.root, \"dist/server/_routes.mjs\"), {\n\t\t\tforce: true,\n\t\t});\n\t} catch (e) {\n\t\tconsole.warn(\n\t\t\t` [static] Could not load routes from \"${routesFile}\". Using \"/\" only.`,\n\t\t\te,\n\t\t);\n\t\tif (paths.length === 0) paths.push(\"/\");\n\t}\n\n\t// 合并 dynamicRoutes\n\tif (opts.dynamicRoutes) {\n\t\tfor (const r of opts.dynamicRoutes) {\n\t\t\tif (!paths.includes(r)) paths.push(r);\n\t\t}\n\t}\n\n\t// 至少包含根路径\n\tif (paths.length === 0) paths.push(\"/\");\n\n\treturn { paths, defs };\n}\n\n/** 从 URL 推断 locale */\nfunction inferLocale(\n\turl: string,\n\tlocales: string[],\n\tdefaultLocale: string,\n): string {\n\tconst segments = url.split(\"/\").filter(Boolean);\n\tif (segments.length > 0 && locales.includes(segments[0])) {\n\t\treturn segments[0];\n\t}\n\treturn defaultLocale;\n}\n\n/** 内联 SSR 注入(同 shared 中的逻辑) */\nfunction injectSSRForStatic(\n\ttemplate: string,\n\tlocale: string,\n\thead: string,\n\tcss: string,\n\thtml: string,\n\tserializedData: string,\n): string {\n\treturn template\n\t\t.replace(\"<!--ssr-lang-->\", locale)\n\t\t.replace(\"<!--ssr-head-->\", head + \"\\n<style>\" + css + \"</style>\")\n\t\t.replace(\"<!--ssr-body-->\", html)\n\t\t.replace(\n\t\t\t\"<!--ssr-data-->\",\n\t\t\t'<script id=\"serialized-server-data\" type=\"application/json\">' +\n\t\t\t\tserializedData +\n\t\t\t\t\"</script>\",\n\t\t);\n}\n\n/** CSR 空壳注入 */\nfunction injectCSRShellForStatic(template: string, locale: string): string {\n\treturn template\n\t\t.replace(\"<!--ssr-lang-->\", locale)\n\t\t.replace(\"<!--ssr-head-->\", \"\")\n\t\t.replace(\"<!--ssr-body-->\", \"\")\n\t\t.replace(\"<!--ssr-data-->\", \"\");\n}\n\n/** 从 URL 去除 locale 前缀,还原路由路径 */\nfunction stripLocalePrefix(url: string, locales: string[]): string {\n\tconst segments = url.split(\"/\").filter(Boolean);\n\tif (segments.length > 0 && locales.includes(segments[0])) {\n\t\tconst rest = segments.slice(1).join(\"/\");\n\t\treturn rest ? `/${rest}` : \"/\";\n\t}\n\treturn url;\n}\n\n/** 解析最终渲染模式:Vite 配置覆盖 > 路由级 > 默认 \"ssr\" */\nfunction resolveRenderMode(\n\troutePath: string,\n\trouteRenderMode?: string,\n\trenderModes?: Record<string, string>,\n): string {\n\t// Vite 配置覆盖优先\n\tif (renderModes) {\n\t\tif (renderModes[routePath]) return renderModes[routePath];\n\t\tfor (const [pattern, mode] of Object.entries(renderModes)) {\n\t\t\tif (pattern.includes(\"*\")) {\n\t\t\t\tconst re = new RegExp(\"^\" + pattern.replace(/\\*/g, \".*\") + \"$\");\n\t\t\t\tif (re.test(routePath)) return mode;\n\t\t\t}\n\t\t}\n\t}\n\treturn routeRenderMode ?? \"ssr\";\n}\n","/**\n * Vercel 适配器 — Build Output API v3\n *\n * 生成 .vercel/output/ 目录:\n * - config.json — 路由规则\n * - static/ — 静态资源\n * - functions/ssr.func/ — Serverless Function\n */\n\nimport {\n\tbuildBundle,\n\tcopyStaticAssets,\n\tgenerateSSREntry,\n\tprerenderRoutes,\n} from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function vercelAdapter(): Adapter {\n\treturn {\n\t\tname: \"vercel\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \".vercel/output\");\n\n\t\t\t// 清理旧输出\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\n\t\t\t// 生成入口源码\n\t\t\t// Vercel Serverless (launcherType: \"Nodejs\") 传入 Node.js IncomingMessage,\n\t\t\t// 必须用 @hono/node-server 转换为 Web Request,而非 hono/vercel 的 handle。\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { getRequestListener } from \"@hono/node-server\";`,\n\t\t\t\tplatformExport: `export default getRequestListener(app.fetch);`,\n\t\t\t});\n\n\t\t\t// 写入临时入口文件\n\t\t\tconst tempEntry = path.resolve(root, \".vercel-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tconst funcDir = path.resolve(\n\t\t\t\t\troot,\n\t\t\t\t\t\".vercel/output/functions/ssr.func\",\n\t\t\t\t);\n\n\t\t\t\t// 构建 serverless function\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".vercel-entry.tmp.mjs\",\n\t\t\t\t\toutDir: funcDir,\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\n\t\t\t\t// .vc-config.json\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tpath.resolve(funcDir, \".vc-config.json\"),\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\truntime: \"nodejs20.x\",\n\t\t\t\t\t\t\thandler: \"index.mjs\",\n\t\t\t\t\t\t\tlauncherType: \"Nodejs\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t2,\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\t// 静态资源\n\t\t\t\tcopyStaticAssets(\n\t\t\t\t\tctx,\n\t\t\t\t\tpath.resolve(root, \".vercel/output/static\"),\n\t\t\t\t);\n\n\t\t\t\t// 路由配置\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tpath.resolve(root, \".vercel/output/config.json\"),\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tversion: 3,\n\t\t\t\t\t\t\troutes: [\n\t\t\t\t\t\t\t\t{ handle: \"filesystem\" },\n\t\t\t\t\t\t\t\t{ src: \"/(.*)\", dest: \"/ssr\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t2,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\t\t\t// 构建时预渲染 prerender 路由\n\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\tconst staticDir = path.resolve(root, \".vercel/output/static\");\n\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\tconst filePath =\n\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t? path.join(staticDir, \"index.html\")\n\t\t\t\t\t\t: path.join(staticDir, url, \"index.html\");\n\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), { recursive: true });\n\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t}\n\t\t\tconsole.log(\" Vercel output → .vercel/output/\\n\");\n\t\t},\n\t};\n}\n","/**\n * resolveAdapter — 字符串 → Adapter 映射\n */\n\nimport { autoAdapter } from \"./auto\";\nimport { cloudflareAdapter } from \"./cloudflare\";\nimport { netlifyAdapter } from \"./netlify\";\nimport { nodeAdapter } from \"./node\";\nimport { staticAdapter } from \"./static\";\nimport type { Adapter } from \"./types\";\nimport { vercelAdapter } from \"./vercel\";\n\nexport function resolveAdapter(value: string | Adapter): Adapter {\n\tif (typeof value !== \"string\") return value;\n\n\tswitch (value) {\n\t\tcase \"vercel\":\n\t\t\treturn vercelAdapter();\n\t\tcase \"cloudflare\":\n\t\t\treturn cloudflareAdapter();\n\t\tcase \"netlify\":\n\t\t\treturn netlifyAdapter();\n\t\tcase \"node\":\n\t\t\treturn nodeAdapter();\n\t\tcase \"static\":\n\t\t\treturn staticAdapter();\n\t\tcase \"auto\":\n\t\t\treturn autoAdapter();\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`[finesoft] Unknown adapter: \"${value}\". ` +\n\t\t\t\t\t`Available: vercel, cloudflare, netlify, node, static, auto`,\n\t\t\t);\n\t}\n}\n","/**\n * Auto 适配器 — 根据环境变量自动选择目标平台\n *\n * 检测顺序:\n * VERCEL → vercel\n * CF_PAGES → cloudflare\n * NETLIFY → netlify\n * (default) → node\n */\n\nimport { resolveAdapter } from \"./resolve\";\nimport type { Adapter } from \"./types\";\n\nexport function autoAdapter(): Adapter {\n\treturn {\n\t\tname: \"auto\",\n\t\tasync build(ctx) {\n\t\t\tconst detected = detectPlatform();\n\t\t\tconsole.log(` [auto] Detected platform: ${detected}\\n`);\n\t\t\tconst adapter = resolveAdapter(detected);\n\t\t\treturn adapter.build(ctx);\n\t\t},\n\t};\n}\n\nfunction detectPlatform(): string {\n\tif (process.env.VERCEL) return \"vercel\";\n\tif (process.env.CF_PAGES) return \"cloudflare\";\n\tif (process.env.NETLIFY) return \"netlify\";\n\treturn \"node\";\n}\n","/**\n * createServer — 一站式服务器工厂\n *\n * 封装 env 加载、运行时检测、Vite 创建、Hono app、SSR、启动。\n * 保留 setup() 钩子用于注册业务路由。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { createSSRApp, type SSRAppOptions } from \"./app\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\nimport { startServer } from \"./start\";\n\nexport interface ServerConfig {\n\t/** 项目根路径(默认 process.cwd()) */\n\troot?: string;\n\t/** 支持的语言列表 */\n\tlocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/** 端口号(默认 3000) */\n\tport?: number;\n\t/** 注册业务路由(在 SSR catch-all 之前调用) */\n\tsetup?: (app: Hono) => void | Promise<void>;\n\t/** SSR 相关选项(透传给 createSSRApp) */\n\tssr?: Pick<SSRAppOptions, \"ssrEntryPath\" | \"ssrProductionModule\">;\n}\n\nexport interface ServerInstance {\n\tapp: Hono;\n\tvite?: ViteDevServer;\n\truntime: RuntimeInfo;\n}\n\n/**\n * 创建并启动 SSR 服务器\n *\n * @example\n * ```ts\n * const { app } = await createServer({\n * locales: [\"zh\", \"en\"],\n * setup: (app) => registerProxies(app),\n * });\n * export { app };\n * ```\n */\nexport async function createServer(\n\tconfig: ServerConfig = {},\n): Promise<ServerInstance> {\n\tconst {\n\t\troot: rootOverride,\n\t\tlocales,\n\t\tdefaultLocale,\n\t\tport = Number(process.env.PORT) || 3000,\n\t\tsetup,\n\t\tssr,\n\t} = config;\n\n\t// 1. 路径 + .env\n\tconst root = rootOverride ?? process.cwd();\n\tconst { existsSync } = await import(/* @vite-ignore */ \"node:fs\");\n\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\tconst envPath = resolve(root, \".env\");\n\tif (existsSync(envPath)) {\n\t\ttry {\n\t\t\tconst { config: dotenvConfig } = await import(\n\t\t\t\t/* @vite-ignore */ \"dotenv\"\n\t\t\t);\n\t\t\tdotenvConfig({ path: envPath });\n\t\t} catch {\n\t\t\t// dotenv 未安装则跳过,调用方可自行加载 .env\n\t\t}\n\t}\n\n\t// 2. 运行时检测\n\tconst runtime = detectRuntime();\n\n\t// 3. Vite(仅开发模式)\n\tlet vite: ViteDevServer | undefined;\n\tif (!runtime.isProduction && !runtime.isVercel) {\n\t\tconst { createServer: createViteServer } = await import(\n\t\t\t/* @vite-ignore */ \"vite\"\n\t\t);\n\t\tvite = await createViteServer({\n\t\t\troot,\n\t\t\tserver: { middlewareMode: true },\n\t\t\tappType: \"custom\",\n\t\t});\n\t}\n\n\t// 4. Hono app + 业务路由\n\tconst app = new Hono();\n\tif (setup) {\n\t\tawait setup(app);\n\t}\n\n\t// 5. SSR catch-all\n\tconst ssrApp = createSSRApp({\n\t\troot,\n\t\tvite,\n\t\tisProduction: runtime.isProduction,\n\t\tsupportedLocales: locales,\n\t\tdefaultLocale,\n\t\t...ssr,\n\t});\n\tapp.route(\"/\", ssrApp);\n\n\t// 6. 启动\n\tawait startServer({\n\t\tapp,\n\t\troot,\n\t\tport,\n\t\tisProduction: runtime.isProduction,\n\t\tvite,\n\t\truntime,\n\t\tlocales,\n\t\tssrEntryPath: ssr?.ssrEntryPath,\n\t});\n\n\treturn { app, vite, runtime };\n}\n","/**\n * runtime — 运行时检测 + 项目根路径推导\n */\n\nexport interface RuntimeInfo {\n\tisDeno: boolean;\n\tisBun: boolean;\n\tisVercel: boolean;\n\tisProduction: boolean;\n}\n\n/** 检测当前运行时环境 */\nexport function detectRuntime(): RuntimeInfo {\n\treturn {\n\t\tisDeno: typeof (globalThis as any).Deno !== \"undefined\",\n\t\tisBun: typeof (globalThis as any).Bun !== \"undefined\",\n\t\tisVercel: !!process.env.VERCEL,\n\t\tisProduction: process.env.NODE_ENV === \"production\",\n\t};\n}\n\n/**\n * 从 `import.meta.url` 推导项目根路径\n *\n * @param importMetaUrl - 调用方的 `import.meta.url`\n * @param levelsUp - 向上移动多少级(默认 0,即调用方所在目录就是项目根)\n */\nexport async function resolveRoot(\n\timportMetaUrl: string,\n\tlevelsUp = 0,\n): Promise<string> {\n\tconst isDeno = typeof (globalThis as any).Deno !== \"undefined\";\n\n\tif (isDeno) {\n\t\tlet url = new URL(importMetaUrl);\n\t\tfor (let i = 0; i < levelsUp; i++) {\n\t\t\turl = new URL(\"..\", url);\n\t\t}\n\t\treturn url.pathname;\n\t}\n\n\tconst { dirname, resolve, normalize } = await import(\n\t\t/* @vite-ignore */ \"node:path\"\n\t);\n\tconst { fileURLToPath } = await import(/* @vite-ignore */ \"node:url\");\n\tlet dir = normalize(dirname(fileURLToPath(importMetaUrl)));\n\tfor (let i = 0; i < levelsUp; i++) {\n\t\tdir = resolve(dir, \"..\");\n\t}\n\treturn dir;\n}\n","/**\n * startServer — 多运行时自动启动\n *\n * 支持 Node.js (dev HMR + prod)、Deno、Bun、Vercel。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\n\nexport interface StartServerOptions {\n\t/** 最终的 Hono app(已包含 SSR + 自定义路由) */\n\tapp: Hono;\n\t/** 项目根路径 */\n\troot: string;\n\t/** 端口号 */\n\tport?: number;\n\t/** 是否生产环境 */\n\tisProduction: boolean;\n\t/** Vite dev server(仅开发模式传入) */\n\tvite?: ViteDevServer;\n\t/** 运行时信息(可选,不传时自动检测) */\n\truntime?: RuntimeInfo;\n\t/** 已注册的路由列表(用于启动日志) */\n\troutes?: string[];\n\t/** 支持的语言列表(用于启动日志) */\n\tlocales?: string[];\n\t/** SSR 入口路径(用于启动日志) */\n\tssrEntryPath?: string;\n}\n\nexport async function startServer(\n\toptions: StartServerOptions,\n): Promise<{ vite?: ViteDevServer }> {\n\tconst {\n\t\tapp,\n\t\troot,\n\t\tport = 3000,\n\t\tisProduction,\n\t\tvite,\n\t\troutes,\n\t\tlocales,\n\t\tssrEntryPath,\n\t} = options;\n\n\tconst { isDeno, isBun, isVercel } = options.runtime ?? detectRuntime();\n\n\tfunction printStartupBanner() {\n\t\tconst lines: string[] = [\n\t\t\t`\\n Server running at http://localhost:${port}\\n`,\n\t\t];\n\t\tif (routes && routes.length > 0) {\n\t\t\tlines.push(\" Routes:\");\n\t\t\tfor (const r of routes) {\n\t\t\t\tlines.push(` ${r}`);\n\t\t\t}\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tif (locales && locales.length > 0) {\n\t\t\tlines.push(` Locales: ${locales.join(\", \")}`);\n\t\t}\n\t\tif (ssrEntryPath) {\n\t\t\tlines.push(` SSR Entry: ${ssrEntryPath}`);\n\t\t}\n\t\tif (locales?.length || ssrEntryPath) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tconsole.log(lines.join(\"\\n\"));\n\t}\n\n\tif (isVercel) {\n\t\treturn { vite };\n\t}\n\n\tif (!isProduction) {\n\t\tlet devVite = vite;\n\t\tif (!devVite) {\n\t\t\tconst { createServer: createViteServer } = await import(\n\t\t\t\t/* @vite-ignore */ \"vite\"\n\t\t\t);\n\t\t\tdevVite = await createViteServer({\n\t\t\t\troot,\n\t\t\t\tserver: { middlewareMode: true },\n\t\t\t\tappType: \"custom\",\n\t\t\t});\n\t\t}\n\n\t\tconst { getRequestListener } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t);\n\t\tconst { createServer } = await import(/* @vite-ignore */ \"node:http\");\n\t\tconst listener = getRequestListener(app.fetch);\n\t\tconst server = createServer((req: any, res: any) => {\n\t\t\tdevVite!.middlewares(req, res, () => listener(req, res));\n\t\t});\n\t\tserver.listen(port, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t\treturn { vite: devVite };\n\t}\n\n\tif (isDeno) {\n\t\t(globalThis as any).Deno.serve({ port }, app.fetch);\n\t} else if (isBun) {\n\t\t// Bun uses export default\n\t} else {\n\t\t// Node.js production\n\t\tconst { serveStatic } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server/serve-static\"\n\t\t);\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\tconst prodApp = new Hono();\n\t\tconst clientDir = resolve(root, \"dist/client\");\n\t\tprodApp.use(\n\t\t\t\"/*\",\n\t\t\tserveStatic({\n\t\t\t\troot: clientDir,\n\t\t\t\t// 禁止目录路径自动提供 index.html,让其 fall through 到 SSR\n\t\t\t\trewriteRequestPath: (path: string) =>\n\t\t\t\t\tpath.endsWith(\"/\") ? \"/__nosuchfile__\" : path,\n\t\t\t}),\n\t\t);\n\t\tprodApp.route(\"/\", app);\n\n\t\tconst { serve } = await import(/* @vite-ignore */ \"@hono/node-server\");\n\t\tserve({ fetch: prodApp.fetch, port }, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t}\n\n\treturn { vite };\n}\n","/**\n * finesoftFrontViteConfig — Vite 插件\n *\n * 将 Hono SSR 服务器集成到 Vite 的 dev / build / preview 生命周期中,\n * 使 template-project 只需 `vite` / `vite build` / `vite preview` 即可运行。\n *\n * 支持多平台 adapter: \"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | \"static\" | \"auto\"\n * 或自定义 Adapter 对象。\n */\n\nimport type { Hono } from \"hono\";\nimport { resolveAdapter } from \"./adapters/resolve\";\nimport {\n\tbuildBundle,\n\tcopyStaticAssets,\n\tgenerateSSREntry,\n} from \"./adapters/shared\";\nimport type { Adapter } from \"./adapters/types\";\nimport type { SSRModule } from \"./app\";\n\nexport interface FinesoftFrontViteOptions {\n\t/** 支持的语言列表 */\n\tlocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/** SSR 配置 */\n\tssr?: {\n\t\t/** SSR 入口文件路径(默认 \"src/ssr.ts\") */\n\t\tentry?: string;\n\t};\n\t/**\n\t * 注册业务路由(API 代理等)。\n\t * - 传入 Function:仅 dev/preview 时可用。\n\t * - 传入 string(文件路径):dev/preview/adapter 均可用,\n\t * 文件需 export default 一个 (app: Hono) => void 函数。\n\t */\n\tsetup?: ((app: Hono) => void | Promise<void>) | string;\n\t/**\n\t * 部署适配器。\n\t * - 字符串快捷方式:\"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | \"static\" | \"auto\"\n\t * - 自定义 Adapter 对象:{ name, build(ctx) }\n\t * - 不设置则不生成部署产物\n\t */\n\tadapter?: string | Adapter;\n\t/**\n\t * 按路由覆盖渲染模式(优先级高于 RouteDefinition.renderMode)。\n\t * key: 精确路径或 glob 模式,如 \"/search\" 或 \"/blog/*\"\n\t * value: \"ssr\" | \"csr\" | \"prerender\"\n\t *\n\t * @example\n\t * ```ts\n\t * renderModes: {\n\t * \"/search\": \"csr\",\n\t * \"/blog/*\": \"prerender\",\n\t * }\n\t * ```\n\t */\n\trenderModes?: Record<string, \"ssr\" | \"csr\" | \"prerender\">;\n}\n\n/**\n * 从 setup 模块中查找 setup 函数:优先 default,其次 setup 命名导出。\n */\nfunction resolveSetupFn(\n\tmod: Record<string, unknown>,\n): ((app: any) => void | Promise<void>) | null {\n\tif (typeof mod.default === \"function\") return mod.default as any;\n\tif (typeof mod.setup === \"function\") return mod.setup as any;\n\tconst first = Object.values(mod).find((v) => typeof v === \"function\");\n\treturn (first as any) ?? null;\n}\n\n/**\n * 匹配 Vite 配置级别的 renderMode 覆盖。\n * 精确路径优先,然后 glob 模式。\n */\nfunction matchRenderModeConfig(\n\turl: string,\n\trenderModes?: Record<string, string>,\n): string | null {\n\tif (!renderModes) return null;\n\tconst path = url.split(\"?\")[0];\n\tif (renderModes[path]) return renderModes[path];\n\tfor (const [pattern, mode] of Object.entries(renderModes)) {\n\t\tif (pattern.includes(\"*\")) {\n\t\t\tconst re = new RegExp(\"^\" + pattern.replace(/\\*/g, \".*\") + \"$\");\n\t\t\tif (re.test(path)) return mode;\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function finesoftFrontViteConfig(\n\toptions: FinesoftFrontViteOptions = {},\n) {\n\tconst ssrEntry = options.ssr?.entry ?? \"src/ssr.ts\";\n\tlet root = process.cwd();\n\tlet resolvedCommand: string | undefined;\n\tlet resolvedResolve: unknown;\n\tlet resolvedCss: unknown;\n\n\treturn {\n\t\tname: \"finesoft-front\",\n\n\t\tconfig(userConfig: Record<string, any>, env: { command: string }) {\n\t\t\tconst overrides: Record<string, any> = {\n\t\t\t\tappType: \"custom\",\n\t\t\t};\n\t\t\tif (\n\t\t\t\tenv.command === \"build\" &&\n\t\t\t\t!process.env.__FINESOFT_SUB_BUILD__\n\t\t\t) {\n\t\t\t\toverrides.build = {\n\t\t\t\t\toutDir: userConfig.build?.outDir ?? \"dist/client\",\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn overrides;\n\t\t},\n\n\t\tconfigResolved(config: Record<string, any>) {\n\t\t\tresolvedCommand = config.command as string;\n\t\t\tresolvedResolve = config.resolve;\n\t\t\tresolvedCss = config.css;\n\t\t\troot = config.root as string;\n\t\t},\n\n\t\t// ─── Dev ───────────────────────────────────────────────\n\t\tconfigureServer(server: any) {\n\t\t\treturn async () => {\n\t\t\t\tconst { Hono: HonoClass } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"hono\"\n\t\t\t\t);\n\t\t\t\tconst { createSSRApp } = await import(\"./app\");\n\t\t\t\tconst { getRequestListener } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t\t\t);\n\n\t\t\t\tconst app = new HonoClass();\n\n\t\t\t\t// Setup: 函数直接调用,文件路径通过 ssrLoadModule 加载\n\t\t\t\tif (typeof options.setup === \"function\") {\n\t\t\t\t\tawait options.setup(app);\n\t\t\t\t} else if (typeof options.setup === \"string\") {\n\t\t\t\t\tconst mod = await server.ssrLoadModule(\"/\" + options.setup);\n\t\t\t\t\tconst fn = resolveSetupFn(mod);\n\t\t\t\t\tif (fn) await fn(app);\n\t\t\t\t}\n\n\t\t\t\tconst ssrApp = createSSRApp({\n\t\t\t\t\troot,\n\t\t\t\t\tvite: server,\n\t\t\t\t\tisProduction: false,\n\t\t\t\t\tssrEntryPath: \"/\" + ssrEntry,\n\t\t\t\t\tsupportedLocales: options.locales,\n\t\t\t\t\tdefaultLocale: options.defaultLocale,\n\t\t\t\t});\n\t\t\t\tapp.route(\"/\", ssrApp);\n\n\t\t\t\tconst listener = getRequestListener(app.fetch);\n\n\t\t\t\tserver.middlewares.use((req: any, res: any) => {\n\t\t\t\t\tlistener(req, res);\n\t\t\t\t});\n\t\t\t};\n\t\t},\n\n\t\t// ─── Preview ───────────────────────────────────────────\n\t\tconfigurePreviewServer(server: any) {\n\t\t\treturn async () => {\n\t\t\t\tconst { readFileSync } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:fs\"\n\t\t\t\t);\n\t\t\t\tconst { resolve } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:path\"\n\t\t\t\t);\n\t\t\t\tconst { pathToFileURL } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:url\"\n\t\t\t\t);\n\t\t\t\tconst { Hono: HonoClass } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"hono\"\n\t\t\t\t);\n\t\t\t\tconst { injectSSRContent, injectCSRShell } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@finesoft/ssr\"\n\t\t\t\t);\n\t\t\t\tconst { parseAcceptLanguage } = await import(\"./locale\");\n\t\t\t\tconst { getRequestListener } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t\t\t);\n\n\t\t\t\tconst app = new HonoClass();\n\n\t\t\t\t// ISR 内存缓存\n\t\t\t\tconst isrCache = new Map<string, string>();\n\n\t\t\t\t// Setup: 函数直接调用,文件路径从构建产物加载\n\t\t\t\tif (typeof options.setup === \"function\") {\n\t\t\t\t\tawait options.setup(app);\n\t\t\t\t} else if (typeof options.setup === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst setupPath = pathToFileURL(\n\t\t\t\t\t\t\tresolve(root, \"dist/server/setup.mjs\"),\n\t\t\t\t\t\t).href;\n\t\t\t\t\t\tconst mod = await import(/* @vite-ignore */ setupPath);\n\t\t\t\t\t\tconst fn = resolveSetupFn(\n\t\t\t\t\t\t\tmod as Record<string, unknown>,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (fn) await fn(app);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\"[finesoft] Could not load setup module for preview. API routes disabled.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst templatePath = resolve(root, \"dist/client/index.html\");\n\t\t\t\tconst template = readFileSync(templatePath, \"utf-8\");\n\n\t\t\t\tconst ssrPath = pathToFileURL(\n\t\t\t\t\tresolve(root, \"dist/server/ssr.js\"),\n\t\t\t\t).href;\n\t\t\t\tconst ssrModule = (await import(\n\t\t\t\t\t/* @vite-ignore */ ssrPath\n\t\t\t\t)) as SSRModule;\n\n\t\t\t\tapp.get(\"*\", async (c: any) => {\n\t\t\t\t\tconst url =\n\t\t\t\t\t\tc.req.path +\n\t\t\t\t\t\t(c.req.url.includes(\"?\")\n\t\t\t\t\t\t\t? \"?\" + c.req.url.split(\"?\")[1]\n\t\t\t\t\t\t\t: \"\");\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst locale = parseAcceptLanguage(\n\t\t\t\t\t\t\tc.req.header(\"accept-language\"),\n\t\t\t\t\t\t\toptions.locales,\n\t\t\t\t\t\t\toptions.defaultLocale,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Vite 配置级别覆盖\n\t\t\t\t\t\tconst overrideMode = matchRenderModeConfig(\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\toptions.renderModes,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (overrideMode === \"csr\") {\n\t\t\t\t\t\t\treturn c.html(injectCSRShell(template, locale));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// ISR 缓存命中\n\t\t\t\t\t\tconst cached = isrCache.get(url);\n\t\t\t\t\t\tif (cached) return c.html(cached);\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\tserverData,\n\t\t\t\t\t\t\trenderMode,\n\t\t\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\t\t\t// 路由级 CSR\n\t\t\t\t\t\tif (renderMode === \"csr\") {\n\t\t\t\t\t\t\treturn c.html(injectCSRShell(template, locale));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst serializedData =\n\t\t\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\t\t\tconst finalHtml = injectSSRContent({\n\t\t\t\t\t\t\ttemplate,\n\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\tserializedData,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Prerender ISR 缓存\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\trenderMode === \"prerender\" ||\n\t\t\t\t\t\t\toverrideMode === \"prerender\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisrCache.set(url, finalHtml);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn c.html(finalHtml);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.error(\"[SSR Preview Error]\", e);\n\t\t\t\t\t\treturn c.text(\"Internal Server Error\", 500);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst listener = getRequestListener(app.fetch);\n\n\t\t\t\tserver.middlewares.use((req: any, res: any) => {\n\t\t\t\t\tlistener(req, res);\n\t\t\t\t});\n\t\t\t};\n\t\t},\n\n\t\t// ─── Build ─────────────────────────────────────────────\n\t\tasync closeBundle() {\n\t\t\tif (process.env.__FINESOFT_SUB_BUILD__) return;\n\t\t\tif (resolvedCommand !== \"build\") return;\n\n\t\t\tprocess.env.__FINESOFT_SUB_BUILD__ = \"1\";\n\t\t\ttry {\n\t\t\t\tconst vite: any = await import(/* @vite-ignore */ \"vite\");\n\t\t\t\tconst fs = await import(/* @vite-ignore */ \"node:fs\");\n\t\t\t\tconst path = await import(/* @vite-ignore */ \"node:path\");\n\n\t\t\t\t// ── 1. SSR 构建 ──\n\t\t\t\tconsole.log(\"\\n Building SSR bundle...\\n\");\n\t\t\t\tawait vite.build({\n\t\t\t\t\troot,\n\t\t\t\t\tbuild: {\n\t\t\t\t\t\tssr: ssrEntry,\n\t\t\t\t\t\toutDir: \"dist/server\",\n\t\t\t\t\t},\n\t\t\t\t\tresolve: resolvedResolve,\n\t\t\t\t\tcss: resolvedCss,\n\t\t\t\t});\n\n\t\t\t\t// ── 2. Setup 模块构建(仅当 setup 是文件路径时) ──\n\t\t\t\tif (typeof options.setup === \"string\") {\n\t\t\t\t\tconsole.log(\" Building setup module...\\n\");\n\t\t\t\t\tawait vite.build({\n\t\t\t\t\t\troot,\n\t\t\t\t\t\tbuild: {\n\t\t\t\t\t\t\tssr: options.setup,\n\t\t\t\t\t\t\toutDir: \"dist/server\",\n\t\t\t\t\t\t\temptyOutDir: false,\n\t\t\t\t\t\t\trollupOptions: {\n\t\t\t\t\t\t\t\toutput: { entryFileNames: \"setup.mjs\" },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresolve: resolvedResolve,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// ── 3. Adapter 构建 ──\n\t\t\t\tif (options.adapter) {\n\t\t\t\t\tconst adapter = resolveAdapter(options.adapter);\n\n\t\t\t\t\tconst locales = options.locales ?? [\"zh\", \"en\"];\n\t\t\t\t\tconst defaultLocale =\n\t\t\t\t\t\toptions.defaultLocale ?? locales[0] ?? \"en\";\n\t\t\t\t\tconst templateHtml = fs.readFileSync(\n\t\t\t\t\t\tpath.resolve(root, \"dist/client/index.html\"),\n\t\t\t\t\t\t\"utf-8\",\n\t\t\t\t\t);\n\n\t\t\t\t\tconst ctx = {\n\t\t\t\t\t\troot,\n\t\t\t\t\t\tssrEntry,\n\t\t\t\t\t\tsetupPath:\n\t\t\t\t\t\t\ttypeof options.setup === \"string\"\n\t\t\t\t\t\t\t\t? options.setup\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tlocales,\n\t\t\t\t\t\tdefaultLocale,\n\t\t\t\t\t\ttemplateHtml,\n\t\t\t\t\t\trenderModes: options.renderModes,\n\t\t\t\t\t\tresolvedResolve,\n\t\t\t\t\t\tresolvedCss,\n\t\t\t\t\t\tvite,\n\t\t\t\t\t\tfs,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tgenerateSSREntry(opts: any) {\n\t\t\t\t\t\t\treturn generateSSREntry(ctx, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbuildBundle(opts: any) {\n\t\t\t\t\t\t\treturn buildBundle(ctx, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcopyStaticAssets(destDir: string, opts?: any) {\n\t\t\t\t\t\t\treturn copyStaticAssets(ctx, destDir, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\t\tconsole.log(` Running adapter: ${adapter.name}...\\n`);\n\t\t\t\t\tawait adapter.build(ctx);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tdelete process.env.__FINESOFT_SUB_BUILD__;\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["Hono","createServer","Hono","createSSRApp","injectSSRContent","injectCSRShell","parseAcceptLanguage"]}
|
|
1
|
+
{"version":3,"sources":["../../server/src/adapters/shared.ts","../../server/src/adapters/cloudflare.ts","../../server/src/adapters/netlify.ts","../../server/src/adapters/node.ts","../../server/src/adapters/static.ts","../../server/src/adapters/vercel.ts","../../server/src/adapters/resolve.ts","../../server/src/adapters/auto.ts","../../server/src/create-server.ts","../../server/src/runtime.ts","../../server/src/start.ts","../../server/src/vite-plugin.ts"],"sourcesContent":["/**\n * 适配器共享工具函数\n *\n * 提供 generateSSREntry / buildBundle / copyStaticAssets 三个方法,\n * 避免各适配器重复实现相同逻辑。\n */\n\nimport type {\n\tAdapterContext,\n\tBuildBundleOptions,\n\tCopyStaticAssetsOptions,\n\tGenerateSSREntryOptions,\n} from \"./types\";\n\nconst BUILD_TOOL_EXTERNALS = [\n\t\"vite\",\n\t\"esbuild\",\n\t\"rollup\",\n\t\"fsevents\",\n\t\"lightningcss\",\n];\n\n/**\n * 生成 SSR serverless/edge 入口源码\n *\n * 内联 parseAcceptLanguage / injectSSR 以避免\n * @finesoft/front → @finesoft/server → vite-plugin → import(\"vite\") 依赖链。\n */\nexport function generateSSREntry(\n\tctx: AdapterContext,\n\topts: GenerateSSREntryOptions,\n): string {\n\tconst setupImport = ctx.setupPath\n\t\t? `import _setupDefault from \"./${ctx.setupPath}\";`\n\t\t: ``;\n\tconst setupCall = ctx.setupPath\n\t\t? `if (typeof _setupDefault === \"function\") await _setupDefault(app);`\n\t\t: ``;\n\n\tconst locales = JSON.stringify(ctx.locales);\n\tconst defaultLocale = JSON.stringify(ctx.defaultLocale);\n\tconst renderModes = JSON.stringify(ctx.renderModes ?? {});\n\n\t// 平台缓存实现:平台自定义 或 内置内存 Map\n\tconst cacheImpl = opts.platformCache\n\t\t? opts.platformCache\n\t\t: `\nconst ISR_CACHE_MAX = 1000;\nconst _isrMap = new Map();\nasync function platformCacheGet(url) {\n return _isrMap.get(url) ?? null;\n}\nasync function platformCacheSet(url, html) {\n if (_isrMap.size >= ISR_CACHE_MAX) {\n const first = _isrMap.keys().next().value;\n _isrMap.delete(first);\n }\n _isrMap.set(url, html);\n}`;\n\n\treturn `\nimport { Hono } from \"hono\";\n${opts.platformImport}\nimport { render, serializeServerData } from \"./${ctx.ssrEntry}\";\n${setupImport}\n\nconst TEMPLATE = ${JSON.stringify(ctx.templateHtml)};\nconst LOCALES = ${locales};\nconst DEFAULT_LOCALE = ${defaultLocale};\nconst RENDER_MODES = ${renderModes};\n${cacheImpl}\n\nfunction parseAcceptLanguage(header) {\n if (!header) return DEFAULT_LOCALE;\n const langs = header.split(\",\").map(p => {\n const [l, q] = p.trim().split(\";q=\");\n return { l: l.trim().toLowerCase(), q: q ? +q : 1 };\n }).sort((a, b) => b.q - a.q);\n for (const { l } of langs) {\n const prefix = l.split(\"-\")[0];\n if (LOCALES.includes(prefix)) return prefix;\n }\n return DEFAULT_LOCALE;\n}\n\nfunction injectSSR(t, locale, head, css, html, data) {\n return t\n .replace(\"<!--ssr-lang-->\", locale)\n .replace(\"<!--ssr-head-->\", head + \"\\\\n<style>\" + css + \"</style>\")\n .replace(\"<!--ssr-body-->\", html)\n .replace(\"<!--ssr-data-->\", '<script id=\"serialized-server-data\" type=\"application/json\">' + data + \"</script>\");\n}\n\nfunction injectCSRShell(t, locale) {\n return t\n .replace(\"<!--ssr-lang-->\", locale)\n .replace(\"<!--ssr-head-->\", \"\")\n .replace(\"<!--ssr-body-->\", \"\")\n .replace(\"<!--ssr-data-->\", \"\");\n}\n\nfunction matchRenderMode(url) {\n const path = url.split(\"?\")[0];\n if (RENDER_MODES[path]) return RENDER_MODES[path];\n for (const [pattern, mode] of Object.entries(RENDER_MODES)) {\n if (pattern.includes(\"*\")) {\n const re = new RegExp(\"^\" + pattern.replace(/\\\\*/g, \".*\") + \"$\");\n if (re.test(path)) return mode;\n }\n }\n return null;\n}\n\nconst app = new Hono();\n${setupCall}\n${opts.platformMiddleware ?? \"\"}\n\napp.get(\"*\", async (c) => {\n const url = c.req.path + (c.req.url.includes(\"?\") ? \"?\" + c.req.url.split(\"?\")[1] : \"\");\n try {\n const locale = parseAcceptLanguage(c.req.header(\"accept-language\"));\n\n // Vite 配置级别覆盖: CSR 直接返回空壳\n const overrideMode = matchRenderMode(url);\n if (overrideMode === \"csr\") {\n return c.html(injectCSRShell(TEMPLATE, locale));\n }\n\n // ISR 缓存命中\n const cached = await platformCacheGet(url);\n if (cached) return c.html(cached);\n\n const { html: appHtml, head, css, serverData, renderMode } = await render(url, locale);\n\n // 路由级 CSR\n if (renderMode === \"csr\") {\n return c.html(injectCSRShell(TEMPLATE, locale));\n }\n\n const serializedData = serializeServerData(serverData);\n const finalHtml = injectSSR(TEMPLATE, locale, head, css, appHtml, serializedData);\n\n // Prerender ISR 缓存(包括 Vite 配置覆盖和路由级)\n if (renderMode === \"prerender\" || overrideMode === \"prerender\") {\n await platformCacheSet(url, finalHtml);\n ${opts.platformPrerenderResponseHook ?? \"\"}\n }\n\n return c.html(finalHtml);\n } catch (e) {\n console.error(\"[SSR Error]\", e);\n return c.text(\"Internal Server Error\", 500);\n }\n});\n\n${opts.platformExport}\n`;\n}\n\n/** 用 Vite SSR 模式构建 bundle */\nexport async function buildBundle(\n\tctx: AdapterContext,\n\topts: BuildBundleOptions,\n): Promise<void> {\n\tawait ctx.vite.build({\n\t\troot: ctx.root,\n\t\tbuild: {\n\t\t\tssr: opts.entry,\n\t\t\toutDir: opts.outDir,\n\t\t\temptyOutDir: true,\n\t\t\ttarget: opts.target ?? \"node18\",\n\t\t\trollupOptions: {\n\t\t\t\toutput: { entryFileNames: opts.fileName ?? \"index.mjs\" },\n\t\t\t},\n\t\t},\n\t\tssr: {\n\t\t\tnoExternal: opts.noExternal !== false,\n\t\t\texternal: opts.external ?? BUILD_TOOL_EXTERNALS,\n\t\t},\n\t\tresolve: ctx.resolvedResolve,\n\t\tcss: ctx.resolvedCss,\n\t});\n}\n\n/** 复制 dist/client 静态资源到目标目录 */\nexport function copyStaticAssets(\n\tctx: AdapterContext,\n\tdestDir: string,\n\topts?: CopyStaticAssetsOptions,\n): void {\n\tconst { fs, path } = ctx;\n\tfs.cpSync(path.resolve(ctx.root, \"dist/client\"), destDir, {\n\t\trecursive: true,\n\t});\n\tif (opts?.excludeHtml !== false) {\n\t\tfs.rmSync(path.join(destDir, \"index.html\"), { force: true });\n\t}\n}\n\nexport interface PrerenderResult {\n\turl: string;\n\thtml: string;\n}\n\n/**\n * 构建时预渲染 prerender 路由。\n *\n * 1. 加载路由定义文件,找出 renderMode === \"prerender\" 的路由\n * 2. 合并 ctx.renderModes 配置覆盖\n * 3. 渲染每个 URL × locale\n *\n * @param routesExport 导出 routes 数组的文件路径(相对项目根),默认 \"src/lib/bootstrap.ts\"\n */\nexport async function prerenderRoutes(\n\tctx: AdapterContext,\n\troutesExport = \"src/lib/bootstrap.ts\",\n): Promise<PrerenderResult[]> {\n\tconst { fs, path, root, vite } = ctx;\n\tconst { pathToFileURL } = await import(/* @vite-ignore */ \"node:url\");\n\n\t// ── 1. 构建并加载路由定义 ──\n\tawait vite.build({\n\t\troot,\n\t\tbuild: {\n\t\t\tssr: routesExport,\n\t\t\toutDir: path.resolve(root, \"dist/server\"),\n\t\t\temptyOutDir: false,\n\t\t\trollupOptions: {\n\t\t\t\toutput: { entryFileNames: \"_routes_prerender.mjs\" },\n\t\t\t},\n\t\t},\n\t\tresolve: ctx.resolvedResolve,\n\t});\n\n\tconst routesPath = pathToFileURL(\n\t\tpath.resolve(root, \"dist/server/_routes_prerender.mjs\"),\n\t).href;\n\tconst routesMod = await import(/* @vite-ignore */ routesPath);\n\tconst routes: Array<{ path: string; renderMode?: string }> =\n\t\troutesMod.routes ?? routesMod.default ?? [];\n\n\t// 清理临时文件\n\tfs.rmSync(path.resolve(root, \"dist/server/_routes_prerender.mjs\"), {\n\t\tforce: true,\n\t});\n\n\t// ── 2. 收集 prerender 路径 ──\n\tconst prerenderPaths = new Set<string>();\n\n\t// 路由定义级别\n\tfor (const r of routes) {\n\t\tif (r.renderMode === \"prerender\" && r.path && !r.path.includes(\":\")) {\n\t\t\tprerenderPaths.add(r.path);\n\t\t}\n\t}\n\n\t// Vite 配置覆盖级别\n\tif (ctx.renderModes) {\n\t\tfor (const [pattern, mode] of Object.entries(ctx.renderModes)) {\n\t\t\tif (\n\t\t\t\tmode === \"prerender\" &&\n\t\t\t\t!pattern.includes(\"*\") &&\n\t\t\t\t!pattern.includes(\":\")\n\t\t\t) {\n\t\t\t\tprerenderPaths.add(pattern);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (prerenderPaths.size === 0) return [];\n\n\t// ── 3. 加载 SSR 模块 ──\n\tconst ssrPath = pathToFileURL(\n\t\tpath.resolve(root, \"dist/server/ssr.js\"),\n\t).href;\n\tconst ssrModule = await import(/* @vite-ignore */ ssrPath);\n\n\t// ── 4. 渲染每个 URL × locale ──\n\tconst results: PrerenderResult[] = [];\n\n\tfor (const routePath of prerenderPaths) {\n\t\tfor (const locale of ctx.locales) {\n\t\t\tconst url =\n\t\t\t\tlocale === ctx.defaultLocale\n\t\t\t\t\t? routePath\n\t\t\t\t\t: `/${locale}${routePath === \"/\" ? \"\" : routePath}`;\n\t\t\ttry {\n\t\t\t\tconst {\n\t\t\t\t\thtml: appHtml,\n\t\t\t\t\thead,\n\t\t\t\t\tcss,\n\t\t\t\t\tserverData,\n\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\tconst serializedData =\n\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\tconst finalHtml = ctx.templateHtml\n\t\t\t\t\t.replace(\"<!--ssr-lang-->\", locale)\n\t\t\t\t\t.replace(\n\t\t\t\t\t\t\"<!--ssr-head-->\",\n\t\t\t\t\t\thead + \"\\n<style>\" + css + \"</style>\",\n\t\t\t\t\t)\n\t\t\t\t\t.replace(\"<!--ssr-body-->\", appHtml)\n\t\t\t\t\t.replace(\n\t\t\t\t\t\t\"<!--ssr-data-->\",\n\t\t\t\t\t\t'<script id=\"serialized-server-data\" type=\"application/json\">' +\n\t\t\t\t\t\t\tserializedData +\n\t\t\t\t\t\t\t\"</script>\",\n\t\t\t\t\t);\n\n\t\t\t\tresults.push({ url, html: finalHtml });\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn(` [prerender] Failed to render ${url}:`, e);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (results.length > 0) {\n\t\tconsole.log(\n\t\t\t` Pre-rendered ${results.length} pages (${prerenderPaths.size} routes × ${ctx.locales.length} locales)\\n`,\n\t\t);\n\t}\n\n\treturn results;\n}\n","/**\n * Cloudflare Pages 适配器\n *\n * 生成 dist/cloudflare/ 目录:\n * - _worker.js — Workers 入口(Hono 原生支持 CF fetch 接口)\n * - assets/ — 静态资源\n *\n * 注意:Cloudflare Workers 不支持原生 Node.js API。\n * 若 setup 代理使用了 process.env,需在 wrangler.toml 启用 nodejs_compat。\n */\n\nimport {\n\tbuildBundle,\n\tcopyStaticAssets,\n\tgenerateSSREntry,\n\tprerenderRoutes,\n} from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function cloudflareAdapter(): Adapter {\n\treturn {\n\t\tname: \"cloudflare\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \"dist/cloudflare\");\n\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\n\t\t\t// Hono 原生支持 CF Workers 的 fetch 接口,直接 export default app\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: ``,\n\t\t\t\tplatformExport: `export default app;`,\n\t\t\t\t// Cloudflare Cache API — 持久化 ISR 缓存到 CDN 边缘节点\n\t\t\t\tplatformCache: `\nconst ISR_CACHE_TTL = 3600; // 1 hour\nasync function platformCacheGet(url) {\n try {\n const cache = caches.default;\n const cacheKey = new Request(\"https://isr-cache/\" + encodeURIComponent(url));\n const resp = await cache.match(cacheKey);\n if (resp) return await resp.text();\n } catch {}\n return null;\n}\nasync function platformCacheSet(url, html) {\n try {\n const cache = caches.default;\n const cacheKey = new Request(\"https://isr-cache/\" + encodeURIComponent(url));\n const resp = new Response(html, {\n headers: { \"Content-Type\": \"text/html; charset=utf-8\", \"Cache-Control\": \"public, max-age=\" + ISR_CACHE_TTL },\n });\n await cache.put(cacheKey, resp);\n } catch {}\n}`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".cf-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".cf-entry.tmp.mjs\",\n\t\t\t\t\toutDir: outputDir,\n\t\t\t\t\ttarget: \"es2022\",\n\t\t\t\t\tfileName: \"_worker.js\",\n\t\t\t\t\t// 使用默认 external(vite/esbuild/rollup/fsevents/lightningcss)\n\t\t\t\t\t// 这些构建工具运行时不需要,且 fsevents 是 macOS .node 原生二进制无法打包\n\t\t\t\t});\n\n\t\t\t\t// 静态资源\n\t\t\t\tcopyStaticAssets(ctx, path.resolve(outputDir, \"assets\"));\n\n\t\t\t\t// 构建时预渲染\n\t\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\t\tconst filePath =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? path.join(outputDir, \"assets\", \"index.html\")\n\t\t\t\t\t\t\t: path.join(outputDir, \"assets\", url, \"index.html\");\n\t\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), {\n\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t});\n\t\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\tconsole.log(\" Cloudflare output → dist/cloudflare/\\n\");\n\t\t},\n\t};\n}\n","/**\n * Netlify 适配器 — Netlify Functions v2\n *\n * 生成:\n * - .netlify/functions-internal/ssr/index.mjs — Serverless Function\n * - dist/client/_redirects — 路由重写规则\n */\n\nimport { buildBundle, generateSSREntry, prerenderRoutes } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function netlifyAdapter(): Adapter {\n\treturn {\n\t\tname: \"netlify\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst funcDir = path.resolve(\n\t\t\t\troot,\n\t\t\t\t\".netlify/functions-internal/ssr\",\n\t\t\t);\n\n\t\t\tfs.rmSync(path.resolve(root, \".netlify\"), {\n\t\t\t\trecursive: true,\n\t\t\t\tforce: true,\n\t\t\t});\n\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { handle } from \"hono/netlify\";`,\n\t\t\t\tplatformExport: `export default handle(app);\nexport const config = { path: \"/*\", preferStatic: true };`,\n\t\t\t\t// Netlify CDN 缓存 — 使用 Netlify-CDN-Cache-Control 头做 ISR\n\t\t\t\tplatformCache: `\nconst ISR_SWR_TTL = 3600;\nconst ISR_CACHE_MAX = 1000;\nconst _isrMap = new Map();\nasync function platformCacheGet(url) {\n return _isrMap.get(url) ?? null;\n}\nasync function platformCacheSet(url, html) {\n if (_isrMap.size >= ISR_CACHE_MAX) {\n const first = _isrMap.keys().next().value;\n _isrMap.delete(first);\n }\n _isrMap.set(url, html);\n}`,\n\t\t\t\tplatformPrerenderResponseHook: `c.header(\"Cache-Control\", \"public, max-age=0, must-revalidate\");\n c.header(\"Netlify-CDN-Cache-Control\", \"public, max-age=\" + ISR_SWR_TTL + \", stale-while-revalidate=\" + ISR_SWR_TTL + \", durable\");`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".netlify-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".netlify-entry.tmp.mjs\",\n\t\t\t\t\toutDir: funcDir,\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\t// _redirects — 静态文件优先,其余走 SSR function\n\t\t\tconst redirects = `/* /.netlify/functions/ssr 200\\n`;\n\t\t\tfs.writeFileSync(\n\t\t\t\tpath.resolve(root, \"dist/client/_redirects\"),\n\t\t\t\tredirects,\n\t\t\t);\n\n\t\t\t// 构建时预渲染\n\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\tconst clientDir = path.resolve(root, \"dist/client\");\n\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\tconst filePath =\n\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t? path.join(clientDir, \"index.html\")\n\t\t\t\t\t\t: path.join(clientDir, url, \"index.html\");\n\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), { recursive: true });\n\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t\" Netlify output → .netlify/functions-internal/ssr/\\n\" +\n\t\t\t\t\t\" Publish dir: dist/client/\\n\",\n\t\t\t);\n\t\t},\n\t};\n}\n","/**\n * Node 适配器 — 独立 HTTP 服务器\n *\n * 生成 dist/server/index.mjs,使用 @hono/node-server 监听端口。\n * 运行:node dist/server/index.mjs\n */\n\nimport { buildBundle, generateSSREntry, prerenderRoutes } from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function nodeAdapter(): Adapter {\n\treturn {\n\t\tname: \"node\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { serve } from \"@hono/node-server\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";`,\n\t\t\t\tplatformMiddleware: `\n// 预渲染文件中间件:检查 dist/prerender/ 下是否有对应的静态 HTML\nconst __entry_dirname = dirname(fileURLToPath(import.meta.url));\nconst prerenderDir = resolve(__entry_dirname, \"../prerender\");\n\napp.use(\"*\", async (c, next) => {\n const urlPath = c.req.path;\n const candidates = [\n resolve(prerenderDir, \".\" + urlPath, \"index.html\"),\n resolve(prerenderDir, \".\" + urlPath + \".html\"),\n ];\n if (urlPath === \"/\") candidates.unshift(resolve(prerenderDir, \"index.html\"));\n for (const f of candidates) {\n if (existsSync(f)) {\n const html = readFileSync(f, \"utf-8\");\n return c.html(html);\n }\n }\n await next();\n});\n`,\n\t\t\t\tplatformExport: `\nconst port = +(process.env.PORT || 3000);\nserve({ fetch: app.fetch, port }, (info) => {\n console.log(\\`Server running at http://localhost:\\${info.port}\\`);\n});\n`,\n\t\t\t});\n\n\t\t\tconst tempEntry = path.resolve(root, \".node-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".node-entry.tmp.mjs\",\n\t\t\t\t\toutDir: path.resolve(root, \"dist/server\"),\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\n\t\t\t// 构建时预渲染 prerender 路由\n\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\tif (prerendered.length > 0) {\n\t\t\t\tconst prerenderDir = path.resolve(root, \"dist/prerender\");\n\t\t\t\tfs.mkdirSync(prerenderDir, { recursive: true });\n\t\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\t\tconst filePath =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? path.join(prerenderDir, \"index.html\")\n\t\t\t\t\t\t\t: path.join(prerenderDir, url, \"index.html\");\n\t\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), {\n\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t});\n\t\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t\" Node output → dist/server/index.mjs\\n\" +\n\t\t\t\t\t\" Run: node dist/server/index.mjs\\n\",\n\t\t\t);\n\t\t},\n\t};\n}\n","/**\n * Static 适配器 — 构建时预渲染\n *\n * 加载 SSR 模块和路由定义,将无参数路由自动预渲染为静态 HTML。\n * 动态参数路由通过 dynamicRoutes 选项补充具体 URL。\n *\n * 输出:dist/static/ — 纯静态站点,可部署到任何静态托管。\n */\n\nimport type { Adapter, AdapterContext } from \"./types\";\n\nexport interface StaticAdapterOptions {\n\t/**\n\t * 导出 routes 数组的文件路径(相对于项目根目录)。\n\t * 默认 \"src/lib/bootstrap.ts\"。\n\t * 文件需 export 一个 RouteDefinition[] 类型的 routes 变量。\n\t */\n\troutesExport?: string;\n\t/**\n\t * 额外的动态路由 URL(带具体参数值),如:\n\t * [\"/product/123\", \"/list/games\"]\n\t */\n\tdynamicRoutes?: string[];\n}\n\nexport function staticAdapter(opts: StaticAdapterOptions = {}): Adapter {\n\treturn {\n\t\tname: \"static\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root, vite } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \"dist/static\");\n\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\t\t\tfs.mkdirSync(outputDir, { recursive: true });\n\n\t\t\t// 加载 SSR 模块\n\t\t\tconst { pathToFileURL } = await import(\n\t\t\t\t/* @vite-ignore */ \"node:url\"\n\t\t\t);\n\t\t\tconst ssrPath = pathToFileURL(\n\t\t\t\tpath.resolve(root, \"dist/server/ssr.js\"),\n\t\t\t).href;\n\t\t\tconst ssrModule = await import(/* @vite-ignore */ ssrPath);\n\n\t\t\t// 先复制静态资源(JS/CSS 等),排除模板 index.html\n\t\t\tctx.copyStaticAssets(outputDir, { excludeHtml: true });\n\n\t\t\t// 提取路由列表(含 renderMode)\n\t\t\tconst { paths: routePaths, defs: routeDefs } =\n\t\t\t\tawait extractRoutesWithModes(ctx, opts);\n\t\t\tconst allUrls: string[] = [];\n\n\t\t\t// 对每个路由 × 每个 locale 生成 URL\n\t\t\tfor (const routePath of routePaths) {\n\t\t\t\tfor (const locale of ctx.locales) {\n\t\t\t\t\tconst url =\n\t\t\t\t\t\tlocale === ctx.defaultLocale\n\t\t\t\t\t\t\t? routePath\n\t\t\t\t\t\t\t: `/${locale}${routePath === \"/\" ? \"\" : routePath}`;\n\t\t\t\t\tallUrls.push(url);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t` Pre-rendering ${allUrls.length} pages (${routePaths.length} routes × ${ctx.locales.length} locales)...\\n`,\n\t\t\t);\n\n\t\t\t// 预渲染每个 URL\n\t\t\tfor (const url of allUrls) {\n\t\t\t\ttry {\n\t\t\t\t\t// 从 URL 推断 locale\n\t\t\t\t\tconst locale = inferLocale(\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tctx.locales,\n\t\t\t\t\t\tctx.defaultLocale,\n\t\t\t\t\t);\n\n\t\t\t\t\t// 检查渲染模式:路由级 + Vite 配置覆盖\n\t\t\t\t\tconst routeDef = routeDefs.find(\n\t\t\t\t\t\t(r) => r.path === stripLocalePrefix(url, ctx.locales),\n\t\t\t\t\t);\n\t\t\t\t\tconst mode = resolveRenderMode(\n\t\t\t\t\t\tstripLocalePrefix(url, ctx.locales),\n\t\t\t\t\t\trouteDef?.renderMode,\n\t\t\t\t\t\tctx.renderModes,\n\t\t\t\t\t);\n\n\t\t\t\t\tlet finalHtml: string;\n\n\t\t\t\t\tif (mode === \"csr\") {\n\t\t\t\t\t\t// CSR: 空壳 HTML,客户端 JS 渲染\n\t\t\t\t\t\tfinalHtml = injectCSRShellForStatic(\n\t\t\t\t\t\t\tctx.templateHtml,\n\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\tserverData,\n\t\t\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\t\t\tconst serializedData =\n\t\t\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\t\t\tfinalHtml = injectSSRForStatic(\n\t\t\t\t\t\t\tctx.templateHtml,\n\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\tappHtml,\n\t\t\t\t\t\t\tserializedData,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// 写入文件:/foo → dist/static/foo/index.html\n\t\t\t\t\tconst filePath =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? path.join(outputDir, \"index.html\")\n\t\t\t\t\t\t\t: path.join(outputDir, url, \"index.html\");\n\n\t\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), {\n\t\t\t\t\t\trecursive: true,\n\t\t\t\t\t});\n\t\t\t\t\tfs.writeFileSync(filePath, finalHtml);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.warn(` [static] Failed to render ${url}:`, e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(` Static output → dist/static/\\n`);\n\t\t},\n\t};\n}\n\n/** 从路由文件提取无参数路由 + 合并 dynamicRoutes(含 renderMode) */\nasync function extractRoutesWithModes(\n\tctx: AdapterContext,\n\topts: StaticAdapterOptions,\n): Promise<{\n\tpaths: string[];\n\tdefs: Array<{ path: string; renderMode?: string }>;\n}> {\n\tconst routesFile = opts.routesExport ?? \"src/lib/bootstrap.ts\";\n\tconst paths: string[] = [];\n\tconst defs: Array<{ path: string; renderMode?: string }> = [];\n\n\ttry {\n\t\t// 使用 Vite SSR 构建加载路由文件\n\t\tconst { pathToFileURL } = await import(/* @vite-ignore */ \"node:url\");\n\n\t\t// 先构建路由文件\n\t\tawait ctx.vite.build({\n\t\t\troot: ctx.root,\n\t\t\tbuild: {\n\t\t\t\tssr: routesFile,\n\t\t\t\toutDir: ctx.path.resolve(ctx.root, \"dist/server\"),\n\t\t\t\temptyOutDir: false,\n\t\t\t\trollupOptions: {\n\t\t\t\t\toutput: { entryFileNames: \"_routes.mjs\" },\n\t\t\t\t},\n\t\t\t},\n\t\t\tresolve: ctx.resolvedResolve,\n\t\t});\n\n\t\tconst routesPath = pathToFileURL(\n\t\t\tctx.path.resolve(ctx.root, \"dist/server/_routes.mjs\"),\n\t\t).href;\n\t\tconst routesMod = await import(/* @vite-ignore */ routesPath);\n\n\t\t// 查找导出的 routes 数组\n\t\tconst routes: Array<{ path: string; renderMode?: string }> =\n\t\t\troutesMod.routes ?? routesMod.default;\n\n\t\tif (Array.isArray(routes)) {\n\t\t\tfor (const r of routes) {\n\t\t\t\tif (r.path && !r.path.includes(\":\")) {\n\t\t\t\t\tpaths.push(r.path);\n\t\t\t\t\tdefs.push({ path: r.path, renderMode: r.renderMode });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 清理临时文件\n\t\tctx.fs.rmSync(ctx.path.resolve(ctx.root, \"dist/server/_routes.mjs\"), {\n\t\t\tforce: true,\n\t\t});\n\t} catch (e) {\n\t\tconsole.warn(\n\t\t\t` [static] Could not load routes from \"${routesFile}\". Using \"/\" only.`,\n\t\t\te,\n\t\t);\n\t\tif (paths.length === 0) paths.push(\"/\");\n\t}\n\n\t// 合并 dynamicRoutes\n\tif (opts.dynamicRoutes) {\n\t\tfor (const r of opts.dynamicRoutes) {\n\t\t\tif (!paths.includes(r)) paths.push(r);\n\t\t}\n\t}\n\n\t// 至少包含根路径\n\tif (paths.length === 0) paths.push(\"/\");\n\n\treturn { paths, defs };\n}\n\n/** 从 URL 推断 locale */\nfunction inferLocale(\n\turl: string,\n\tlocales: string[],\n\tdefaultLocale: string,\n): string {\n\tconst segments = url.split(\"/\").filter(Boolean);\n\tif (segments.length > 0 && locales.includes(segments[0])) {\n\t\treturn segments[0];\n\t}\n\treturn defaultLocale;\n}\n\n/** 内联 SSR 注入(同 shared 中的逻辑) */\nfunction injectSSRForStatic(\n\ttemplate: string,\n\tlocale: string,\n\thead: string,\n\tcss: string,\n\thtml: string,\n\tserializedData: string,\n): string {\n\treturn template\n\t\t.replace(\"<!--ssr-lang-->\", locale)\n\t\t.replace(\"<!--ssr-head-->\", head + \"\\n<style>\" + css + \"</style>\")\n\t\t.replace(\"<!--ssr-body-->\", html)\n\t\t.replace(\n\t\t\t\"<!--ssr-data-->\",\n\t\t\t'<script id=\"serialized-server-data\" type=\"application/json\">' +\n\t\t\t\tserializedData +\n\t\t\t\t\"</script>\",\n\t\t);\n}\n\n/** CSR 空壳注入 */\nfunction injectCSRShellForStatic(template: string, locale: string): string {\n\treturn template\n\t\t.replace(\"<!--ssr-lang-->\", locale)\n\t\t.replace(\"<!--ssr-head-->\", \"\")\n\t\t.replace(\"<!--ssr-body-->\", \"\")\n\t\t.replace(\"<!--ssr-data-->\", \"\");\n}\n\n/** 从 URL 去除 locale 前缀,还原路由路径 */\nfunction stripLocalePrefix(url: string, locales: string[]): string {\n\tconst segments = url.split(\"/\").filter(Boolean);\n\tif (segments.length > 0 && locales.includes(segments[0])) {\n\t\tconst rest = segments.slice(1).join(\"/\");\n\t\treturn rest ? `/${rest}` : \"/\";\n\t}\n\treturn url;\n}\n\n/** 解析最终渲染模式:Vite 配置覆盖 > 路由级 > 默认 \"ssr\" */\nfunction resolveRenderMode(\n\troutePath: string,\n\trouteRenderMode?: string,\n\trenderModes?: Record<string, string>,\n): string {\n\t// Vite 配置覆盖优先\n\tif (renderModes) {\n\t\tif (renderModes[routePath]) return renderModes[routePath];\n\t\tfor (const [pattern, mode] of Object.entries(renderModes)) {\n\t\t\tif (pattern.includes(\"*\")) {\n\t\t\t\tconst re = new RegExp(\"^\" + pattern.replace(/\\*/g, \".*\") + \"$\");\n\t\t\t\tif (re.test(routePath)) return mode;\n\t\t\t}\n\t\t}\n\t}\n\treturn routeRenderMode ?? \"ssr\";\n}\n","/**\n * Vercel 适配器 — Build Output API v3\n *\n * 生成 .vercel/output/ 目录:\n * - config.json — 路由规则\n * - static/ — 静态资源\n * - functions/ssr.func/ — Serverless Function\n */\n\nimport {\n\tbuildBundle,\n\tcopyStaticAssets,\n\tgenerateSSREntry,\n\tprerenderRoutes,\n} from \"./shared\";\nimport type { Adapter } from \"./types\";\n\nexport function vercelAdapter(): Adapter {\n\treturn {\n\t\tname: \"vercel\",\n\t\tasync build(ctx) {\n\t\t\tconst { fs, path, root } = ctx;\n\t\t\tconst outputDir = path.resolve(root, \".vercel/output\");\n\n\t\t\t// 清理旧输出\n\t\t\tfs.rmSync(outputDir, { recursive: true, force: true });\n\n\t\t\t// 生成入口源码\n\t\t\t// Vercel Serverless (launcherType: \"Nodejs\") 传入 Node.js IncomingMessage,\n\t\t\t// 必须用 @hono/node-server 转换为 Web Request,而非 hono/vercel 的 handle。\n\t\t\tconst entrySource = generateSSREntry(ctx, {\n\t\t\t\tplatformImport: `import { getRequestListener } from \"@hono/node-server\";`,\n\t\t\t\tplatformExport: `export default getRequestListener(app.fetch);`,\n\t\t\t});\n\n\t\t\t// 写入临时入口文件\n\t\t\tconst tempEntry = path.resolve(root, \".vercel-entry.tmp.mjs\");\n\t\t\tfs.writeFileSync(tempEntry, entrySource);\n\n\t\t\ttry {\n\t\t\t\tconst funcDir = path.resolve(\n\t\t\t\t\troot,\n\t\t\t\t\t\".vercel/output/functions/ssr.func\",\n\t\t\t\t);\n\n\t\t\t\t// 构建 serverless function\n\t\t\t\tawait buildBundle(ctx, {\n\t\t\t\t\tentry: \".vercel-entry.tmp.mjs\",\n\t\t\t\t\toutDir: funcDir,\n\t\t\t\t\ttarget: \"node18\",\n\t\t\t\t});\n\n\t\t\t\t// .vc-config.json\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tpath.resolve(funcDir, \".vc-config.json\"),\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\truntime: \"nodejs20.x\",\n\t\t\t\t\t\t\thandler: \"index.mjs\",\n\t\t\t\t\t\t\tlauncherType: \"Nodejs\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t2,\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\t// 静态资源\n\t\t\t\tcopyStaticAssets(\n\t\t\t\t\tctx,\n\t\t\t\t\tpath.resolve(root, \".vercel/output/static\"),\n\t\t\t\t);\n\n\t\t\t\t// 路由配置\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\tpath.resolve(root, \".vercel/output/config.json\"),\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tversion: 3,\n\t\t\t\t\t\t\troutes: [\n\t\t\t\t\t\t\t\t{ handle: \"filesystem\" },\n\t\t\t\t\t\t\t\t{ src: \"/(.*)\", dest: \"/ssr/$1\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t2,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tfs.rmSync(tempEntry, { force: true });\n\t\t\t}\n\t\t\t// 构建时预渲染 prerender 路由\n\t\t\tconst prerendered = await prerenderRoutes(ctx);\n\t\t\tconst staticDir = path.resolve(root, \".vercel/output/static\");\n\t\t\tfor (const { url, html } of prerendered) {\n\t\t\t\tconst filePath =\n\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t? path.join(staticDir, \"index.html\")\n\t\t\t\t\t\t: path.join(staticDir, url, \"index.html\");\n\t\t\t\tfs.mkdirSync(path.resolve(filePath, \"..\"), { recursive: true });\n\t\t\t\tfs.writeFileSync(filePath, html);\n\t\t\t}\n\n\t\t\t// 为预渲染路由写入 Vercel ISR 配置(overrides)\n\t\t\t// Vercel 会在 initialRevalidateSeconds 后重新执行函数并更新静态缓存\n\t\t\tif (prerendered.length > 0) {\n\t\t\t\tconst configPath = path.resolve(\n\t\t\t\t\troot,\n\t\t\t\t\t\".vercel/output/config.json\",\n\t\t\t\t);\n\t\t\t\tconst config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n\t\t\t\tconfig.overrides = config.overrides ?? {};\n\t\t\t\tfor (const { url } of prerendered) {\n\t\t\t\t\tconst key =\n\t\t\t\t\t\turl === \"/\"\n\t\t\t\t\t\t\t? \"index.html\"\n\t\t\t\t\t\t\t: `${url.replace(/^\\//, \"\")}/index.html`;\n\t\t\t\t\tconfig.overrides[key] = {\n\t\t\t\t\t\tpath: url === \"/\" ? \"/\" : url,\n\t\t\t\t\t\tcontentType: \"text/html; charset=utf-8\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// 添加 ISR 路由:预渲染路径回退到 SSR 函数进行重新验证\n\t\t\t\tconst isrRoutes = prerendered.map(({ url }) => ({\n\t\t\t\t\tsrc: `^${url.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}/?$`,\n\t\t\t\t\tdest: url,\n\t\t\t\t\thas: [{ type: \"header\", key: \"x-vercel-isr\" }],\n\t\t\t\t}));\n\t\t\t\tconfig.routes = [\n\t\t\t\t\t...isrRoutes,\n\t\t\t\t\t{ handle: \"filesystem\" },\n\t\t\t\t\t{ src: \"/(.*)\", dest: \"/ssr/$1\" },\n\t\t\t\t];\n\t\t\t\tfs.writeFileSync(configPath, JSON.stringify(config, null, 2));\n\t\t\t}\n\n\t\t\tconsole.log(\" Vercel output → .vercel/output/\\n\");\n\t\t},\n\t};\n}\n","/**\n * resolveAdapter — 字符串 → Adapter 映射\n */\n\nimport { autoAdapter } from \"./auto\";\nimport { cloudflareAdapter } from \"./cloudflare\";\nimport { netlifyAdapter } from \"./netlify\";\nimport { nodeAdapter } from \"./node\";\nimport { staticAdapter } from \"./static\";\nimport type { Adapter } from \"./types\";\nimport { vercelAdapter } from \"./vercel\";\n\nexport function resolveAdapter(value: string | Adapter): Adapter {\n\tif (typeof value !== \"string\") return value;\n\n\tswitch (value) {\n\t\tcase \"vercel\":\n\t\t\treturn vercelAdapter();\n\t\tcase \"cloudflare\":\n\t\t\treturn cloudflareAdapter();\n\t\tcase \"netlify\":\n\t\t\treturn netlifyAdapter();\n\t\tcase \"node\":\n\t\t\treturn nodeAdapter();\n\t\tcase \"static\":\n\t\t\treturn staticAdapter();\n\t\tcase \"auto\":\n\t\t\treturn autoAdapter();\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t`[finesoft] Unknown adapter: \"${value}\". ` +\n\t\t\t\t\t`Available: vercel, cloudflare, netlify, node, static, auto`,\n\t\t\t);\n\t}\n}\n","/**\n * Auto 适配器 — 根据环境变量自动选择目标平台\n *\n * 检测顺序:\n * VERCEL → vercel\n * CF_PAGES → cloudflare\n * NETLIFY → netlify\n * (default) → node\n */\n\nimport { resolveAdapter } from \"./resolve\";\nimport type { Adapter } from \"./types\";\n\nexport function autoAdapter(): Adapter {\n\treturn {\n\t\tname: \"auto\",\n\t\tasync build(ctx) {\n\t\t\tconst detected = detectPlatform();\n\t\t\tconsole.log(` [auto] Detected platform: ${detected}\\n`);\n\t\t\tconst adapter = resolveAdapter(detected);\n\t\t\treturn adapter.build(ctx);\n\t\t},\n\t};\n}\n\nfunction detectPlatform(): string {\n\tif (process.env.VERCEL) return \"vercel\";\n\tif (process.env.CF_PAGES) return \"cloudflare\";\n\tif (process.env.NETLIFY) return \"netlify\";\n\treturn \"node\";\n}\n","/**\n * createServer — 一站式服务器工厂\n *\n * 封装 env 加载、运行时检测、Vite 创建、Hono app、SSR、启动。\n * 保留 setup() 钩子用于注册业务路由。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { createSSRApp, type SSRAppOptions } from \"./app\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\nimport { startServer } from \"./start\";\n\nexport interface ServerConfig {\n\t/** 项目根路径(默认 process.cwd()) */\n\troot?: string;\n\t/** 支持的语言列表 */\n\tlocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/** 端口号(默认 3000) */\n\tport?: number;\n\t/** 注册业务路由(在 SSR catch-all 之前调用) */\n\tsetup?: (app: Hono) => void | Promise<void>;\n\t/** SSR 相关选项(透传给 createSSRApp) */\n\tssr?: Pick<SSRAppOptions, \"ssrEntryPath\" | \"ssrProductionModule\">;\n}\n\nexport interface ServerInstance {\n\tapp: Hono;\n\tvite?: ViteDevServer;\n\truntime: RuntimeInfo;\n}\n\n/**\n * 创建并启动 SSR 服务器\n *\n * @example\n * ```ts\n * const { app } = await createServer({\n * locales: [\"zh\", \"en\"],\n * setup: (app) => registerProxies(app),\n * });\n * export { app };\n * ```\n */\nexport async function createServer(\n\tconfig: ServerConfig = {},\n): Promise<ServerInstance> {\n\tconst {\n\t\troot: rootOverride,\n\t\tlocales,\n\t\tdefaultLocale,\n\t\tport = Number(process.env.PORT) || 3000,\n\t\tsetup,\n\t\tssr,\n\t} = config;\n\n\t// 1. 路径 + .env\n\tconst root = rootOverride ?? process.cwd();\n\tconst { existsSync } = await import(/* @vite-ignore */ \"node:fs\");\n\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\tconst envPath = resolve(root, \".env\");\n\tif (existsSync(envPath)) {\n\t\ttry {\n\t\t\tconst { config: dotenvConfig } = await import(\n\t\t\t\t/* @vite-ignore */ \"dotenv\"\n\t\t\t);\n\t\t\tdotenvConfig({ path: envPath });\n\t\t} catch {\n\t\t\t// dotenv 未安装则跳过,调用方可自行加载 .env\n\t\t}\n\t}\n\n\t// 2. 运行时检测\n\tconst runtime = detectRuntime();\n\n\t// 3. Vite(仅开发模式)\n\tlet vite: ViteDevServer | undefined;\n\tif (!runtime.isProduction && !runtime.isVercel) {\n\t\tconst { createServer: createViteServer } = await import(\n\t\t\t/* @vite-ignore */ \"vite\"\n\t\t);\n\t\tvite = await createViteServer({\n\t\t\troot,\n\t\t\tserver: { middlewareMode: true },\n\t\t\tappType: \"custom\",\n\t\t});\n\t}\n\n\t// 4. Hono app + 业务路由\n\tconst app = new Hono();\n\tif (setup) {\n\t\tawait setup(app);\n\t}\n\n\t// 5. SSR catch-all\n\tconst ssrApp = createSSRApp({\n\t\troot,\n\t\tvite,\n\t\tisProduction: runtime.isProduction,\n\t\tsupportedLocales: locales,\n\t\tdefaultLocale,\n\t\t...ssr,\n\t});\n\tapp.route(\"/\", ssrApp);\n\n\t// 6. 启动\n\tawait startServer({\n\t\tapp,\n\t\troot,\n\t\tport,\n\t\tisProduction: runtime.isProduction,\n\t\tvite,\n\t\truntime,\n\t\tlocales,\n\t\tssrEntryPath: ssr?.ssrEntryPath,\n\t});\n\n\treturn { app, vite, runtime };\n}\n","/**\n * runtime — 运行时检测 + 项目根路径推导\n */\n\nexport interface RuntimeInfo {\n\tisDeno: boolean;\n\tisBun: boolean;\n\tisVercel: boolean;\n\tisProduction: boolean;\n}\n\n/** 检测当前运行时环境 */\nexport function detectRuntime(): RuntimeInfo {\n\treturn {\n\t\tisDeno: typeof (globalThis as any).Deno !== \"undefined\",\n\t\tisBun: typeof (globalThis as any).Bun !== \"undefined\",\n\t\tisVercel: !!process.env.VERCEL,\n\t\tisProduction: process.env.NODE_ENV === \"production\",\n\t};\n}\n\n/**\n * 从 `import.meta.url` 推导项目根路径\n *\n * @param importMetaUrl - 调用方的 `import.meta.url`\n * @param levelsUp - 向上移动多少级(默认 0,即调用方所在目录就是项目根)\n */\nexport async function resolveRoot(\n\timportMetaUrl: string,\n\tlevelsUp = 0,\n): Promise<string> {\n\tconst isDeno = typeof (globalThis as any).Deno !== \"undefined\";\n\n\tif (isDeno) {\n\t\tlet url = new URL(importMetaUrl);\n\t\tfor (let i = 0; i < levelsUp; i++) {\n\t\t\turl = new URL(\"..\", url);\n\t\t}\n\t\treturn url.pathname;\n\t}\n\n\tconst { dirname, resolve, normalize } = await import(\n\t\t/* @vite-ignore */ \"node:path\"\n\t);\n\tconst { fileURLToPath } = await import(/* @vite-ignore */ \"node:url\");\n\tlet dir = normalize(dirname(fileURLToPath(importMetaUrl)));\n\tfor (let i = 0; i < levelsUp; i++) {\n\t\tdir = resolve(dir, \"..\");\n\t}\n\treturn dir;\n}\n","/**\n * startServer — 多运行时自动启动\n *\n * 支持 Node.js (dev HMR + prod)、Deno、Bun、Vercel。\n */\n\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { detectRuntime, type RuntimeInfo } from \"./runtime\";\n\nexport interface StartServerOptions {\n\t/** 最终的 Hono app(已包含 SSR + 自定义路由) */\n\tapp: Hono;\n\t/** 项目根路径 */\n\troot: string;\n\t/** 端口号 */\n\tport?: number;\n\t/** 是否生产环境 */\n\tisProduction: boolean;\n\t/** Vite dev server(仅开发模式传入) */\n\tvite?: ViteDevServer;\n\t/** 运行时信息(可选,不传时自动检测) */\n\truntime?: RuntimeInfo;\n\t/** 已注册的路由列表(用于启动日志) */\n\troutes?: string[];\n\t/** 支持的语言列表(用于启动日志) */\n\tlocales?: string[];\n\t/** SSR 入口路径(用于启动日志) */\n\tssrEntryPath?: string;\n}\n\nexport async function startServer(\n\toptions: StartServerOptions,\n): Promise<{ vite?: ViteDevServer }> {\n\tconst {\n\t\tapp,\n\t\troot,\n\t\tport = 3000,\n\t\tisProduction,\n\t\tvite,\n\t\troutes,\n\t\tlocales,\n\t\tssrEntryPath,\n\t} = options;\n\n\tconst { isDeno, isBun, isVercel } = options.runtime ?? detectRuntime();\n\n\tfunction printStartupBanner() {\n\t\tconst lines: string[] = [\n\t\t\t`\\n Server running at http://localhost:${port}\\n`,\n\t\t];\n\t\tif (routes && routes.length > 0) {\n\t\t\tlines.push(\" Routes:\");\n\t\t\tfor (const r of routes) {\n\t\t\t\tlines.push(` ${r}`);\n\t\t\t}\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tif (locales && locales.length > 0) {\n\t\t\tlines.push(` Locales: ${locales.join(\", \")}`);\n\t\t}\n\t\tif (ssrEntryPath) {\n\t\t\tlines.push(` SSR Entry: ${ssrEntryPath}`);\n\t\t}\n\t\tif (locales?.length || ssrEntryPath) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tconsole.log(lines.join(\"\\n\"));\n\t}\n\n\tif (isVercel) {\n\t\treturn { vite };\n\t}\n\n\tif (!isProduction) {\n\t\tlet devVite = vite;\n\t\tif (!devVite) {\n\t\t\tconst { createServer: createViteServer } = await import(\n\t\t\t\t/* @vite-ignore */ \"vite\"\n\t\t\t);\n\t\t\tdevVite = await createViteServer({\n\t\t\t\troot,\n\t\t\t\tserver: { middlewareMode: true },\n\t\t\t\tappType: \"custom\",\n\t\t\t});\n\t\t}\n\n\t\tconst { getRequestListener } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t);\n\t\tconst { createServer } = await import(/* @vite-ignore */ \"node:http\");\n\t\tconst listener = getRequestListener(app.fetch);\n\t\tconst server = createServer((req: any, res: any) => {\n\t\t\tdevVite!.middlewares(req, res, () => listener(req, res));\n\t\t});\n\t\tserver.listen(port, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t\treturn { vite: devVite };\n\t}\n\n\tif (isDeno) {\n\t\t(globalThis as any).Deno.serve({ port }, app.fetch);\n\t} else if (isBun) {\n\t\t// Bun uses export default\n\t} else {\n\t\t// Node.js production\n\t\tconst { serveStatic } = await import(\n\t\t\t/* @vite-ignore */ \"@hono/node-server/serve-static\"\n\t\t);\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\tconst prodApp = new Hono();\n\t\tconst clientDir = resolve(root, \"dist/client\");\n\t\tprodApp.use(\n\t\t\t\"/*\",\n\t\t\tserveStatic({\n\t\t\t\troot: clientDir,\n\t\t\t\t// 禁止目录路径自动提供 index.html,让其 fall through 到 SSR\n\t\t\t\trewriteRequestPath: (path: string) =>\n\t\t\t\t\tpath.endsWith(\"/\") ? \"/__nosuchfile__\" : path,\n\t\t\t}),\n\t\t);\n\t\tprodApp.route(\"/\", app);\n\n\t\tconst { serve } = await import(/* @vite-ignore */ \"@hono/node-server\");\n\t\tserve({ fetch: prodApp.fetch, port }, () => {\n\t\t\tprintStartupBanner();\n\t\t});\n\t}\n\n\treturn { vite };\n}\n","/**\n * finesoftFrontViteConfig — Vite 插件\n *\n * 将 Hono SSR 服务器集成到 Vite 的 dev / build / preview 生命周期中,\n * 使 template-project 只需 `vite` / `vite build` / `vite preview` 即可运行。\n *\n * 支持多平台 adapter: \"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | \"static\" | \"auto\"\n * 或自定义 Adapter 对象。\n */\n\nimport type { Hono } from \"hono\";\nimport { resolveAdapter } from \"./adapters/resolve\";\nimport {\n\tbuildBundle,\n\tcopyStaticAssets,\n\tgenerateSSREntry,\n} from \"./adapters/shared\";\nimport type { Adapter } from \"./adapters/types\";\nimport type { SSRModule } from \"./app\";\n\nexport interface FinesoftFrontViteOptions {\n\t/** 支持的语言列表 */\n\tlocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n\t/** SSR 配置 */\n\tssr?: {\n\t\t/** SSR 入口文件路径(默认 \"src/ssr.ts\") */\n\t\tentry?: string;\n\t};\n\t/**\n\t * 注册业务路由(API 代理等)。\n\t * - 传入 Function:仅 dev/preview 时可用。\n\t * - 传入 string(文件路径):dev/preview/adapter 均可用,\n\t * 文件需 export default 一个 (app: Hono) => void 函数。\n\t */\n\tsetup?: ((app: Hono) => void | Promise<void>) | string;\n\t/**\n\t * 部署适配器。\n\t * - 字符串快捷方式:\"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | \"static\" | \"auto\"\n\t * - 自定义 Adapter 对象:{ name, build(ctx) }\n\t * - 不设置则不生成部署产物\n\t */\n\tadapter?: string | Adapter;\n\t/**\n\t * 按路由覆盖渲染模式(优先级高于 RouteDefinition.renderMode)。\n\t * key: 精确路径或 glob 模式,如 \"/search\" 或 \"/blog/*\"\n\t * value: \"ssr\" | \"csr\" | \"prerender\"\n\t *\n\t * @example\n\t * ```ts\n\t * renderModes: {\n\t * \"/search\": \"csr\",\n\t * \"/blog/*\": \"prerender\",\n\t * }\n\t * ```\n\t */\n\trenderModes?: Record<string, \"ssr\" | \"csr\" | \"prerender\">;\n}\n\n/**\n * 从 setup 模块中查找 setup 函数:优先 default,其次 setup 命名导出。\n */\nfunction resolveSetupFn(\n\tmod: Record<string, unknown>,\n): ((app: any) => void | Promise<void>) | null {\n\tif (typeof mod.default === \"function\") return mod.default as any;\n\tif (typeof mod.setup === \"function\") return mod.setup as any;\n\tconst first = Object.values(mod).find((v) => typeof v === \"function\");\n\treturn (first as any) ?? null;\n}\n\n/**\n * 匹配 Vite 配置级别的 renderMode 覆盖。\n * 精确路径优先,然后 glob 模式。\n */\nfunction matchRenderModeConfig(\n\turl: string,\n\trenderModes?: Record<string, string>,\n): string | null {\n\tif (!renderModes) return null;\n\tconst path = url.split(\"?\")[0];\n\tif (renderModes[path]) return renderModes[path];\n\tfor (const [pattern, mode] of Object.entries(renderModes)) {\n\t\tif (pattern.includes(\"*\")) {\n\t\t\tconst re = new RegExp(\"^\" + pattern.replace(/\\*/g, \".*\") + \"$\");\n\t\t\tif (re.test(path)) return mode;\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function finesoftFrontViteConfig(\n\toptions: FinesoftFrontViteOptions = {},\n) {\n\tconst ssrEntry = options.ssr?.entry ?? \"src/ssr.ts\";\n\tlet root = process.cwd();\n\tlet resolvedCommand: string | undefined;\n\tlet resolvedResolve: unknown;\n\tlet resolvedCss: unknown;\n\n\treturn {\n\t\tname: \"finesoft-front\",\n\n\t\tconfig(userConfig: Record<string, any>, env: { command: string }) {\n\t\t\tconst overrides: Record<string, any> = {\n\t\t\t\tappType: \"custom\",\n\t\t\t};\n\t\t\tif (\n\t\t\t\tenv.command === \"build\" &&\n\t\t\t\t!process.env.__FINESOFT_SUB_BUILD__\n\t\t\t) {\n\t\t\t\toverrides.build = {\n\t\t\t\t\toutDir: userConfig.build?.outDir ?? \"dist/client\",\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn overrides;\n\t\t},\n\n\t\tconfigResolved(config: Record<string, any>) {\n\t\t\tresolvedCommand = config.command as string;\n\t\t\tresolvedResolve = config.resolve;\n\t\t\tresolvedCss = config.css;\n\t\t\troot = config.root as string;\n\t\t},\n\n\t\t// ─── Dev ───────────────────────────────────────────────\n\t\tconfigureServer(server: any) {\n\t\t\treturn async () => {\n\t\t\t\tconst { Hono: HonoClass } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"hono\"\n\t\t\t\t);\n\t\t\t\tconst { createSSRApp } = await import(\"./app\");\n\t\t\t\tconst { getRequestListener } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t\t\t);\n\n\t\t\t\tconst app = new HonoClass();\n\n\t\t\t\t// Setup: 函数直接调用,文件路径通过 ssrLoadModule 加载\n\t\t\t\tif (typeof options.setup === \"function\") {\n\t\t\t\t\tawait options.setup(app);\n\t\t\t\t} else if (typeof options.setup === \"string\") {\n\t\t\t\t\tconst mod = await server.ssrLoadModule(\"/\" + options.setup);\n\t\t\t\t\tconst fn = resolveSetupFn(mod);\n\t\t\t\t\tif (fn) await fn(app);\n\t\t\t\t}\n\n\t\t\t\tconst ssrApp = createSSRApp({\n\t\t\t\t\troot,\n\t\t\t\t\tvite: server,\n\t\t\t\t\tisProduction: false,\n\t\t\t\t\tssrEntryPath: \"/\" + ssrEntry,\n\t\t\t\t\tsupportedLocales: options.locales,\n\t\t\t\t\tdefaultLocale: options.defaultLocale,\n\t\t\t\t});\n\t\t\t\tapp.route(\"/\", ssrApp);\n\n\t\t\t\tconst listener = getRequestListener(app.fetch);\n\n\t\t\t\tserver.middlewares.use((req: any, res: any) => {\n\t\t\t\t\tlistener(req, res);\n\t\t\t\t});\n\t\t\t};\n\t\t},\n\n\t\t// ─── Preview ───────────────────────────────────────────\n\t\tconfigurePreviewServer(server: any) {\n\t\t\treturn async () => {\n\t\t\t\tconst { readFileSync } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:fs\"\n\t\t\t\t);\n\t\t\t\tconst { resolve } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:path\"\n\t\t\t\t);\n\t\t\t\tconst { pathToFileURL } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"node:url\"\n\t\t\t\t);\n\t\t\t\tconst { Hono: HonoClass } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"hono\"\n\t\t\t\t);\n\t\t\t\tconst { injectSSRContent, injectCSRShell } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@finesoft/ssr\"\n\t\t\t\t);\n\t\t\t\tconst { parseAcceptLanguage } = await import(\"./locale\");\n\t\t\t\tconst { getRequestListener } = await import(\n\t\t\t\t\t/* @vite-ignore */ \"@hono/node-server\"\n\t\t\t\t);\n\n\t\t\t\tconst app = new HonoClass();\n\n\t\t\t\t// ISR 内存缓存\n\t\t\t\tconst isrCache = new Map<string, string>();\n\n\t\t\t\t// Setup: 函数直接调用,文件路径从构建产物加载\n\t\t\t\tif (typeof options.setup === \"function\") {\n\t\t\t\t\tawait options.setup(app);\n\t\t\t\t} else if (typeof options.setup === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst setupPath = pathToFileURL(\n\t\t\t\t\t\t\tresolve(root, \"dist/server/setup.mjs\"),\n\t\t\t\t\t\t).href;\n\t\t\t\t\t\tconst mod = await import(/* @vite-ignore */ setupPath);\n\t\t\t\t\t\tconst fn = resolveSetupFn(\n\t\t\t\t\t\t\tmod as Record<string, unknown>,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (fn) await fn(app);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\"[finesoft] Could not load setup module for preview. API routes disabled.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst templatePath = resolve(root, \"dist/client/index.html\");\n\t\t\t\tconst template = readFileSync(templatePath, \"utf-8\");\n\n\t\t\t\tconst ssrPath = pathToFileURL(\n\t\t\t\t\tresolve(root, \"dist/server/ssr.js\"),\n\t\t\t\t).href;\n\t\t\t\tconst ssrModule = (await import(\n\t\t\t\t\t/* @vite-ignore */ ssrPath\n\t\t\t\t)) as SSRModule;\n\n\t\t\t\tapp.get(\"*\", async (c: any) => {\n\t\t\t\t\tconst url =\n\t\t\t\t\t\tc.req.path +\n\t\t\t\t\t\t(c.req.url.includes(\"?\")\n\t\t\t\t\t\t\t? \"?\" + c.req.url.split(\"?\")[1]\n\t\t\t\t\t\t\t: \"\");\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst locale = parseAcceptLanguage(\n\t\t\t\t\t\t\tc.req.header(\"accept-language\"),\n\t\t\t\t\t\t\toptions.locales,\n\t\t\t\t\t\t\toptions.defaultLocale,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Vite 配置级别覆盖\n\t\t\t\t\t\tconst overrideMode = matchRenderModeConfig(\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\toptions.renderModes,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (overrideMode === \"csr\") {\n\t\t\t\t\t\t\treturn c.html(injectCSRShell(template, locale));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// ISR 缓存命中\n\t\t\t\t\t\tconst cached = isrCache.get(url);\n\t\t\t\t\t\tif (cached) return c.html(cached);\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\tserverData,\n\t\t\t\t\t\t\trenderMode,\n\t\t\t\t\t\t} = await ssrModule.render(url, locale);\n\n\t\t\t\t\t\t// 路由级 CSR\n\t\t\t\t\t\tif (renderMode === \"csr\") {\n\t\t\t\t\t\t\treturn c.html(injectCSRShell(template, locale));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst serializedData =\n\t\t\t\t\t\t\tssrModule.serializeServerData(serverData);\n\n\t\t\t\t\t\tconst finalHtml = injectSSRContent({\n\t\t\t\t\t\t\ttemplate,\n\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t\thead,\n\t\t\t\t\t\t\tcss,\n\t\t\t\t\t\t\thtml: appHtml,\n\t\t\t\t\t\t\tserializedData,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Prerender ISR 缓存\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\trenderMode === \"prerender\" ||\n\t\t\t\t\t\t\toverrideMode === \"prerender\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisrCache.set(url, finalHtml);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn c.html(finalHtml);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.error(\"[SSR Preview Error]\", e);\n\t\t\t\t\t\treturn c.text(\"Internal Server Error\", 500);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst listener = getRequestListener(app.fetch);\n\n\t\t\t\tserver.middlewares.use((req: any, res: any) => {\n\t\t\t\t\tlistener(req, res);\n\t\t\t\t});\n\t\t\t};\n\t\t},\n\n\t\t// ─── Build ─────────────────────────────────────────────\n\t\tasync closeBundle() {\n\t\t\tif (process.env.__FINESOFT_SUB_BUILD__) return;\n\t\t\tif (resolvedCommand !== \"build\") return;\n\n\t\t\tprocess.env.__FINESOFT_SUB_BUILD__ = \"1\";\n\t\t\ttry {\n\t\t\t\tconst vite: any = await import(/* @vite-ignore */ \"vite\");\n\t\t\t\tconst fs = await import(/* @vite-ignore */ \"node:fs\");\n\t\t\t\tconst path = await import(/* @vite-ignore */ \"node:path\");\n\n\t\t\t\t// ── 1. SSR 构建 ──\n\t\t\t\tconsole.log(\"\\n Building SSR bundle...\\n\");\n\t\t\t\tawait vite.build({\n\t\t\t\t\troot,\n\t\t\t\t\tbuild: {\n\t\t\t\t\t\tssr: ssrEntry,\n\t\t\t\t\t\toutDir: \"dist/server\",\n\t\t\t\t\t},\n\t\t\t\t\tresolve: resolvedResolve,\n\t\t\t\t\tcss: resolvedCss,\n\t\t\t\t});\n\n\t\t\t\t// ── 2. Setup 模块构建(仅当 setup 是文件路径时) ──\n\t\t\t\tif (typeof options.setup === \"string\") {\n\t\t\t\t\tconsole.log(\" Building setup module...\\n\");\n\t\t\t\t\tawait vite.build({\n\t\t\t\t\t\troot,\n\t\t\t\t\t\tbuild: {\n\t\t\t\t\t\t\tssr: options.setup,\n\t\t\t\t\t\t\toutDir: \"dist/server\",\n\t\t\t\t\t\t\temptyOutDir: false,\n\t\t\t\t\t\t\trollupOptions: {\n\t\t\t\t\t\t\t\toutput: { entryFileNames: \"setup.mjs\" },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresolve: resolvedResolve,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// ── 3. Adapter 构建 ──\n\t\t\t\tif (options.adapter) {\n\t\t\t\t\tconst adapter = resolveAdapter(options.adapter);\n\n\t\t\t\t\tconst locales = options.locales ?? [\"zh\", \"en\"];\n\t\t\t\t\tconst defaultLocale =\n\t\t\t\t\t\toptions.defaultLocale ?? locales[0] ?? \"en\";\n\t\t\t\t\tconst templateHtml = fs.readFileSync(\n\t\t\t\t\t\tpath.resolve(root, \"dist/client/index.html\"),\n\t\t\t\t\t\t\"utf-8\",\n\t\t\t\t\t);\n\n\t\t\t\t\tconst ctx = {\n\t\t\t\t\t\troot,\n\t\t\t\t\t\tssrEntry,\n\t\t\t\t\t\tsetupPath:\n\t\t\t\t\t\t\ttypeof options.setup === \"string\"\n\t\t\t\t\t\t\t\t? options.setup\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tlocales,\n\t\t\t\t\t\tdefaultLocale,\n\t\t\t\t\t\ttemplateHtml,\n\t\t\t\t\t\trenderModes: options.renderModes,\n\t\t\t\t\t\tresolvedResolve,\n\t\t\t\t\t\tresolvedCss,\n\t\t\t\t\t\tvite,\n\t\t\t\t\t\tfs,\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tgenerateSSREntry(opts: any) {\n\t\t\t\t\t\t\treturn generateSSREntry(ctx, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbuildBundle(opts: any) {\n\t\t\t\t\t\t\treturn buildBundle(ctx, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcopyStaticAssets(destDir: string, opts?: any) {\n\t\t\t\t\t\t\treturn copyStaticAssets(ctx, destDir, opts);\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\t\tconsole.log(` Running adapter: ${adapter.name}...\\n`);\n\t\t\t\t\tawait adapter.build(ctx);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tdelete process.env.__FINESOFT_SUB_BUILD__;\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["Hono","createServer","Hono","createSSRApp","injectSSRContent","injectCSRShell","parseAcceptLanguage"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../server/src/app.ts"],"sourcesContent":["/**\n * createSSRApp — 创建 Hono SSR 应用\n *\n * 提供 SSR 通配路由,读取模板、加载 SSR 模块、渲染。\n * 应用层可在此之上追加自定义路由(API 代理等)。\n */\n\nimport { injectCSRShell, injectSSRContent } from \"@finesoft/ssr\";\nimport { Hono } from \"hono\";\nimport type { ViteDevServer } from \"vite\";\nimport { parseAcceptLanguage } from \"./locale\";\n\nexport interface SSRModule {\n\trender: (\n\t\turl: string,\n\t\tlocale: string,\n\t) => Promise<{\n\t\thtml: string;\n\t\thead: string;\n\t\tcss: string;\n\t\tserverData: unknown;\n\t\trenderMode?: string;\n\t}>;\n\tserializeServerData: (data: unknown) => string;\n}\n\nexport interface SSRAppOptions {\n\t/** 项目根路径 */\n\troot: string;\n\t/** Vite dev server(仅开发模式) */\n\tvite?: ViteDevServer;\n\t/** 是否生产环境 */\n\tisProduction: boolean;\n\t/** SSR 入口文件路径(开发用,如 \"/src/ssr.ts\") */\n\tssrEntryPath?: string;\n\t/** 生产环境 SSR 模块路径(如 \"../dist/server/ssr.js\") */\n\tssrProductionModule?: string;\n\t/** 支持的语言列表 */\n\tsupportedLocales?: string[];\n\t/** 默认语言 */\n\tdefaultLocale?: string;\n}\n\nexport function createSSRApp(options: SSRAppOptions): Hono {\n\tconst {\n\t\troot,\n\t\tvite,\n\t\tisProduction,\n\t\tssrEntryPath = \"/src/ssr.ts\",\n\t\tssrProductionModule,\n\t\tsupportedLocales,\n\t\tdefaultLocale,\n\t} = options;\n\n\tconst app = new Hono();\n\n\t/** ISR 内存缓存(prerender 路由首次请求后缓存) */\n\tconst isrCache = new Map<string, string>();\n\n\tasync function readTemplate(url: string): Promise<string> {\n\t\tif (!isProduction && vite) {\n\t\t\tconst { readFileSync } = await import(/* @vite-ignore */ \"node:fs\");\n\t\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\t\tconst raw = readFileSync(resolve(root, \"index.html\"), \"utf-8\");\n\t\t\treturn vite.transformIndexHtml(url, raw);\n\t\t}\n\n\t\tconst isDeno = typeof (globalThis as any).Deno !== \"undefined\";\n\t\tif (isDeno) {\n\t\t\treturn (globalThis as any).Deno.readTextFileSync(\n\t\t\t\tnew URL(\"../dist/client/index.html\", import.meta.url),\n\t\t\t);\n\t\t}\n\n\t\tconst { readFileSync } = await import(/* @vite-ignore */ \"node:fs\");\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\treturn readFileSync(resolve(root, \"dist/client/index.html\"), \"utf-8\");\n\t}\n\n\tasync function loadSSRModule(): Promise<SSRModule> {\n\t\tif (!isProduction && vite) {\n\t\t\treturn (await vite.ssrLoadModule(ssrEntryPath)) as SSRModule;\n\t\t}\n\t\tif (ssrProductionModule) {\n\t\t\treturn import(ssrProductionModule) as Promise<SSRModule>;\n\t\t}\n\t\tconst { resolve } = await import(/* @vite-ignore */ \"node:path\");\n\t\tconst { pathToFileURL } = await import(/* @vite-ignore */ \"node:url\");\n\t\tconst absPath = pathToFileURL(resolve(root, \"dist/server/ssr.js\")).href;\n\t\treturn import(absPath) as Promise<SSRModule>;\n\t}\n\n\tapp.get(\"*\", async (c) => {\n\t\tconst url =\n\t\t\tc.req.path +\n\t\t\t(c.req.url.includes(\"?\") ? \"?\" + c.req.url.split(\"?\")[1] : \"\");\n\n\t\ttry {\n\t\t\t// ISR 缓存命中\n\t\t\tconst cacheKey = url;\n\t\t\tconst cached = isrCache.get(cacheKey);\n\t\t\tif (cached) return c.html(cached);\n\n\t\t\tconst template = await readTemplate(url);\n\t\t\tconst { render, serializeServerData } = await loadSSRModule();\n\n\t\t\tconst locale = parseAcceptLanguage(\n\t\t\t\tc.req.header(\"accept-language\"),\n\t\t\t\tsupportedLocales,\n\t\t\t\tdefaultLocale,\n\t\t\t);\n\n\t\t\tconst {\n\t\t\t\thtml: appHtml,\n\t\t\t\thead,\n\t\t\t\tcss,\n\t\t\t\tserverData,\n\t\t\t\trenderMode,\n\t\t\t} = await render(url, locale);\n\n\t\t\t// CSR 模式:返回空壳 HTML\n\t\t\tif (renderMode === \"csr\") {\n\t\t\t\treturn c.html(injectCSRShell(template, locale));\n\t\t\t}\n\n\t\t\tconst serializedData = serializeServerData(serverData);\n\n\t\t\tconst finalHtml = injectSSRContent({\n\t\t\t\ttemplate,\n\t\t\t\tlocale,\n\t\t\t\thead,\n\t\t\t\tcss,\n\t\t\t\thtml: appHtml,\n\t\t\t\tserializedData,\n\t\t\t});\n\n\t\t\t// Prerender ISR 缓存\n\t\t\tif (renderMode === \"prerender\") {\n\t\t\t\tisrCache.set(cacheKey, finalHtml);\n\t\t\t}\n\n\t\t\treturn c.html(finalHtml);\n\t\t} catch (e) {\n\t\t\tif (!isProduction && vite) {\n\t\t\t\tvite.ssrFixStacktrace(e as Error);\n\t\t\t}\n\t\t\tconsole.error(\"[SSR Error]\", e);\n\t\t\treturn c.text(\"Internal Server Error\", 500);\n\t\t}\n\t});\n\n\treturn app;\n}\n"],"mappings":"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","names":["readFileSync","resolve"]}
|
|
File without changes
|