@lark-apaas/coding-preset-vite-react 0.1.1-alpha.0 → 0.1.1
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/LICENSE +13 -0
- package/lib/index.d.ts +52 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +410 -0
- package/lib/index.js.map +1 -0
- package/lib/plugins/capabilities.d.ts +23 -0
- package/lib/plugins/capabilities.d.ts.map +1 -0
- package/lib/plugins/capabilities.js +151 -0
- package/lib/plugins/capabilities.js.map +1 -0
- package/lib/plugins/dev-logs.d.ts +44 -0
- package/lib/plugins/dev-logs.d.ts.map +1 -0
- package/lib/plugins/dev-logs.js +544 -0
- package/lib/plugins/dev-logs.js.map +1 -0
- package/lib/plugins/error-overlay.d.ts +19 -0
- package/lib/plugins/error-overlay.d.ts.map +1 -0
- package/lib/plugins/error-overlay.js +136 -0
- package/lib/plugins/error-overlay.js.map +1 -0
- package/lib/plugins/fonts-mirror.d.ts +14 -0
- package/lib/plugins/fonts-mirror.d.ts.map +1 -0
- package/lib/plugins/fonts-mirror.js +70 -0
- package/lib/plugins/fonts-mirror.js.map +1 -0
- package/lib/plugins/health.d.ts +19 -0
- package/lib/plugins/health.d.ts.map +1 -0
- package/lib/plugins/health.js +36 -0
- package/lib/plugins/health.js.map +1 -0
- package/lib/plugins/hmr-timing.d.ts +13 -0
- package/lib/plugins/hmr-timing.d.ts.map +1 -0
- package/lib/plugins/hmr-timing.js +93 -0
- package/lib/plugins/hmr-timing.js.map +1 -0
- package/lib/plugins/html-minify.d.ts +18 -0
- package/lib/plugins/html-minify.d.ts.map +1 -0
- package/lib/plugins/html-minify.js +100 -0
- package/lib/plugins/html-minify.js.map +1 -0
- package/lib/plugins/module-alias.d.ts +12 -0
- package/lib/plugins/module-alias.d.ts.map +1 -0
- package/lib/plugins/module-alias.js +78 -0
- package/lib/plugins/module-alias.js.map +1 -0
- package/lib/plugins/og-meta.d.ts +21 -0
- package/lib/plugins/og-meta.d.ts.map +1 -0
- package/lib/plugins/og-meta.js +60 -0
- package/lib/plugins/og-meta.js.map +1 -0
- package/lib/plugins/polyfill.d.ts +11 -0
- package/lib/plugins/polyfill.d.ts.map +1 -0
- package/lib/plugins/polyfill.js +140 -0
- package/lib/plugins/polyfill.js.map +1 -0
- package/lib/plugins/routes.d.ts +26 -0
- package/lib/plugins/routes.d.ts.map +1 -0
- package/lib/plugins/routes.js +265 -0
- package/lib/plugins/routes.js.map +1 -0
- package/lib/plugins/slardar.d.ts +24 -0
- package/lib/plugins/slardar.d.ts.map +1 -0
- package/lib/plugins/slardar.js +74 -0
- package/lib/plugins/slardar.js.map +1 -0
- package/lib/plugins/static-assets.d.ts +10 -0
- package/lib/plugins/static-assets.d.ts.map +1 -0
- package/lib/plugins/static-assets.js +307 -0
- package/lib/plugins/static-assets.js.map +1 -0
- package/lib/plugins/view-context.d.ts +22 -0
- package/lib/plugins/view-context.d.ts.map +1 -0
- package/lib/plugins/view-context.js +165 -0
- package/lib/plugins/view-context.js.map +1 -0
- package/lib/plugins/vite-client-patch.d.ts +4 -0
- package/lib/plugins/vite-client-patch.d.ts.map +1 -0
- package/lib/plugins/vite-client-patch.js +37 -0
- package/lib/plugins/vite-client-patch.js.map +1 -0
- package/lib/plugins/ws-watchdog.d.ts +22 -0
- package/lib/plugins/ws-watchdog.d.ts.map +1 -0
- package/lib/plugins/ws-watchdog.js +103 -0
- package/lib/plugins/ws-watchdog.js.map +1 -0
- package/lib/polyfills/index.d.ts +15 -0
- package/lib/polyfills/index.d.ts.map +1 -0
- package/lib/polyfills/index.js +36 -0
- package/lib/polyfills/index.js.map +1 -0
- package/lib/utils/normalize-base-path.d.ts +37 -0
- package/lib/utils/normalize-base-path.d.ts.map +1 -0
- package/lib/utils/normalize-base-path.js +57 -0
- package/lib/utils/normalize-base-path.js.map +1 -0
- package/lib/utils/snapdom-proxy.d.ts +12 -0
- package/lib/utils/snapdom-proxy.d.ts.map +1 -0
- package/lib/utils/snapdom-proxy.js +75 -0
- package/lib/utils/snapdom-proxy.js.map +1 -0
- package/package.json +9 -15
- package/dist/index.d.ts +0 -320
- package/dist/index.js +0 -1941
- package/dist/index.js.map +0 -1
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/plugins/routes.ts","../src/utils/normalize-base-path.ts","../src/plugins/html-minify.ts","../src/plugins/static-assets.ts","../src/plugins/capabilities.ts","../src/plugins/error-overlay.ts","../src/plugins/hmr-timing.ts","../src/plugins/ws-watchdog.ts","../src/plugins/health.ts","../src/plugins/view-context.ts","../src/plugins/module-alias.ts","../src/plugins/og-meta.ts","../src/plugins/fonts-mirror.ts","../src/plugins/polyfill.ts","../src/plugins/vite-client-patch.ts","../src/plugins/slardar.ts","../src/plugins/dev-logs.ts","../src/utils/snapdom-proxy.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { mergeConfig, type Plugin, type UserConfig, type ViteDevServer } from 'vite';\nimport react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';\n\nimport { routesPlugin } from './plugins/routes';\nimport { htmlMinifyPlugin } from './plugins/html-minify';\nimport { staticAssetsPlugin } from './plugins/static-assets';\nimport { capabilitiesBundlePlugin } from './plugins/capabilities';\nimport { errorOverlayPlugin } from './plugins/error-overlay';\nimport { hmrTimingPlugin } from './plugins/hmr-timing';\nimport { wsWatchdogPlugin } from './plugins/ws-watchdog';\nimport { healthMiddlewarePlugin } from './plugins/health';\nimport { viewContextPlugin } from './plugins/view-context';\nimport { moduleAliasPlugin } from './plugins/module-alias';\nimport { ogMetaPlugin } from './plugins/og-meta';\nimport { fontsMirrorPlugin } from './plugins/fonts-mirror';\nimport { polyfillPlugin } from './plugins/polyfill';\nimport { viteClientPatchPlugin } from './plugins/vite-client-patch';\nimport { slardarPlugin } from './plugins/slardar';\nimport { devLogsPlugin } from './plugins/dev-logs';\n\nimport { normalizeBasePath } from './utils/normalize-base-path';\nimport { registerSnapDomProxyMiddleware } from './utils/snapdom-proxy';\n\nconst req = createRequire(import.meta.url);\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * 兼容两种模板 layout 的路径解析:\n * - 老 fullstack 模板:`client/X` 存在\n * - 新 jsPage 模板:`X` 在项目根(无 client/ 包装)\n */\nfunction resolveClientPath(rootDir: string, rel: string): string {\n const legacy = path.resolve(rootDir, 'client', rel);\n if (fs.existsSync(legacy)) return legacy;\n return path.resolve(rootDir, rel);\n}\n\nfunction readAppFlags(rootDir: string): Record<string, unknown> {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.resolve(rootDir, 'package.json'), 'utf-8'));\n return pkg.flags || {};\n } catch {\n return {};\n }\n}\n\n/**\n * 读 dist/{page,api}-routes.json(build.sh 在 vite build 前生成,jsPage 不产)。\n * 即使文件不存在也安全注入空数组 define,避免业务代码引用时报 undefined。\n */\nfunction readRouteDefinitions(rootDir: string) {\n let pageRoutes: Array<{ path: string }> = [];\n let apiRoutes: Array<{ method: string; path: string }> = [];\n try {\n const p = path.resolve(rootDir, 'dist/page-routes.json');\n if (fs.existsSync(p)) pageRoutes = JSON.parse(fs.readFileSync(p, 'utf-8'));\n } catch {\n /* ignore */\n }\n try {\n const p = path.resolve(rootDir, 'dist/api-routes.json');\n if (fs.existsSync(p)) apiRoutes = JSON.parse(fs.readFileSync(p, 'utf-8'));\n } catch {\n /* ignore */\n }\n return { pageRoutes, apiRoutes };\n}\n\n/**\n * 动态加载 inspector(dev 默认开,`DISABLE_INSPECTOR=true` 可关)。\n * tsup ESM build 下没有原生 require,用 createRequire 走标准 Node 接口。\n */\nfunction tryLoadInspector(enabled: boolean): Plugin[] {\n if (!enabled) return [];\n try {\n const mod = req('@lark-apaas/vite-inspector-plugin') as { inspectorPlugin: () => Plugin };\n return [mod.inspectorPlugin()];\n } catch {\n return [];\n }\n}\n\n/**\n * miaoda-coding vite-react (jsPage) 默认 Vite 配置。\n *\n * 通过环境变量自动读取部署相关参数,用户只需提供项目特有的覆盖:\n *\n * ```ts\n * import { defineConfig } from '@lark-apaas/coding-preset-vite-react';\n * import path from 'node:path';\n *\n * export default defineConfig({\n * resolve: {\n * alias: {\n * '@': path.resolve(__dirname, 'src'),\n * '@shared': path.resolve(__dirname, 'shared'),\n * },\n * },\n * });\n * ```\n *\n * 支持环境变量:\n * - NODE_ENV development | production(默认 development)\n * - CLIENT_BASE_PATH 部署侧 client base path(如 `/app/<id>`)\n * - ASSETS_CDN_PATH 生产 JS/CSS CDN 前缀(可选)\n * - CLIENT_DEV_PORT dev server 端口(默认 8080)\n * - CLIENT_DEV_HOST dev server host(默认 localhost)\n * - FORCE_FRAMEWORK_DOMAIN_MAIN 反向代理域名(启用 wss HMR + 设置 ACAO)\n * - DISABLE_INSPECTOR `true` 关 inspector\n * - MIAODA_FONTS_MIRROR_OFF `1` 关 Google Fonts 代理替换\n * - MIAODA_APP_TYPE 妙搭应用类型(数字字符串,供 lite Safety 徽标判断)\n */\nexport function defineConfig(overrides: UserConfig = {}): UserConfig {\n const isDev = process.env.NODE_ENV !== 'production';\n const rootDir = process.cwd();\n const clientBasePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);\n const assetsCdnPath = normalizeBasePath(process.env.ASSETS_CDN_PATH);\n\n // dev / prod base 来源不同:dev 完全用 clientBasePath,prod 优先 CDN\n const publicPath = isDev ? clientBasePath : (assetsCdnPath || clientBasePath);\n const base = publicPath ? `${publicPath}/` : '/';\n\n // 从 clientBasePath 提取 appId 给 viewContext 用\n const isNewPathFormat = /^\\/app\\/[^/]/.test(clientBasePath);\n const appId = isNewPathFormat\n ? clientBasePath.replace(/\\/+$/, '').split('/').pop()\n : undefined;\n\n const appFlags = readAppFlags(rootDir);\n const { pageRoutes, apiRoutes } = readRouteDefinitions(rootDir);\n const enableInspector = isDev && process.env.DISABLE_INSPECTOR !== 'true';\n\n const baseConfig: UserConfig = {\n root: rootDir,\n base,\n\n plugins: [\n // dev only: HMR 重连不刷页面(沙箱链路下避免 ~18s 死连接超时)\n isDev && viteClientPatchPlugin(),\n\n // virtual:capabilities —— client-toolkit-lite / client-capability SDK 强依赖;\n // 即便业务工程没有 capability JSON 也要把虚拟模块注册成空 map,否则 build fail\n capabilitiesBundlePlugin(),\n\n // dev only: 自定义 HMR 错误浮层(替 Vite 原生)\n isDev && errorOverlayPlugin({ clientBasePath }),\n\n // @shared/static/* 路径解析 —— enforce: 'pre',早于 tsconfig paths 和 vite:json\n staticAssetsPlugin({ clientBasePath, rootDir }),\n\n // inspector 必须排在 react() 之前 —— 两者都 enforce:'pre',inspector 需要原 JSX\n // 还在的时候打 data-* 标记;react 转译完就剩 _jsxDEV() 调用了\n ...tryLoadInspector(enableInspector),\n\n react(),\n tailwindcss(),\n\n // clsx / echarts / echarts-for-react alias —— 让所有 echarts 子路径指向 preset 自带版本\n moduleAliasPlugin(),\n\n // routes.json(dev 内存 + middleware;build emitFile)\n routesPlugin({\n appPath: fs.existsSync(path.resolve(rootDir, 'client/src/app.tsx'))\n ? './client/src/app.tsx'\n : './src/app.tsx',\n serveBasePath: clientBasePath,\n // dev 显式空 base —— 沙箱网关把 prefix 剥掉了,直接 / 访问\n ...(isDev ? { basePath: '' } : {}),\n }),\n\n // OG Meta tags + title + favicon 注入 HBS 占位符({{appName}} / {{appAvatar}} 等)\n // 由部署运行时(vefaas)调 platform API 拿 appInfo 后做 hbs replace;\n // dev 预览看到的是字面占位符,业务侧用 useAppInfo + useEffect setTitle 兜底\n ogMetaPlugin(),\n\n // head 顺序敏感:slardar 必须排在 viewContext **之前**——\n // Vite 同 bucket(head-prepend)是\"后执行者插更前\"。\n // 数组里 slardar 在前 → HTML 里 viewContext 在 slardar 之上 → onload 时拿得到 window.tenantId\n slardarPlugin({ bid: 'apaas_miaoda' }),\n viewContextPlugin({ appId: isDev ? appId : undefined }),\n\n // prod only: 老浏览器 polyfill(按需加载)\n !isDev && polyfillPlugin(),\n\n // build-time HTML minify(HBS 占位符保护)\n htmlMinifyPlugin(),\n\n // dev only DX 插件\n isDev && hmrTimingPlugin(),\n isDev && wsWatchdogPlugin({ clientBasePath }),\n isDev && healthMiddlewarePlugin(),\n // 客户端日志收集 endpoint(POST /dev/logs/collect{,-batch})\n isDev && devLogsPlugin({ basePath: clientBasePath }),\n\n // Google Fonts → 妙搭字体代理(编译时字符串 replace;dev / build 都有用)\n fontsMirrorPlugin(),\n ].filter(Boolean) as Plugin[],\n\n resolve: {\n // Vite 8 原生 tsconfig paths 解析\n tsconfigPaths: true,\n // 跟 rspack-preset 对齐的 mainFields 顺序\n mainFields: ['module', 'browser', 'main'],\n extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],\n alias: {\n // 所有 echarts 子路径解析到 preset 自带的 echarts,避免第三方扩展(如\n // echarts-wordcloud)拉独立 echarts 副本导致注册不到同一实例\n echarts: path.dirname(req.resolve('echarts/package.json')),\n // Inspector dev-only CSS:dev 走 inspector 运行时注入,build 给空 stub\n '@/inspector.dev.css': path.resolve(__dirname, '../src/empty.css'),\n // prod:inspector 整包替成空 stub,避免进生产 bundle\n ...(!isDev\n ? {\n '@lark-apaas/miaoda-inspector': path.resolve(__dirname, '../src/inspector-stub.js'),\n }\n : {}),\n },\n },\n\n define: {\n // Node global polyfill(sockjs-client 等老库要)\n global: 'globalThis',\n 'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),\n 'process.env.runtimeMode': JSON.stringify('fullstack'),\n 'process.env.CLIENT_BASE_PATH': JSON.stringify(clientBasePath),\n __APP_BASE_PATH__: JSON.stringify(clientBasePath),\n // 未设置时替换为字面量 `undefined`,让 `??` fallback 正确触发(`\"\"`/`undefined` 行为不同)\n 'process.env.FORCE_FRAMEWORK_DOMAIN_MAIN': process.env.FORCE_FRAMEWORK_DOMAIN_MAIN\n ? JSON.stringify(process.env.FORCE_FRAMEWORK_DOMAIN_MAIN)\n : 'undefined',\n 'process.env.CWD': JSON.stringify(''),\n 'process.env.__RUNTIME_INJECTED__': JSON.stringify('true'),\n 'process.env.BUILD_TOOL': JSON.stringify('vite'),\n 'process.env.APP_FLAGS': JSON.stringify(appFlags),\n // 路由定义(jsPage 用空数组,业务代码引用时不至于 undefined)\n 'process.env.__PAGE_ROUTE_DEFINITIONS__': JSON.stringify(JSON.stringify(pageRoutes)),\n 'process.env.__API_ROUTE_DEFINITIONS__': JSON.stringify(JSON.stringify(apiRoutes)),\n 'process.env.MIAODA_APP_TYPE': process.env.MIAODA_APP_TYPE\n ? JSON.stringify(process.env.MIAODA_APP_TYPE)\n : 'undefined',\n },\n\n server: {\n port: Number(process.env.CLIENT_DEV_PORT) || 8080,\n host: process.env.CLIENT_DEV_HOST || 'localhost',\n strictPort: true,\n cors: true,\n allowedHosts: true,\n headers: {\n ...(process.env.FORCE_FRAMEWORK_DOMAIN_MAIN\n ? { 'Access-Control-Allow-Origin': process.env.FORCE_FRAMEWORK_DOMAIN_MAIN }\n : {}),\n },\n watch: {\n usePolling: true,\n interval: 500,\n ignored: ['**/node_modules/**', '**/dist/**'],\n },\n hmr: process.env.FORCE_FRAMEWORK_DOMAIN_MAIN\n ? { protocol: 'wss', path: '/ws' }\n : { path: '/ws' },\n },\n\n build: {\n outDir: path.resolve(rootDir, 'dist/client'),\n // build.sh 已经在 vite build 前 `rm -rf dist`,这里不再让 vite 自己清\n emptyOutDir: false,\n sourcemap: isDev ? true : 'hidden',\n minify: !isDev,\n cssTarget: ['ios12', 'safari12', 'chrome80'],\n rollupOptions: {\n input: resolveClientPath(rootDir, 'index.html'),\n output: {\n // 按依赖拆 chunk,优化缓存和并行加载\n manualChunks(id: string) {\n if (id.includes('@lark-apaas/client-toolkit-lite')) return 'toolkit';\n if (id.includes('@radix-ui')) return 'radix';\n if (id.includes('@data-loom')) return 'dataloom';\n return undefined;\n },\n },\n },\n copyPublicDir: true,\n },\n\n publicDir: resolveClientPath(rootDir, 'public'),\n\n optimizeDeps: {\n include: [\n 'react',\n 'react-dom',\n 'react/jsx-runtime',\n 'react/jsx-dev-runtime',\n 'clsx',\n 'echarts',\n 'echarts-for-react',\n ...(enableInspector ? ['@lark-apaas/miaoda-inspector'] : []),\n ],\n },\n };\n\n // dev 期补三组 middleware:base-path internal rewrite、SnapDom proxy、devtool-kits 日志相关\n if (isDev) {\n (baseConfig.plugins as Plugin[]).push({\n name: 'miaoda-dev-middlewares',\n async configureServer(server: ViteDevServer) {\n // ── base-path normalize ──────────────────────────────────────────\n // Vite 8 baseMiddleware:请求 pathname 不以 base(含末尾 /)开头时显示警告页,\n // 不再自动 301。沙箱预览过来的 URL 通常是 `/app/app_xxx?sso_token=...`(pathname\n // 没末尾 /),会被警告页拦下。\n //\n // 用 internal rewrite(不是 301)—— 浏览器跳 → 沙箱网关在转发\"带尾 /\"时会把\n // 尾 / 又 strip 回去 → vite 又 301 → ERR_TOO_MANY_REDIRECTS。\n // 必须 unshift 到 stack 开头才能早于 baseMiddleware 执行。\n const baseWithSlash = clientBasePath.endsWith('/')\n ? clientBasePath\n : clientBasePath + '/';\n const baseWithoutSlash = baseWithSlash.slice(0, -1);\n if (baseWithoutSlash) {\n const stack = (\n server.middlewares as unknown as { stack: Array<{ route: string; handle: unknown }> }\n ).stack;\n if (Array.isArray(stack)) {\n stack.unshift({\n route: '',\n handle: (\n req: IncomingMessage,\n _res: ServerResponse,\n next: () => void\n ) => {\n const url = req.url || '';\n const qIdx = url.indexOf('?');\n const pathname = qIdx >= 0 ? url.slice(0, qIdx) : url;\n const search = qIdx >= 0 ? url.slice(qIdx) : '';\n if (pathname === baseWithoutSlash) {\n req.url = baseWithoutSlash + '/' + search;\n }\n next();\n },\n });\n }\n }\n\n // SnapDom proxy(client 截图库的跨域转发)\n registerSnapDomProxyMiddleware(server.middlewares, { baseUrl: clientBasePath });\n // 注:客户端日志收集 endpoint 现在由 devLogsPlugin 自己挂载(plugin 数组里),\n // 这里不再做集中注册——以前依赖 @lark-apaas/devtool-kits 已彻底去除\n },\n });\n }\n\n return mergeConfig(baseConfig, overrides);\n}\n\n// 默认导出与命名导出同名\nexport default defineConfig;\n\n// 子模块导出\nexport { routesPlugin, parseRoutes } from './plugins/routes';\nexport { htmlMinifyPlugin, minifyHtmlWithHbsProtection } from './plugins/html-minify';\nexport { staticAssetsPlugin } from './plugins/static-assets';\nexport { capabilitiesBundlePlugin } from './plugins/capabilities';\nexport { errorOverlayPlugin } from './plugins/error-overlay';\nexport { hmrTimingPlugin } from './plugins/hmr-timing';\nexport { wsWatchdogPlugin } from './plugins/ws-watchdog';\nexport { healthMiddlewarePlugin } from './plugins/health';\nexport { viewContextPlugin } from './plugins/view-context';\nexport { moduleAliasPlugin } from './plugins/module-alias';\nexport { ogMetaPlugin } from './plugins/og-meta';\nexport { fontsMirrorPlugin } from './plugins/fonts-mirror';\nexport { polyfillPlugin } from './plugins/polyfill';\nexport { viteClientPatchPlugin } from './plugins/vite-client-patch';\nexport { slardarPlugin } from './plugins/slardar';\nexport { devLogsPlugin } from './plugins/dev-logs';\nexport { normalizeBasePath } from './utils/normalize-base-path';\nexport { registerSnapDomProxyMiddleware } from './utils/snapdom-proxy';\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { parse } from '@babel/parser';\nimport _traverse from '@babel/traverse';\nimport * as t from '@babel/types';\nimport type { Plugin, ViteDevServer } from 'vite';\n\nimport { normalizeBasePath } from '../utils/normalize-base-path';\n\n// @babel/traverse 在 ESM 下默认是 default export\nconst traverse = (_traverse as unknown as { default: typeof _traverse }).default ?? _traverse;\n\nexport interface RoutesPluginOptions {\n /** 应用入口路径(相对项目根)。默认按顺序探测 `src/app.tsx`、`client/src/app.tsx`。 */\n appPath?: string;\n /** 写入 routes.json 时给每条 path 的前缀。未传时回退到 `process.env.CLIENT_BASE_PATH`。 */\n basePath?: string;\n /** dev middleware 把 `/routes.json` 挂在哪个 URL 前缀下。未传时回退到 `process.env.CLIENT_BASE_PATH`。 */\n serveBasePath?: string;\n}\n\ninterface RouteEntry {\n path: string;\n}\n\ninterface RouteFrame {\n path?: string;\n index?: boolean;\n}\n\nfunction isRouteComponent(opening: t.JSXOpeningElement): boolean {\n return t.isJSXIdentifier(opening.name) && opening.name.name === 'Route';\n}\n\nfunction evaluateTemplateLiteral(tpl: t.TemplateLiteral): string {\n // 仅处理纯字面量 quasis;有 expression 时把表达式段当空字符串拼\n if (tpl.quasis.length === 1 && tpl.expressions.length === 0) {\n return tpl.quasis[0].value.raw;\n }\n return tpl.quasis.map((q) => q.value.raw).join('');\n}\n\nfunction extractRouteFrame(opening: t.JSXOpeningElement): RouteFrame {\n const frame: RouteFrame = {};\n for (const attr of opening.attributes) {\n if (!t.isJSXAttribute(attr) || !t.isJSXIdentifier(attr.name)) continue;\n const name = attr.name.name;\n if (name !== 'path' && name !== 'index') continue;\n\n let value: string | boolean | undefined;\n if (attr.value) {\n if (t.isStringLiteral(attr.value)) {\n value = attr.value.value;\n } else if (t.isJSXExpressionContainer(attr.value)) {\n const expr = attr.value.expression;\n if (t.isStringLiteral(expr)) value = expr.value;\n else if (t.isTemplateLiteral(expr)) value = evaluateTemplateLiteral(expr);\n else value = true;\n }\n } else {\n // 无值属性:`<Route index>` → value=true\n value = true;\n }\n\n if (name === 'path' && typeof value === 'string') frame.path = value;\n if (name === 'index' && value === true) frame.index = true;\n }\n return frame;\n}\n\nfunction buildFullPath(stack: RouteFrame[], current: RouteFrame): string | null {\n let fullPath = '';\n for (const parent of stack) {\n if (!parent.path) continue;\n let p = parent.path;\n if (!p.startsWith('/')) p = '/' + p;\n if (p.endsWith('/') && p !== '/') p = p.slice(0, -1);\n fullPath += p === '/' ? '' : p;\n }\n\n if (current.index) return fullPath || '/';\n\n if (current.path) {\n const rp = current.path;\n if (rp === '*') return null;\n if (!rp.startsWith('/')) fullPath = `${fullPath}/${rp}`;\n else fullPath = rp; // 绝对路径覆盖\n if (fullPath === '') fullPath = '/';\n if (!fullPath.startsWith('/')) fullPath = '/' + fullPath;\n return fullPath;\n }\n\n return null;\n}\n\n/**\n * AST 解析 React Router 的 `<Route>` 元素,返回路由列表。\n *\n * 算法移植自 `@lark-apaas/devtool-kits` 的 `parseRoutesFromFile`:\n * - `<Route path=\"...\" />` / `path={'...'}` / `path={`...`}` 都识别\n * - 嵌套 path 自动 join,子节点用绝对路径时覆盖\n * - `<Route index>` 视作当前层级根\n * - `path=\"*\"` 通配符跳过\n * - 表达式形如 `path={variable}` 时跳过(无法静态求值)\n */\nexport function parseRoutes(source: string, basePath: string): RouteEntry[] {\n const defaultPath = basePath ? `${basePath}/` : '/';\n\n let ast: t.File;\n try {\n ast = parse(source, {\n sourceType: 'module',\n plugins: [\n 'jsx',\n 'typescript',\n 'decorators-legacy',\n 'classProperties',\n 'objectRestSpread',\n 'functionBind',\n 'exportDefaultFrom',\n 'exportNamespaceFrom',\n 'dynamicImport',\n 'nullishCoalescingOperator',\n 'optionalChaining',\n ],\n });\n } catch (e) {\n // 解析失败:fallback 到默认单根路由(与上游一致)\n return [{ path: defaultPath }];\n }\n\n const routeSet = new Set<string>();\n const stack: RouteFrame[] = [];\n\n traverse(ast, {\n JSXElement: {\n enter(p) {\n const opening = p.node.openingElement;\n if (isRouteComponent(opening)) {\n stack.push(extractRouteFrame(opening));\n }\n },\n exit(p) {\n const opening = p.node.openingElement;\n if (!isRouteComponent(opening)) return;\n const current = stack.pop();\n if (!current) return;\n if (current.path === '*') return;\n if (current.path || current.index) {\n const full = buildFullPath(stack, current);\n if (full) routeSet.add(full);\n }\n },\n },\n });\n\n const routes = Array.from(routeSet).map((p) => ({\n path: basePath ? `${basePath}${p}` : p,\n }));\n return routes.length > 0 ? routes : [{ path: defaultPath }];\n}\n\nfunction resolveAppPath(rootDir: string, hint?: string): string | null {\n if (hint) {\n const abs = path.resolve(rootDir, hint);\n return fs.existsSync(abs) ? abs : null;\n }\n for (const rel of ['src/app.tsx', 'client/src/app.tsx']) {\n const abs = path.resolve(rootDir, rel);\n if (fs.existsSync(abs)) return abs;\n }\n return null;\n}\n\nexport function routesPlugin(options: RoutesPluginOptions = {}): Plugin {\n const envBase = process.env.CLIENT_BASE_PATH || '';\n const buildBase = normalizeBasePath(options.basePath ?? envBase);\n const serveBase = normalizeBasePath(options.serveBasePath ?? envBase);\n\n let appAbs: string | null = null;\n let cached: { routes: RouteEntry[]; base: string } | null = null;\n\n function generate(forBase: string): RouteEntry[] {\n if (cached && cached.base === forBase) return cached.routes;\n if (!appAbs || !fs.existsSync(appAbs)) {\n const fallback = [{ path: forBase ? `${forBase}/` : '/' }];\n cached = { routes: fallback, base: forBase };\n return fallback;\n }\n const src = fs.readFileSync(appAbs, 'utf-8');\n const routes = parseRoutes(src, forBase);\n cached = { routes, base: forBase };\n return routes;\n }\n\n return {\n name: 'miaoda-routes',\n\n configResolved(config) {\n appAbs = resolveAppPath(config.root, options.appPath);\n },\n\n configureServer(server: ViteDevServer) {\n // dev:base 强制为空(沙箱预览代理把 base path 剥掉了),middleware URL 按 serveBase 挂载\n generate('');\n\n if (appAbs) {\n server.watcher.add(appAbs);\n server.watcher.on('change', (file) => {\n if (file === appAbs) {\n cached = null;\n generate('');\n }\n });\n }\n\n const urlPath = serveBase ? `${serveBase}/routes.json` : '/routes.json';\n server.middlewares.use((req, res, next) => {\n const pathname = req.url?.split('?')[0];\n if (pathname === urlPath) {\n const routes = generate('');\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(routes, null, 2));\n return;\n }\n next();\n });\n },\n\n buildStart() {\n cached = null;\n generate(buildBase);\n },\n\n generateBundle() {\n const routes = generate(buildBase);\n this.emitFile({\n type: 'asset',\n fileName: 'routes.json',\n source: JSON.stringify(routes, null, 2),\n });\n },\n };\n}\n\nexport default routesPlugin;\n","/**\n * 标准化 base path:\n * - 空 / undefined → 空字符串\n * - 前面强制加 `/`\n * - 去掉尾部 `/`\n *\n * 例:\n * normalizeBasePath('') === ''\n * normalizeBasePath('/') === ''\n * normalizeBasePath('foo') === '/foo'\n * normalizeBasePath('/foo/') === '/foo'\n * normalizeBasePath('/app/x/') === '/app/x'\n */\nexport function normalizeBasePath(input: string | undefined): string {\n if (!input) return '';\n let p = input.trim();\n if (!p || p === '/') return '';\n if (!p.startsWith('/')) p = '/' + p;\n return p.replace(/\\/+$/, '');\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { minify } from 'html-minifier-terser';\nimport type { Plugin, ResolvedConfig } from 'vite';\n\n/**\n * 压缩 HTML,同时保护 HBS(Handlebars)占位符。\n *\n * `{{csrfToken}}` / `{{{appAvatar}}}` 这类占位符是部署运行时(vefaas)替换的,\n * 直接交给 html-minifier-terser 会被解析破坏。先把它们抽出来用 `__HBS_<i>__`\n * 占位,压缩完再放回去。\n */\nexport async function minifyHtmlWithHbsProtection(html: string): Promise<string> {\n const placeholders: string[] = [];\n let processed = html.replace(/\\{\\{\\{?.+?\\}\\}\\}?/g, (match) => {\n const i = placeholders.length;\n placeholders.push(match);\n return `__HBS_${i}__`;\n });\n\n processed = await minify(processed, {\n collapseWhitespace: true,\n removeComments: true,\n removeRedundantAttributes: true,\n removeEmptyAttributes: true,\n minifyCSS: true,\n // 不压 JS:inline script 里可能引用了 HBS 占位符\n minifyJS: false,\n });\n\n return processed.replace(/__HBS_(\\d+)__/g, (_, i) => placeholders[Number(i)]);\n}\n\n/**\n * 仅 build 期生效的 HTML 压缩插件。\n *\n * dev 期完全 no-op(不挂 hook、不读盘);\n * build 完毕时(closeBundle)读 `outDir/index.html` 压缩后写回。\n */\nexport function htmlMinifyPlugin(): Plugin {\n let config: ResolvedConfig;\n let isDev = false;\n\n return {\n name: 'miaoda-html-minify',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n isDev = resolvedConfig.command === 'serve';\n },\n\n async closeBundle() {\n if (isDev || !config) return;\n\n const htmlPath = path.resolve(config.build.outDir, 'index.html');\n if (!fs.existsSync(htmlPath)) return;\n\n try {\n const source = fs.readFileSync(htmlPath, 'utf-8');\n const minified = await minifyHtmlWithHbsProtection(source);\n fs.writeFileSync(htmlPath, minified);\n } catch (e) {\n // 单独捕获:minify 失败不应该把整个 build 拖崩,输出文件仍然是 Vite 写出的原版\n console.warn(`[miaoda-html-minify] minify failed, keeping unminified HTML:`, e);\n }\n },\n };\n}\n\nexport default htmlMinifyPlugin;\n","/**\n * 业务工程 `shared/static/*` 静态资源解析。\n *\n * - JSON:dev 内联展开成 `export default {...}`;prod 走 `window.__STATIC_JSON__['key']`\n * (prod HTML 注入 inline script 一次性塞所有 json)\n * - 其它文件:返回 URL 字符串 `${publicPrefix}/<rel>`(默认 `${clientBasePath}/static/<rel>`)\n * - 脚本扩展(.ts/.tsx/.js/.jsx/.mts/.cts/.mjs/.cjs):fallback 到真实路径,让 Vite 当普通模块打\n * - 带 query 的 import(`?raw`/`?url` 等):返回真实路径 + query,让 Vite 内置处理\n *\n * 算法移植自 `@lark-apaas/coding-vite-preset/static-assets-plugin`,\n * 把 `glob` 依赖换成 `fs.readdirSync` 递归遍历,去掉额外 dep。\n */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { HtmlTagDescriptor, Plugin, ViteDevServer } from 'vite';\n\nconst PREFIX = '@shared/static/';\nconst VIRTUAL_PREFIX = '\\0@shared/static/';\n\nconst SCRIPT_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mts', '.cts', '.mjs', '.cjs'];\n\nconst MIME: Record<string, string> = {\n '.json': 'application/json',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.webp': 'image/webp',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.eot': 'application/vnd.ms-fontobject',\n '.otf': 'font/otf',\n '.css': 'text/css',\n '.js': 'application/javascript',\n '.txt': 'text/plain',\n '.html': 'text/html',\n '.xml': 'application/xml',\n '.pdf': 'application/pdf',\n '.mp3': 'audio/mpeg',\n '.mp4': 'video/mp4',\n '.webm': 'video/webm',\n};\n\nfunction splitQuery(rel: string): [string, string] {\n const i = rel.indexOf('?');\n return i === -1 ? [rel, ''] : [rel.slice(0, i), rel.slice(i)];\n}\n\nfunction resolveScriptFile(staticDir: string, cleanPath: string): string | null {\n const ext = path.extname(cleanPath).toLowerCase();\n if (ext && SCRIPT_EXTENSIONS.includes(ext)) {\n return path.join(staticDir, cleanPath);\n }\n if (!ext) {\n for (const e of SCRIPT_EXTENSIONS) {\n const p = path.join(staticDir, cleanPath + e);\n if (fs.existsSync(p)) return p;\n }\n }\n return null;\n}\n\nfunction walkJson(dir: string, out: Record<string, unknown>, prefix = ''): void {\n if (!fs.existsSync(dir)) return;\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = path.join(dir, entry.name);\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n walkJson(full, out, rel);\n } else if (entry.isFile() && entry.name.endsWith('.json')) {\n try {\n const key = rel.replace(/\\.json$/, '');\n out[key] = JSON.parse(fs.readFileSync(full, 'utf-8'));\n } catch (e) {\n console.warn(`[miaoda-static-assets] skip invalid json: ${rel}: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n }\n}\n\nexport interface StaticAssetsPluginOptions {\n /** Client base path prefix for routes. */\n clientBasePath?: string;\n /** Project root directory. Defaults to `process.cwd()`. */\n rootDir?: string;\n}\n\nexport function staticAssetsPlugin(options: StaticAssetsPluginOptions = {}): Plugin {\n const { clientBasePath = '', rootDir = process.cwd() } = options;\n const staticDir = path.resolve(rootDir, 'shared/static');\n\n let isDev = true;\n let jsonCache: Record<string, unknown> | null = null;\n\n function getJson(): Record<string, unknown> {\n if (!isDev && jsonCache) return jsonCache;\n const data: Record<string, unknown> = {};\n walkJson(staticDir, data);\n if (!isDev) jsonCache = data;\n return data;\n }\n\n return {\n name: 'miaoda-static-assets',\n // 必须 enforce:'pre':早于 tsconfig paths 和 vite:json transform\n enforce: 'pre',\n\n config(_config, { command }) {\n isDev = command === 'serve';\n },\n\n resolveId: {\n filter: { id: /^@shared\\/static\\// },\n handler(id: string) {\n if (!id.startsWith(PREFIX)) return null;\n const rel = id.slice(PREFIX.length);\n const [cleanPath, query] = splitQuery(rel);\n\n // ?raw / ?url 等:返回真实路径 + query,交给 Vite 内置处理\n if (query) return path.join(staticDir, cleanPath) + query;\n\n // 脚本:解析到真实文件,让 vite 当普通模块打\n const scriptPath = resolveScriptFile(staticDir, cleanPath);\n if (scriptPath) return scriptPath;\n\n const virtualId = VIRTUAL_PREFIX + cleanPath;\n // 后缀 `.js` 避免 vite:json 把 .json 虚拟模块当 JSON 文件 transform\n return cleanPath.endsWith('.json') ? virtualId + '.js' : virtualId;\n },\n },\n\n load(id: string) {\n if (!id.startsWith(VIRTUAL_PREFIX)) return null;\n\n let rel = id.slice(VIRTUAL_PREFIX.length);\n if (rel.endsWith('.json.js')) rel = rel.slice(0, -3); // strip 上面加的 .js\n const isJson = rel.endsWith('.json');\n\n if (isJson) {\n if (isDev) {\n // dev:直接内联 JSON 内容,避免依赖 window.__STATIC_JSON__\n const full = path.join(staticDir, rel);\n try {\n const content = fs.readFileSync(full, 'utf-8');\n return `export default ${content};`;\n } catch (e) {\n console.warn(`[miaoda-static-assets] read json failed: ${rel}`, e);\n return `export default undefined;`;\n }\n }\n // prod:从 transformIndexHtml 注入的 window.__STATIC_JSON__ 取\n const key = rel.replace(/\\.json$/, '');\n return `export default window.__STATIC_JSON__[${JSON.stringify(key)}];`;\n }\n\n // 非 JSON:返回 URL 字符串\n // - dev:走 `${clientBasePath}/static/${rel}`,由本插件挂的 middleware 服务真实文件\n // - prod:走 `${STATIC_ASSETS_BASE_URL}/${rel}`(build.sh 从 MIAODA_STATIC_CDN_PREFIX 映射,\n // 最终来自 TOS preUploadStatic.downloadURLPrefix)。未设置时空字符串退化为相对路径——\n // 线上 build 缺这个环境变量基本是 deploy 配置漏了,warn 一下方便排查。\n let url: string;\n if (isDev) {\n url = `${clientBasePath}/static/${rel}`;\n } else {\n const cdnPrefix = (process.env.STATIC_ASSETS_BASE_URL ?? '').replace(/\\/+$/, '');\n if (!cdnPrefix) {\n console.warn(\n `[miaoda-static-assets] STATIC_ASSETS_BASE_URL is not set; \"${rel}\" will resolve to a relative URL. ` +\n `Did you forget to inject MIAODA_STATIC_CDN_PREFIX in build.sh?`\n );\n }\n url = cdnPrefix ? `${cdnPrefix}/${rel}` : `/${rel}`;\n }\n return `export default ${JSON.stringify(url)};`;\n },\n\n transformIndexHtml() {\n if (isDev) return; // dev 直接内联,不需要 window.__STATIC_JSON__\n const data = getJson();\n if (Object.keys(data).length === 0) return;\n const tags: HtmlTagDescriptor[] = [\n {\n tag: 'script',\n children: `window.__STATIC_JSON__ = ${JSON.stringify(data)};`,\n injectTo: 'head-prepend',\n },\n ];\n return { html: '', tags };\n },\n\n configureServer(server: ViteDevServer) {\n if (!fs.existsSync(staticDir)) return;\n\n const watcher = server.watcher;\n watcher.add(staticDir);\n\n const handleChange = (changedPath: string) => {\n if (!changedPath.startsWith(staticDir)) return;\n const rel = path.relative(staticDir, changedPath);\n if (rel.endsWith('.json')) {\n // JSON 变了:invalidate 虚拟模块 + full-reload\n const moduleId = VIRTUAL_PREFIX + rel;\n const mod = server.environments.client.moduleGraph.getModuleById(moduleId);\n if (mod) server.environments.client.moduleGraph.invalidateModule(mod);\n server.hot.send({ type: 'custom', event: 'static-json-update', data: { path: rel } });\n server.hot.send({ type: 'full-reload', path: '*' });\n } else {\n server.hot.send({ type: 'custom', event: 'static-asset-update', data: { path: rel } });\n }\n };\n\n watcher.on('change', handleChange);\n watcher.on('add', handleChange);\n watcher.on('unlink', (changedPath: string) => {\n if (!changedPath.startsWith(staticDir)) return;\n if (changedPath.endsWith('.json')) {\n const rel = path.relative(staticDir, changedPath);\n const moduleId = VIRTUAL_PREFIX + rel;\n const mod = server.environments.client.moduleGraph.getModuleById(moduleId);\n if (mod) server.environments.client.moduleGraph.invalidateModule(mod);\n }\n server.hot.send({ type: 'full-reload', path: '*' });\n });\n\n // dev 下直接 serve `${clientBasePath}/static/...` 路径\n server.middlewares.use((req, res, next) => {\n const staticPrefix = `${clientBasePath}/static/`;\n const url = req.url || '';\n if (!url.startsWith(staticPrefix)) return next();\n\n const rawRel = url.slice(staticPrefix.length).split('?')[0];\n let rel: string;\n try {\n rel = decodeURIComponent(rawRel);\n } catch {\n res.statusCode = 400;\n res.end('Bad Request');\n return;\n }\n const filePath = path.join(staticDir, rel);\n\n // 防 path traversal\n const normalized = path.normalize(filePath);\n if (!normalized.startsWith(staticDir)) {\n res.statusCode = 403;\n res.end('Forbidden');\n return;\n }\n if (!fs.existsSync(filePath)) {\n res.statusCode = 404;\n res.end('Not Found');\n return;\n }\n const stat = fs.statSync(filePath);\n if (stat.isDirectory()) {\n res.statusCode = 403;\n res.end('Forbidden');\n return;\n }\n\n const ext = path.extname(filePath).toLowerCase();\n res.setHeader('Content-Type', MIME[ext] || 'application/octet-stream');\n res.setHeader('Cache-Control', 'no-cache');\n fs.createReadStream(filePath).pipe(res);\n });\n },\n\n // closeBundle 拷贝 shared/static 的逻辑已删除——build.sh 用 rsync 直接拷到\n // dist/output_static/(部署侧识别的目录),plugin 之前拷到 dist/shared/static\n // 是死代码、没人读,而且没排除 .ts/.tsx 还可能误传脚本文件。\n };\n}\n\nexport default staticAssetsPlugin;\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Plugin } from 'vite';\n\nconst VIRTUAL_ID = 'virtual:capabilities';\nconst RESOLVED = '\\0' + VIRTUAL_ID;\n\n// jsPage 约定的 capability 目录(老 fullstack 路径 `server/capabilities/` 不兼容)\nconst DEFAULT_DIRS = ['shared/capabilities'] as const;\n\nexport interface CapabilitiesBundlePluginOptions {\n /** 覆盖扫描目录(相对项目根)。不传时按默认目录列表依次扫描。 */\n dir?: string;\n}\n\n/**\n * 把业务工程 `<dir>/*.json` 的 capability 配置打成 `virtual:capabilities` 虚拟模块。\n *\n * `@lark-apaas/client-capability` SDK(被 client-toolkit-lite 内联使用)会\n * `import map from 'virtual:capabilities'` 取这个 map。SDK 在 dev 预览 / 沙箱\n * 加载流程中依赖这个模块存在,所以即使 capabilities 目录为空,也必须把模块\n * 注册成解析成功(空 map),否则 rolldown 在 build 时直接 fail。\n *\n * 同时通过 `optimizeDeps.esbuildOptions.plugins` 在 depOptimizer 那条路径上\n * 也提供解析——因为 client-toolkit-lite 是 pre-bundle 进来的,pre-bundle 的\n * esbuild 不会经过 Vite 主 pipeline 的 plugin 链。\n *\n * V1 限制:dev 期更改 capability JSON 后,pre-bundle 产物里的 map 是启动时快照,\n * 不会自动刷新;新增 / 修改 capability 后需要重启 dev server。\n */\nexport function capabilitiesBundlePlugin(options: CapabilitiesBundlePluginOptions = {}): Plugin {\n let rootDir = process.cwd();\n\n function listDirs(): string[] {\n if (options.dir) return [path.resolve(rootDir, options.dir)];\n return DEFAULT_DIRS.map((d) => path.resolve(rootDir, d));\n }\n\n function loadMap(): Record<string, unknown> {\n const map: Record<string, unknown> = {};\n for (const abs of listDirs()) {\n if (!fs.existsSync(abs)) continue;\n for (const f of fs.readdirSync(abs)) {\n if (!f.endsWith('.json')) continue;\n try {\n const cfg = JSON.parse(fs.readFileSync(path.join(abs, f), 'utf-8'));\n if (cfg?.id) map[cfg.id] = cfg;\n } catch (e) {\n console.warn(\n `[miaoda-capabilities] skip invalid json: ${path.join(abs, f)}: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n }\n }\n }\n return map;\n }\n\n return {\n name: 'miaoda-capabilities-bundle',\n\n configResolved(config) {\n rootDir = config.root;\n },\n\n // 同时通过 depOptimizer 的 Rolldown 注入解析,让 client-toolkit-lite 这种\n // pre-bundle 进来的依赖也能把 `import 'virtual:capabilities'` 解掉。\n // Vite 8 用 Rolldown 替换了 esbuild 做 depOptimize,所以走 rolldownOptions.plugins。\n config() {\n return {\n optimizeDeps: {\n rolldownOptions: {\n plugins: [\n {\n name: 'miaoda-capabilities-rolldown',\n resolveId(source: string) {\n if (source === VIRTUAL_ID) return RESOLVED;\n return null;\n },\n load(id: string) {\n if (id !== RESOLVED) return null;\n return `export default ${JSON.stringify(loadMap())};`;\n },\n },\n ],\n },\n },\n };\n },\n\n resolveId(id) {\n if (id === VIRTUAL_ID) return RESOLVED;\n return null;\n },\n\n load(id) {\n if (id !== RESOLVED) return null;\n return `export default ${JSON.stringify(loadMap())};`;\n },\n\n configureServer(server) {\n for (const abs of listDirs()) {\n if (fs.existsSync(abs)) server.watcher.add(abs);\n }\n const watching = listDirs();\n const handle = (file: string) => {\n if (!file.endsWith('.json')) return;\n if (!watching.some((d) => file.startsWith(d))) return;\n const mod = server.moduleGraph.getModuleById(RESOLVED);\n if (mod) server.moduleGraph.invalidateModule(mod);\n server.ws.send({ type: 'full-reload', path: '*' });\n };\n server.watcher.on('add', handle);\n server.watcher.on('change', handle);\n server.watcher.on('unlink', handle);\n },\n };\n}\n\nexport default capabilitiesBundlePlugin;\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Plugin, HtmlTagDescriptor, ViteDevServer } from 'vite';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst OVERLAY_PATH = '/@error-overlay.js';\n\nexport interface ErrorOverlayPluginOptions {\n /** Whether to enable the error overlay. Default true. */\n enabled?: boolean;\n /** Client base path prefix. Default ''. */\n clientBasePath?: string;\n}\n\n/**\n * 解析 overlay 客户端脚本路径。\n *\n * 包发布后目录结构:\n * dist/index.js ← 该文件运行时位置\n * src/overlay/*.js ← 静态资源(package.json files 字段包含)\n *\n * 开发时(vitest 之类直接跑 src):__dirname 是 src/plugins/,往上一级 → src/overlay。\n */\nfunction resolveClientScriptPath(): string | null {\n const candidates = [\n path.resolve(__dirname, '../src/overlay/vite-client.js'), // dist 运行时\n path.resolve(__dirname, '../overlay/vite-client.js'), // src/plugins 运行时\n ];\n return candidates.find((p) => fs.existsSync(p)) ?? null;\n}\n\nfunction processClientScript(clientBasePath: string): string {\n const scriptPath = resolveClientScriptPath();\n if (!scriptPath) return '// error-overlay client script not found';\n\n let code = fs.readFileSync(scriptPath, 'utf-8');\n\n // 客户端脚本里被替换的几个变量(与原 preset 行为对齐)\n const env: Record<string, string> = {\n 'process.env.FORCE_FRAMEWORK_DOMAIN_MAIN': JSON.stringify(\n process.env.FORCE_FRAMEWORK_DOMAIN_MAIN ?? ''\n ),\n 'process.env.CLIENT_BASE_PATH': JSON.stringify(clientBasePath),\n };\n for (const [k, v] of Object.entries(env)) {\n code = code.replace(new RegExp(k.replace(/\\./g, '\\\\.'), 'g'), v);\n }\n return code;\n}\n\n/**\n * 自定义 HMR error overlay。\n *\n * - 关掉 Vite 原生 overlay(`server.hmr.overlay = false`)\n * - dev middleware 暴露 `/@error-overlay.js`(按 clientBasePath 加前缀)\n * - HTML head 注入 `<script type=\"module\" src=\"...\">`\n *\n * 只在 dev 期生效;build 时整个 `configureServer` / `transformIndexHtml` 分支不触发。\n */\nexport function errorOverlayPlugin(options: ErrorOverlayPluginOptions = {}): Plugin {\n const { enabled = true, clientBasePath = '' } = options;\n const overlayPath = clientBasePath + OVERLAY_PATH;\n\n return {\n name: 'miaoda-error-overlay',\n enforce: 'pre',\n\n // 关掉 Vite 原生 overlay\n config(config) {\n if (!enabled) return;\n return {\n server: {\n ...config.server,\n hmr:\n config.server?.hmr === false\n ? false\n : {\n ...(typeof config.server?.hmr === 'object' ? config.server.hmr : {}),\n overlay: false,\n },\n },\n };\n },\n\n configureServer(server: ViteDevServer) {\n if (!enabled) return;\n server.middlewares.use((req, res, next) => {\n if (req.url !== overlayPath) return next();\n try {\n const code = processClientScript(clientBasePath);\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(code);\n } catch (e) {\n console.error('[miaoda-error-overlay] serve failed:', e);\n res.statusCode = 500;\n res.end(`// error: ${e instanceof Error ? e.message : String(e)}`);\n }\n });\n },\n\n transformIndexHtml(html: string) {\n if (!enabled) return html;\n const tags: HtmlTagDescriptor[] = [\n {\n tag: 'script',\n attrs: { type: 'module', src: overlayPath },\n injectTo: 'head',\n },\n ];\n return { html, tags };\n },\n };\n}\n\nexport default errorOverlayPlugin;\n","import * as fs from 'node:fs';\nimport type { Plugin, ViteDevServer, HotUpdateOptions } from 'vite';\n\nconst VALID_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx', '.css', '.json', '.html'];\n\n/**\n * HMR 计时插件(Vite 8+)。\n *\n * 监听文件变更记录起始时间,在 `hotUpdate` 钩子里算出耗时 + 文件数 + 累计大小,\n * 通过 `server.hot.send({ type: 'custom', event: 'hmr-timing' })` 广播给浏览器;\n * 浏览器侧由 inspector / dev panel 收消息展示。\n *\n * dev 期专用;build 完全不挂 hook。\n */\nexport function hmrTimingPlugin(): Plugin {\n let startTime = 0;\n const changedFiles = new Set<string>();\n let server: ViteDevServer | null = null;\n\n return {\n name: 'miaoda-hmr-timing',\n\n configureServer(devServer: ViteDevServer) {\n server = devServer;\n server.watcher.on('change', (file) => {\n startTime = Date.now();\n changedFiles.add(file);\n });\n },\n\n hotUpdate(_ctx: HotUpdateOptions) {\n if (!server || changedFiles.size === 0) return;\n\n const duration = Date.now() - startTime;\n const cwd = process.cwd();\n\n const validFiles = [...changedFiles]\n .map((f) => f.replace(cwd, '').replace(/\\\\/g, '/'))\n .filter((p) => {\n if (!p) return false;\n if (p.includes('/node_modules/')) return false;\n return VALID_EXTENSIONS.some((ext) => p.toLowerCase().endsWith(ext));\n });\n\n const totalSize = validFiles.reduce((sum, p) => {\n try {\n return sum + fs.statSync(cwd + p).size;\n } catch {\n return sum;\n }\n }, 0);\n\n server.hot.send({\n type: 'custom',\n event: 'hmr-timing',\n data: { duration, fileCount: validFiles.length, fileTotalSize: totalSize },\n });\n\n changedFiles.clear();\n },\n };\n}\n\nexport default hmrTimingPlugin;\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Plugin, HtmlTagDescriptor } from 'vite';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst CLIENT_RUNTIME_PATH = '/@ws-watchdog.js';\n\n/**\n * 检测沙箱代理链路下的 WebSocket 僵尸连接。\n *\n * 客户端 5s ping 一次(通过 vite hot.send),连续 2 次拿不到 pong 判死,\n * 向 parent window 发 `postMessage({ type: 'disconnected' })` 通知沙箱外壳。\n *\n * 仅 dev 期生效(`apply: 'serve'`);本地裸 dev 也开,不会有副作用——\n * parent 不是沙箱时 postMessage 无消费者,自然丢弃。\n */\nexport interface WsWatchdogPluginOptions {\n pingEvent?: string;\n pongEvent?: string;\n /**\n * 客户端 base path(如 `/app/app_xxx`)。沙箱网关把完整路径透传给 Vite,\n * middleware 匹配和注入的 `<script src>` 都必须带 base;空串退化到裸路径。\n */\n clientBasePath?: string;\n}\n\nfunction resolveClientRuntimePath(): string | null {\n const candidates = [\n path.resolve(__dirname, '../src/runtime/ws-watchdog-client.mjs'), // dist 运行时\n path.resolve(__dirname, '../runtime/ws-watchdog-client.mjs'), // src/plugins 运行时\n ];\n return candidates.find((p) => fs.existsSync(p)) ?? null;\n}\n\nexport function wsWatchdogPlugin(options: WsWatchdogPluginOptions = {}): Plugin {\n const {\n pingEvent = 'ws-watchdog:ping',\n pongEvent = 'ws-watchdog:pong',\n clientBasePath = '',\n } = options;\n const watchdogPath = clientBasePath + CLIENT_RUNTIME_PATH;\n\n return {\n name: 'miaoda-ws-watchdog',\n apply: 'serve',\n\n configureServer(server) {\n server.ws.on(pingEvent, (data: { t?: number } | undefined, client) => {\n if (typeof data?.t !== 'number') return;\n client.send(pongEvent, { echo: data.t });\n });\n\n // 直出 plain .mjs,跳过 server.transformRequest;no-cache 让升降级即时生效\n server.middlewares.use((req, res, next) => {\n if (req.url !== watchdogPath) return next();\n const clientPath = resolveClientRuntimePath();\n if (!clientPath) {\n res.statusCode = 500;\n res.end('// ws-watchdog client not found');\n return;\n }\n try {\n let code = fs.readFileSync(clientPath, 'utf-8');\n const env: Record<string, string> = {\n 'process.env.FORCE_FRAMEWORK_DOMAIN_MAIN': JSON.stringify(\n process.env.FORCE_FRAMEWORK_DOMAIN_MAIN ?? ''\n ),\n 'process.env.CLIENT_BASE_PATH': JSON.stringify(clientBasePath),\n };\n for (const [k, v] of Object.entries(env)) {\n code = code.replace(new RegExp(k.replace(/\\./g, '\\\\.'), 'g'), v);\n }\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(code);\n } catch (e) {\n console.error('[miaoda-ws-watchdog] serve failed:', e);\n res.statusCode = 500;\n res.end(`// error: ${e instanceof Error ? e.message : String(e)}`);\n }\n });\n },\n\n transformIndexHtml() {\n const tags: HtmlTagDescriptor[] = [\n {\n tag: 'script',\n attrs: { type: 'module', src: watchdogPath },\n // head-prepend:尽早注入,避免业务代码先和外壳完成握手才出 watchdog\n injectTo: 'head-prepend',\n },\n ];\n return tags;\n },\n };\n}\n\nexport default wsWatchdogPlugin;\n","import type { Plugin, ViteDevServer } from 'vite';\n\n/**\n * 给妙搭沙箱外壳提供统一的 health endpoint。\n *\n * 协议(飞书文档 - 妙搭应用 Health Check 接口规范):\n * - HTTP connection refused / timeout → dev server 没起来 → 外壳重启沙箱\n * - 200 + { ready: true } → 应用已就绪\n * - 200 + { ready: false } → 还在启动,按 error 描述判断重试\n *\n * 不归本接口管:\n * - vite compile error / runtime error / 资源加载失败 → 浏览器侧自己上报\n */\nexport interface HealthMiddlewarePluginOptions {\n /** Health endpoint 路径,默认 `/dev/health`。 */\n endpoint?: string;\n}\n\nexport function healthMiddlewarePlugin(options: HealthMiddlewarePluginOptions = {}): Plugin {\n const endpoint = options.endpoint ?? '/dev/health';\n let viteReady = false;\n\n return {\n name: 'miaoda-health',\n apply: 'serve',\n\n configureServer(server: ViteDevServer) {\n const httpServer = server.httpServer;\n // 三种状态:\n // - middleware 模式(无 httpServer) → 认为已就绪\n // - httpServer.listening 已 true → 已就绪\n // - 否则注册一次 listening 回调\n if (!httpServer || httpServer.listening) {\n viteReady = true;\n } else {\n httpServer.once('listening', () => {\n viteReady = true;\n });\n }\n\n server.middlewares.use(endpoint, (req, res, next) => {\n if (req.method && req.method !== 'GET') return next();\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Cache-Control', 'no-store');\n res.statusCode = 200;\n res.end(JSON.stringify({ ready: viteReady }));\n });\n },\n };\n}\n\nexport default healthMiddlewarePlugin;\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { IncomingMessage } from 'node:http';\nimport type { HtmlTagDescriptor, Plugin } from 'vite';\n\n/**\n * 在 HTML head 注入 inline script,把启动期上下文挂到 `window`。\n *\n * **dev 期完全走 server 渲染**:在 `configureServer` 中间件里解析 incoming request\n * 的 cookie / host / `x-larkgw-suda-webuser` header,用 `AsyncLocalStorage` 绑到当前\n * 异步链;`transformIndexHtml` 钩子读出后**全部拼成字面量**注入。\n *\n * **prod / 本地裸 dev 无 request 上下文时**走 IIFE fallback:\n * - `csrfToken` 从 `document.cookie` 读\n * - `ENVIRONMENT` 从 `location.hostname` 推\n * - `userId / tenantId / userName` 空字符串\n *\n * 这套设计针对纯前端 jsPage 模板:dev 期沙箱网关已经把 `x-larkgw-suda-webuser`\n * 透传给本地 devserver,于是 server 端有完整 user 上下文;prod 由业务侧\n * `useCurrentUserProfile` 等 hook 异步 fetch 兜底。\n */\n\nconst SUDA_HEADER = 'x-larkgw-suda-webuser';\n\ninterface SudaWebUser {\n user_id?: string;\n tenant_id?: number;\n app_id?: string;\n user_name?: Record<string, string>;\n env?: 'preview' | 'runtime';\n}\n\ninterface RequestRenderContext {\n userId: string;\n tenantId: number | string;\n userName: string;\n csrfToken: string;\n environment: 'staging' | 'gray' | 'online';\n}\n\nconst requestContext = new AsyncLocalStorage<RequestRenderContext>();\n\n// ───────────── header / cookie / host 解析 helpers ─────────────\n\nfunction parseSudaWebUser(header: string | string[] | undefined): SudaWebUser | null {\n if (typeof header !== 'string' || !header) return null;\n try {\n return JSON.parse(decodeURIComponent(header)) as SudaWebUser;\n } catch {\n return null;\n }\n}\n\nfunction parseCsrfToken(cookieHeader: string | undefined): string {\n if (!cookieHeader) return '';\n const m = cookieHeader.match(/(?:^|;\\s*)suda-csrf-token=([^;]+)/);\n return m ? decodeURIComponent(m[1]) : '';\n}\n\nfunction deriveEnvironment(host: string | undefined): 'staging' | 'gray' | 'online' {\n if (!host) return 'online';\n if (host.includes('boe')) return 'staging';\n if (host.includes('feishu-pre') || host.includes('-pre.')) return 'gray';\n return 'online';\n}\n\n/** 从 incoming request 抽出全部 server 端能拿到的 view-context 字段 */\nexport function buildRenderContext(req: IncomingMessage): RequestRenderContext {\n const user = parseSudaWebUser(req.headers[SUDA_HEADER]);\n return {\n userId: user?.user_id ?? '',\n tenantId: user?.tenant_id ?? '',\n userName: user?.user_name?.zh_cn ?? '',\n csrfToken: parseCsrfToken(req.headers.cookie),\n environment: deriveEnvironment(req.headers.host),\n };\n}\n\n// ───────────── inline script 构造 ─────────────\n\nexport interface ViewContextPluginOptions {\n /**\n * 显式传入的 appId override。preset 已经从 `CLIENT_BASE_PATH=/app/<appId>`\n * 提取,设置后 inline script 直接拼真值字面量。未设置则走 IIFE 从 URL\n * 解析(prod / 部分本地 dev URL 没 base path 时用)。\n */\n appId?: string;\n}\n\nfunction appIdExpr(appId: string | undefined): string {\n if (appId) return JSON.stringify(appId);\n return `(function () {\n var p = location.pathname.match(/\\\\/app\\\\/(app_[a-z0-9]+)/i);\n if (p) return p[1];\n var h = location.hostname.match(/app_[a-z0-9]+/i);\n return h ? h[0] : '';\n })()`;\n}\n\n/** 有 request context(dev 沙箱 / dev 本地):全字面量 */\nfunction buildScriptFromRequest(\n options: ViewContextPluginOptions,\n ctx: RequestRenderContext\n): string {\n return `\n window.appId = ${appIdExpr(options.appId)};\n window.userId = ${JSON.stringify(ctx.userId)};\n window.tenantId = ${JSON.stringify(ctx.tenantId)};\n window.userName = ${JSON.stringify(ctx.userName)};\n window.csrfToken = ${JSON.stringify(ctx.csrfToken)};\n window.ENVIRONMENT = ${JSON.stringify(ctx.environment)};\n `;\n}\n\n/** 无 request context(prod build):IIFE fallback */\nfunction buildScriptFallback(options: ViewContextPluginOptions): string {\n return `\n window.appId = ${appIdExpr(options.appId)};\n window.userId = '';\n window.tenantId = '';\n window.userName = '';\n window.csrfToken = (function () {\n var m = document.cookie.match(/(?:^|;\\\\s*)suda-csrf-token=([^;]+)/);\n return m ? decodeURIComponent(m[1]) : '';\n })();\n window.ENVIRONMENT = (function () {\n var h = location.hostname;\n if (h.indexOf('boe') !== -1) return 'staging';\n if (h.indexOf('feishu-pre') !== -1 || h.indexOf('-pre.') !== -1) return 'gray';\n return 'online';\n })();\n `;\n}\n\nexport function viewContextPlugin(options: ViewContextPluginOptions = {}): Plugin {\n return {\n name: 'miaoda-view-context',\n\n /**\n * dev 期前置 middleware:每个请求都把 render context 绑到 ALS。\n * 后续 `transformIndexHtml` 在同一异步链里 `getStore()` 读出。\n */\n configureServer(server) {\n server.middlewares.use((req, _res, next) => {\n const ctx = buildRenderContext(req);\n requestContext.run(ctx, () => next());\n });\n },\n\n transformIndexHtml() {\n const ctx = requestContext.getStore();\n const children = ctx\n ? buildScriptFromRequest(options, ctx)\n : buildScriptFallback(options);\n const tags: HtmlTagDescriptor[] = [\n {\n tag: 'script',\n children,\n // head-prepend:必须在业务代码 / runtime 之前注入,保证业务可同步读 window 全局\n injectTo: 'head-prepend',\n },\n ];\n return tags;\n },\n };\n}\n\nexport default viewContextPlugin;\n","import * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Plugin } from 'vite';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * 把业务工程里 `import 'clsx'` / `import 'echarts'` / `import 'echarts-for-react'`\n * 这种裸 import 强制指向 preset 自带的 ESM wrapper(`src/module-alias/*.mjs`)。\n *\n * 解决的问题:第三方扩展(如 `echarts-wordcloud`)自带独立 echarts 副本时,\n * 业务代码和扩展跑在两份 echarts 实例上,wordcloud 注册不到主实例 → 渲染丢失。\n * Wrapper 强制所有 echarts 指针指向 preset 自带版本,全栈共用一份实例。\n */\nexport function moduleAliasPlugin(): Plugin {\n // 编译后 __dirname = dist/,资产在 src/module-alias/;src 直跑(vitest)时 __dirname = src/plugins/\n const aliasDir = [\n path.resolve(__dirname, '../src/module-alias'),\n path.resolve(__dirname, '../module-alias'),\n ];\n\n function resolveAlias(name: string): string | null {\n for (const dir of aliasDir) {\n const p = path.join(dir, `${name}.mjs`);\n // 不在这里做 fs.existsSync 检查;假设包发布完整即可。Vite 后续 load 阶段\n // 找不到会自然报错。\n return p;\n }\n return null;\n }\n\n return {\n name: 'miaoda-module-alias',\n enforce: 'pre',\n\n resolveId: {\n filter: { id: /^(clsx|echarts|echarts-for-react)$/ },\n handler(source: string, importer: string | undefined) {\n // 别把 wrapper 自己内部的 import 又拐回 wrapper(死循环)\n if (importer && importer.includes('module-alias')) return null;\n return resolveAlias(source);\n },\n },\n };\n}\n\nexport default moduleAliasPlugin;\n","import type { Plugin } from 'vite';\n\n/**\n * 向 `index.html` 注入 / 改写 OG meta、title、description meta、favicon。\n *\n * 所有值用 HBS 占位符(`{{appName}}` 等),由部署运行时(vefaas)替换为\n * platform API 拿到的真值;jsPage 流程下浏览器侧不直接消费这些 meta。\n *\n * 既存 tag 会被原地改写(保留其它属性),缺失则插入到 `</head>` 之前。\n */\nexport interface OgMetaPluginOptions {\n customTags?: Array<{ property: string; placeholder: string }>;\n titlePlaceholder?: string;\n descriptionPlaceholder?: string;\n faviconPlaceholder?: string;\n}\n\nconst DEFAULT_TAGS = [\n { property: 'og:title', placeholder: '{{appName}}' },\n { property: 'og:description', placeholder: '{{appDescription}}' },\n { property: 'og:image', placeholder: '{{appAvatar}}' },\n];\n\nexport function ogMetaPlugin(options: OgMetaPluginOptions = {}): Plugin {\n const {\n customTags,\n titlePlaceholder = '{{appName}}',\n descriptionPlaceholder = '{{appDescription}}',\n faviconPlaceholder = '{{appAvatar}}',\n } = options;\n const tags = customTags || DEFAULT_TAGS;\n\n return {\n name: 'miaoda-og-meta',\n\n transformIndexHtml(html) {\n let result = html;\n\n // 1. OG meta tags\n for (const { property, placeholder } of tags) {\n const esc = property.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const exists = new RegExp(\n `<meta\\\\s+[^>]*property=[\"']?${esc}[\"']?[^>]*>`,\n 'i'\n ).test(result);\n if (exists) {\n result = result.replace(\n new RegExp(\n `(<meta\\\\s+[^>]*property=[\"']?${esc}[\"']?[^>]*content=)[\"'][^\"']*[\"']([^>]*>)`,\n 'gi'\n ),\n `$1\"${placeholder}\"$2`\n );\n } else {\n result = result.replace(\n '</head>',\n `\\n <meta property=\"${property}\" content=\"${placeholder}\">\\n </head>`\n );\n }\n }\n\n // 2. <title>\n if (/<title>[^<]*<\\/title>/i.test(result)) {\n result = result.replace(/<title>[^<]*<\\/title>/gi, `<title>${titlePlaceholder}</title>`);\n } else {\n result = result.replace('</head>', `\\n <title>${titlePlaceholder}</title>\\n </head>`);\n }\n\n // 2.1 <meta name=\"description\">\n const descRe = /<meta\\b[^>]*\\bname=[\"']description[\"'][^>]*>/i;\n if (descRe.test(result)) {\n result = result.replace(\n /<meta\\b[^>]*\\bname=[\"']description[\"'][^>]*>/gi,\n (tag) => {\n if (/\\bcontent=/.test(tag)) {\n return tag.replace(\n /\\bcontent=([\"'])([\\s\\S]*?)\\1/i,\n `content=\"${descriptionPlaceholder}\"`\n );\n }\n return tag.replace(/>$/, ` content=\"${descriptionPlaceholder}\">`);\n }\n );\n } else {\n result = result.replace(\n '</head>',\n `\\n <meta name=\"description\" content=\"${descriptionPlaceholder}\">\\n </head>`\n );\n }\n\n // 3. <link rel=\"icon\">\n const iconRe = /<link\\s+[^>]*rel=[\"']?(?:icon|shortcut icon)[\"']?[^>]*>/i;\n if (iconRe.test(result)) {\n result = result.replace(\n /(<link\\s+[^>]*rel=[\"']?(?:icon|shortcut icon)[\"']?[^>]*href=)[\"'][^\"']*[\"']([^>]*>)/gi,\n `$1\"${faviconPlaceholder}\"$2`\n );\n } else {\n result = result.replace(\n '</head>',\n `\\n <link rel=\"icon\" href=\"${faviconPlaceholder}\">\\n </head>`\n );\n }\n\n return result;\n },\n };\n}\n\nexport default ogMetaPlugin;\n","import type { Plugin } from 'vite';\n\n/**\n * 编译时把 `fonts.googleapis.com` / `fonts.gstatic.com` 全量改写到妙搭字体代理,\n * 屏蔽 Google Fonts 在内网 / 部分客户端不可达导致的白屏。\n *\n * - 命中文件类型:html / css / scss / less / styl / js / ts / tsx / vue / svelte 等\n * - URL pathname 保持与 Google Fonts 一致(`/css`、`/css2?family=...&wght=...`),\n * 任意模型输出形式都能被代理;只换域名\n * - 关闭:`{ disabled: true }` 或环境变量 `MIAODA_FONTS_MIRROR_OFF=1`\n */\nconst DEFAULT_MIRROR = 'https://miaoda.feishu.cn/fonts';\nconst GOOGLE_FONTS_RE = /https?:\\/\\/fonts\\.(googleapis|gstatic)\\.com/g;\nconst HAS_GOOGLE_FONTS = /fonts\\.(googleapis|gstatic)\\.com/;\nconst TRANSFORM_EXT = /\\.(html|css|scss|sass|less|styl|js|jsx|ts|tsx|mjs|cjs|vue|svelte)(\\?|$)/;\n\nexport interface FontsMirrorPluginOptions {\n /** Mirror 完整基址,默认 `https://miaoda.feishu.cn/fonts` */\n mirror?: string;\n /** 关闭(调试时兜底) */\n disabled?: boolean;\n /** 命中时打 warning(便于找出源码里的旧引用) */\n warnOnMatch?: boolean;\n /** 排除 id 子串或正则 */\n exclude?: (string | RegExp)[];\n}\n\nexport function fontsMirrorPlugin(options: FontsMirrorPluginOptions = {}): Plugin | false {\n const envDisabled = process.env.MIAODA_FONTS_MIRROR_OFF === '1';\n if (options.disabled || envDisabled) return false;\n\n const mirror = options.mirror ?? DEFAULT_MIRROR;\n const warn = options.warnOnMatch ?? false;\n const exclude = options.exclude ?? [];\n\n const shouldExclude = (id: string) =>\n exclude.some((p) => (typeof p === 'string' ? id.includes(p) : p.test(id)));\n\n const stats = { files: 0, occurrences: 0 };\n\n return {\n name: 'miaoda-fonts-mirror',\n enforce: 'pre',\n\n buildStart() {\n stats.files = 0;\n stats.occurrences = 0;\n },\n\n transformIndexHtml(html: string) {\n if (!HAS_GOOGLE_FONTS.test(html)) return html;\n const matches = html.match(GOOGLE_FONTS_RE);\n const replaced = html.replace(GOOGLE_FONTS_RE, mirror);\n stats.files += 1;\n stats.occurrences += matches?.length ?? 0;\n if (warn) {\n console.warn(`[miaoda-fonts-mirror] rewrote ${matches?.length ?? 0} occurrence(s) in index.html`);\n }\n return replaced;\n },\n\n transform(code: string, id: string) {\n if (!TRANSFORM_EXT.test(id)) return null;\n if (shouldExclude(id)) return null;\n if (!HAS_GOOGLE_FONTS.test(code)) return null;\n const matches = code.match(GOOGLE_FONTS_RE);\n if (!matches) return null;\n stats.files += 1;\n stats.occurrences += matches.length;\n if (warn) {\n console.warn(`[miaoda-fonts-mirror] rewrote ${matches.length} occurrence(s) in ${id}`);\n }\n return { code: code.replace(GOOGLE_FONTS_RE, mirror), map: null };\n },\n\n closeBundle() {\n if (stats.files > 0) {\n console.log(\n `[miaoda-fonts-mirror] ✓ rewrote ${stats.occurrences} occurrence(s) across ${stats.files} file(s) → ${mirror}`\n );\n }\n },\n };\n}\n\nexport default fontsMirrorPlugin;\n","import * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Plugin, ResolvedConfig, Rollup } from 'vite';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\ntype OutputBundle = Rollup.OutputBundle;\ntype OutputAsset = Rollup.OutputAsset;\n\n/**\n * 为旧版浏览器生成独立 `polyfills.js`,HTML 注入 detection 脚本按需加载。\n * 现代浏览器不会请求该文件,零开销。\n *\n * 使用 Vite build API 二次 build 把 `src/polyfills/index.ts` 打成 IIFE bundle。\n * 仅生产构建生效(`apply: 'build'`)。\n */\nexport function polyfillPlugin(): Plugin {\n let config: ResolvedConfig;\n\n return {\n name: 'miaoda-polyfill',\n apply: 'build',\n enforce: 'post',\n\n configResolved(c) {\n config = c;\n },\n\n async generateBundle(_options, bundle: OutputBundle) {\n // 编译后:dist/,资产在 src/polyfills/;src 直跑时:src/plugins/\n const entry = [\n path.resolve(__dirname, '../src/polyfills/index'),\n path.resolve(__dirname, '../polyfills/index'),\n ];\n const { build } = await import('vite');\n\n let polyfillCode = '';\n try {\n const result = await build({\n configFile: false,\n logLevel: 'silent',\n build: {\n write: false,\n lib: {\n entry: entry[0],\n formats: ['iife'],\n name: 'polyfills',\n fileName: 'polyfills',\n },\n minify: true,\n rollupOptions: {\n output: { inlineDynamicImports: true },\n },\n },\n });\n\n const output = Array.isArray(result) ? result[0] : result;\n polyfillCode = 'output' in output ? output.output[0]?.code || '' : '';\n\n this.emitFile({\n type: 'asset',\n fileName: 'polyfills.js',\n source: polyfillCode,\n });\n\n console.log(\n `[miaoda-polyfill] generated polyfills.js (${Math.round(polyfillCode.length / 1024)}KB)`\n );\n } catch (error) {\n console.error('[miaoda-polyfill] build failed:', error);\n return;\n }\n\n // 改写 HTML:head 起始注入按需加载脚本\n const base = config.base || '/';\n const polyfillUrl = `${base}polyfills.js`.replace(/\\/+/g, '/').replace(':/', '://');\n const htmlFiles = Object.keys(bundle).filter((name) => name.endsWith('.html'));\n\n for (const file of htmlFiles) {\n const chunk = bundle[file];\n if (chunk.type !== 'asset') continue;\n\n let htmlContent =\n typeof chunk.source === 'string'\n ? chunk.source\n : Buffer.from(chunk.source).toString('utf-8');\n\n const detection = buildDetectionScript(polyfillUrl);\n htmlContent = htmlContent.replace(/<head([^>]*)>/i, `<head$1>\\n${detection}`);\n (chunk as OutputAsset).source = htmlContent;\n }\n },\n };\n}\n\nfunction buildDetectionScript(polyfillUrl: string): string {\n return `<script>\n(function(){\n var needsPolyfill=(function(){\n try{\n if(typeof crypto===\"undefined\"||typeof crypto.randomUUID!==\"function\")return true;\n if(typeof Object.hasOwn!==\"function\")return true;\n if(typeof[].at!==\"function\")return true;\n if(typeof[].findLast!==\"function\")return true;\n return false;\n }catch(e){return true}\n })();\n if(needsPolyfill){\n document.write('<script src=\"${polyfillUrl}\"><\\\\/script>');\n }\n})();\n</script>`;\n}\n\nexport default polyfillPlugin;\n","import type { Plugin } from 'vite';\n\n/**\n * 抑制 `@vite/client` 在 HMR WS 重连成功后的 `location.reload()`。\n *\n * 背景(沙箱反向代理场景):电脑休眠唤醒后 WS 断连重连。Vite 客户端走\n * `waitForSuccessfulPing()` 用新 TCP 连接握手成功,立刻发 `location.reload()`;\n * 但 reload 用的是浏览器 HTTP/2 连接池里复用的休眠前死连接,\n * 导致 ~18s `ERR_CONNECTION_TIMED_OUT` 白屏。\n *\n * 解:transform 拦截 `vite/dist/client/client.mjs`,直接删掉 reload 那一行。\n * 用户需要新代码时手动刷新。\n *\n * 仅 dev(`apply: 'serve'`)。\n */\nconst RECONNECT_RELOAD_PATTERN =\n /(await waitForSuccessfulPing\\(url\\.href\\);)\\r?\\n(\\s*)location\\.reload\\(\\);/;\n\nexport function viteClientPatchPlugin(): Plugin {\n return {\n name: 'miaoda-vite-client-patch',\n enforce: 'post',\n apply: 'serve',\n\n transform(code, id) {\n if (!id.includes('vite/dist/client/client.mjs')) return;\n\n if (!RECONNECT_RELOAD_PATTERN.test(code)) {\n console.warn(\n '[miaoda-vite-client-patch] reconnect-reload pattern not found in @vite/client. ' +\n 'patch NOT applied — Vite client.mjs may have changed.'\n );\n return;\n }\n\n const patched = code.replace(RECONNECT_RELOAD_PATTERN, (_, pingLine) => pingLine);\n return { code: patched };\n },\n };\n}\n\nexport default viteClientPatchPlugin;\n","import type { Plugin, HtmlTagDescriptor } from 'vite';\n\n/**\n * 注入 Slardar SDK + Performance + Tea 监控埋点。\n *\n * 三段都通过 `<script>` 注入到 head-prepend:\n * 1. Slardar SDK loader(onload 后读 `window.tenantId/appId/userId/ENVIRONMENT` 初始化)\n * 2. Performance SDK\n * 3. Tea SDK loader\n *\n * 依赖 viewContextPlugin 提前注入 `window.tenantId/appId/userId/ENVIRONMENT`。\n *\n * head-prepend bucket:Vite 同 bucket 是\"后执行者插更前\"。\n * 数组里 slardar 必须排在 viewContext **之前** —— 这样在 HTML 里 viewContext 出现在\n * slardar 之上,slardar onload 时才能读到 window.tenantId 等真值。\n */\nexport interface SlardarPluginOptions {\n /** Business ID。默认 `apaas_miaoda` */\n bid?: string;\n /** SDK 暴露在 window 上的全局名。默认 `KSlardarWeb` */\n globalName?: string;\n}\n\nfunction buildSlardarScript(bid: string, globalName: string): string {\n return `\n const slardarScript = document.createElement('script');\n slardarScript.src = 'https://lf3-short.ibytedapm.com/slardar/fe/sdk-web/browser.cn.js?bid=${bid}&globalName=${globalName}';\n slardarScript.crossOrigin = 'anonymous';\n slardarScript.onload = function() {\n if (window.${globalName}) {\n window.${globalName}('context.merge', {\n tenantId: window.tenantId ?? '',\n appId: window.appId ?? '',\n });\n window.${globalName}('init', {\n bid: '${bid}',\n env: window.ENVIRONMENT || 'online',\n userId: window.userId ?? '',\n });\n window.${globalName}('start');\n }\n };\n slardarScript.onerror = function() {\n console.warn('Failed to load Slardar script');\n };\n document.head.appendChild(slardarScript);\n `;\n}\n\nfunction buildTeaScript(): string {\n return `\n (function (win, export_obj) {\n win['LogAnalyticsObject'] = export_obj;\n if (!win[export_obj]) {\n function _collect() { _collect.q.push(arguments); }\n _collect.q = _collect.q || [];\n win[export_obj] = _collect;\n }\n win[export_obj].l = +new Date();\n })(window, 'collectEvent');\n\n const teaScript = document.createElement('script');\n teaScript.src = 'https://lf3-cdn-tos.bytescm.com/obj/static/log-sdk/collect/5.1/collect.js';\n teaScript.crossOrigin = 'anonymous';\n teaScript.async = true;\n teaScript.onerror = function() {\n console.warn('Failed to load Tea script');\n };\n document.head.appendChild(teaScript);\n `;\n}\n\nexport function slardarPlugin(options: SlardarPluginOptions = {}): Plugin {\n const { bid = 'apaas_miaoda', globalName = 'KSlardarWeb' } = options;\n\n return {\n name: 'miaoda-slardar',\n\n transformIndexHtml(html) {\n const tags: HtmlTagDescriptor[] = [\n { tag: 'script', children: buildSlardarScript(bid, globalName), injectTo: 'head-prepend' },\n {\n tag: 'script',\n attrs: {\n src: 'https://sf3-scmcdn-cn.feishucdn.com/obj/unpkg/byted/performance/0.1.2/dist/performance.iife.js',\n crossorigin: 'anonymous',\n defer: true,\n },\n injectTo: 'head-prepend',\n },\n { tag: 'script', children: buildTeaScript(), injectTo: 'head-prepend' },\n ];\n return { html, tags };\n },\n };\n}\n\nexport default slardarPlugin;\n","import * as crypto from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { createInterface } from 'node:readline';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { Plugin, ViteDevServer } from 'vite';\n\n/**\n * 客户端日志收集 + 读取 + SSE 流式 endpoint。\n *\n * 写入:\n * - `POST <basePath>/dev/logs/collect` 单条 log(`{ message, ... }`)\n * - `POST <basePath>/dev/logs/collect-batch` 数组批量 log\n *\n * 读取:\n * - `GET <basePath>/dev/logs/files/:fileName?page=1&pageSize=200`\n * 倒序分页读 `<logDir>/<fileName>` 任意文件,防 path traversal,max pageSize 2000\n * - `GET <basePath>/dev/logs/server-logs?limit=100&offset=0&levels=error,warn&sources=client-std`\n * 合并 4 个常见日志文件(server.log / trace.log / server.std.log / client.std.log)\n * 的 entries,按 timestamp desc 排序后分页 + 过滤\n * - `GET <basePath>/dev/logs/server-logs/stream`(SSE)\n * `LogWatcher` 增量监听 4 个文件,新行实时推送\n *\n * jsPage 说明:endpoint 名字带 \"server-\" 是历史遗留(与 `client-toolkit` 写死的路径\n * 兼容,见 `client-toolkit/src/server-log/poller.ts`);实际只监测一个文件\n * `client.std.log`(dev.mjs 写的)。上游另外那 3 个(`server.log`、`trace.log`、\n * `server.std.log`)是 fullstack 后端的产物,jsPage 不产、也没消费者,全部砍掉。\n *\n * 写入路径:`<logDir>/<fileName>`(默认 `./logs/client.log`,由 `LOG_DIR` 环境变量改写)。\n *\n * 移植自上游 `@lark-apaas/devtool-kits` 的 `dev-logs` + `collect-logs` middlewares。\n * 仍然不补的 fullstack-only endpoints:\n * - `/app/trace/:traceId`、`/trace/recent`、`/trace/trigger/*`、`/trace/capability/list`\n * —— 全是 server-side trace.log 的索引接口\n * - `/api-list` —— 从 fullstack server 抓 API route 清单\n * - `/health` —— 重复(本 preset 有独立 `/dev/health`)\n */\nexport interface DevLogsPluginOptions {\n /** 日志写入目录。默认 `process.env.LOG_DIR ?? './logs'`。 */\n logDir?: string;\n /** 日志文件名。默认 `client.log`。 */\n fileName?: string;\n /** Body 大小上限(bytes)。默认 20 MB。 */\n bodyLimit?: number;\n /** 接口基路径前缀(沙箱 base path)。默认空。 */\n basePath?: string;\n}\n\nconst DEFAULT_BODY_LIMIT = 20 * 1024 * 1024;\n\nfunction ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n}\n\nfunction resolveLogFilePath(baseDir: string, fileName: string): string {\n const sanitized = fileName.replace(/\\\\/g, '/');\n const segments = sanitized.split('/').filter(Boolean);\n if (segments.some((seg) => seg === '..')) {\n throw new Error('Invalid log file path');\n }\n const resolved = path.join(baseDir, segments.join('/'));\n const rel = path.relative(baseDir, resolved);\n if (rel.startsWith('..')) {\n throw new Error('Access to the specified log file is denied');\n }\n return resolved;\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n if (!value || !value.trim()) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\nfunction parseLimit(value: string | undefined, def: number, max: number): number {\n if (!value || !value.trim()) return def;\n const n = Number(value);\n if (Number.isFinite(n) && n > 0) return Math.min(Math.floor(n), max);\n return def;\n}\n\ninterface LogPage {\n page: number;\n pageSize: number;\n totalLines: number;\n totalPages: number;\n lines: string[];\n}\n\n// ───────────────────────── parsers + helpers ─────────────────────────\n\ntype LogLevel = 'fatal' | 'error' | 'warn' | 'log' | 'debug' | 'verbose';\n\ninterface LogEntry {\n id: string;\n level: LogLevel;\n timestamp: number;\n message: string;\n context: unknown;\n traceId: string | null;\n userId: string | null;\n appId: string | null;\n tenantId: string | null;\n stack: string | null;\n meta: Record<string, unknown> | null;\n tags: string[];\n}\n\nfunction extractLogLevel(text: string): LogLevel {\n const lower = text.toLowerCase();\n if (lower.includes('fatal') || lower.includes('critical')) return 'fatal';\n if (lower.includes('error') || lower.includes('<e>') || lower.includes('✖')) return 'error';\n if (lower.includes('warn') || lower.includes('<w>') || lower.includes('⚠')) return 'warn';\n if (lower.includes('debug') || lower.includes('<d>')) return 'debug';\n if (lower.includes('verbose') || lower.includes('trace')) return 'verbose';\n return 'log';\n}\n\n/**\n * std 输出日志解析(dev.mjs 的格式):\n * `[2026-05-29 10:00:00] [client] message`\n * 不匹配前缀时整行当 message、level 走文本启发式。\n */\nfunction parseStdLog(line: string, source: string): LogEntry {\n const id = crypto.randomUUID();\n const m = line.match(/^\\[(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})\\] \\[(server|client)\\] (.*)$/);\n if (!m) {\n return {\n id,\n level: 'log',\n timestamp: Date.now(),\n message: line,\n context: null,\n traceId: null,\n userId: null,\n appId: null,\n tenantId: null,\n stack: null,\n meta: null,\n tags: [source],\n };\n }\n const [, timeStr, , content] = m;\n let timestamp = new Date(timeStr.replace(' ', 'T')).getTime();\n if (Number.isNaN(timestamp)) timestamp = Date.now();\n return {\n id,\n level: extractLogLevel(content),\n timestamp,\n message: content,\n context: null,\n traceId: null,\n userId: null,\n appId: null,\n tenantId: null,\n stack: null,\n meta: null,\n tags: [source],\n };\n}\n\n// 监测的日志文件。jsPage 只有一个 client.std.log(dev.mjs 写的),其它 fullstack\n// 后端的文件(server.log / trace.log / server.std.log)这里不监测——上游 LogWatcher\n// 4 个文件的设计是 fullstack 遗留,本 preset 不携带。\nconst LOG_FILES: Array<{\n fileName: string;\n source: string;\n parser: (line: string, source: string) => LogEntry | null;\n}> = [{ fileName: 'client.std.log', source: 'client-std', parser: parseStdLog }];\n\nasync function readLogsBySource(logDir: string, source: string): Promise<LogEntry[]> {\n const config = LOG_FILES.find((c) => c.source === source);\n if (!config) return [];\n const filePath = path.join(logDir, config.fileName);\n if (!fs.existsSync(filePath)) return [];\n\n const out: LogEntry[] = [];\n const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });\n const rl = createInterface({ input: stream, crlfDelay: Infinity });\n try {\n for await (const line of rl) {\n if (!line.trim()) continue;\n try {\n const entry = config.parser(line, source);\n if (entry) out.push(entry);\n } catch {\n /* skip unparseable */\n }\n }\n } finally {\n rl.close();\n stream.close();\n }\n return out;\n}\n\ninterface ServerLogsResult {\n logs: LogEntry[];\n total: number;\n hasMore: boolean;\n}\n\nasync function readServerLogs(\n logDir: string,\n opts: { limit?: number; offset?: number; levels?: string[]; sources?: string[] } = {}\n): Promise<ServerLogsResult | null> {\n const limit = opts.limit ?? 100;\n const offset = opts.offset ?? 0;\n const sources = opts.sources ?? LOG_FILES.map((c) => c.source);\n\n const all: LogEntry[] = [];\n for (const source of sources) {\n try {\n const logs = await readLogsBySource(logDir, source);\n all.push(...logs);\n } catch (e) {\n console.warn(\n `[miaoda-dev-logs] read ${source} failed: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n }\n if (all.length === 0) return null;\n\n let filtered = all;\n if (opts.levels && opts.levels.length > 0) {\n filtered = all.filter((l) => opts.levels!.includes(l.level));\n }\n filtered.sort((a, b) => b.timestamp - a.timestamp);\n return {\n logs: filtered.slice(offset, offset + limit),\n total: filtered.length,\n hasMore: offset + limit < filtered.length,\n };\n}\n\n// ───────────────────────── LogWatcher (SSE) ─────────────────────────\n\ntype LogSubscriber = (entry: LogEntry) => void;\n\nclass LogWatcher {\n private logDir = '';\n private watchers = new Map<string, fs.FSWatcher>();\n private positions = new Map<string, number>();\n private subscribers = new Set<LogSubscriber>();\n private running = false;\n\n start(logDir: string): void {\n if (this.running) return;\n this.logDir = logDir;\n this.running = true;\n for (const cfg of LOG_FILES) this.watchFile(cfg);\n }\n\n stop(): void {\n if (!this.running) return;\n this.running = false;\n for (const w of this.watchers.values()) {\n try {\n w.close();\n } catch {\n /* noop */\n }\n }\n this.watchers.clear();\n this.positions.clear();\n }\n\n onLog(cb: LogSubscriber): () => void {\n this.subscribers.add(cb);\n return () => this.subscribers.delete(cb);\n }\n\n getSubscriberCount(): number {\n return this.subscribers.size;\n }\n\n private watchFile(cfg: (typeof LOG_FILES)[number]): void {\n const filePath = path.join(this.logDir, cfg.fileName);\n if (!fs.existsSync(filePath)) return; // 文件不存在静默 skip(jsPage 常见)\n\n try {\n this.positions.set(cfg.fileName, fs.statSync(filePath).size);\n } catch {\n this.positions.set(cfg.fileName, 0);\n }\n try {\n const watcher = fs.watch(filePath, (event) => {\n if (event === 'change') this.handleChange(cfg);\n });\n watcher.on('error', () => this.restart(cfg));\n this.watchers.set(cfg.fileName, watcher);\n } catch {\n /* noop */\n }\n }\n\n private restart(cfg: (typeof LOG_FILES)[number]): void {\n const existing = this.watchers.get(cfg.fileName);\n if (existing) {\n try {\n existing.close();\n } catch {\n /* noop */\n }\n this.watchers.delete(cfg.fileName);\n }\n setTimeout(() => {\n if (this.running) this.watchFile(cfg);\n }, 1000);\n }\n\n private handleChange(cfg: (typeof LOG_FILES)[number]): void {\n const filePath = path.join(this.logDir, cfg.fileName);\n const last = this.positions.get(cfg.fileName) ?? 0;\n let stats: fs.Stats;\n try {\n stats = fs.statSync(filePath);\n } catch {\n return;\n }\n const cur = stats.size;\n if (cur < last) {\n // 文件被截断,重置 position 再走一次\n this.positions.set(cfg.fileName, 0);\n this.handleChange(cfg);\n return;\n }\n if (cur === last) return;\n\n const buf = Buffer.alloc(cur - last);\n const fd = fs.openSync(filePath, 'r');\n try {\n fs.readSync(fd, buf, 0, cur - last, last);\n } finally {\n fs.closeSync(fd);\n }\n this.positions.set(cfg.fileName, cur);\n\n for (const line of buf.toString('utf-8').split('\\n')) {\n if (!line.trim()) continue;\n try {\n const entry = cfg.parser(line, cfg.source);\n if (entry) this.notify(entry);\n } catch {\n /* skip */\n }\n }\n }\n\n private notify(entry: LogEntry): void {\n for (const sub of this.subscribers) {\n try {\n sub(entry);\n } catch {\n /* skip subscriber errors */\n }\n }\n }\n}\n\nfunction formatSSE(event: string, data: unknown): string {\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\n/**\n * 倒序分页读日志:page=1 返回最新 pageSize 行。\n *\n * 算法移植自上游 `readLogFilePage`:用环形 buffer 缓存最近 `page*pageSize` 行避免\n * 把整个文件读进内存;遍历完后只输出落在第 `page` 页范围内的行。\n */\nasync function readLogFilePage(\n filePath: string,\n page: number,\n pageSize: number\n): Promise<LogPage | null> {\n if (!fs.existsSync(filePath)) return null;\n\n const capacity = page * pageSize;\n const buffer: string[] = [];\n let totalLines = 0;\n\n const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });\n const rl = createInterface({ input: stream, crlfDelay: Infinity });\n try {\n for await (const line of rl) {\n buffer.push(line);\n if (buffer.length > capacity) buffer.shift();\n totalLines += 1;\n }\n } finally {\n rl.close();\n stream.close();\n }\n\n const totalPages = totalLines === 0 ? 0 : Math.ceil(totalLines / pageSize);\n if (buffer.length === 0) return { page, pageSize, totalLines, totalPages, lines: [] };\n\n const startIndex = Math.max(totalLines - page * pageSize, 0);\n const endIndex = Math.max(totalLines - (page - 1) * pageSize, 0);\n const bufferStartIndex = totalLines - buffer.length;\n const lines: string[] = [];\n for (let i = buffer.length - 1; i >= 0; i -= 1) {\n const lineIndex = bufferStartIndex + i;\n if (lineIndex >= startIndex && lineIndex < endIndex) lines.push(buffer[i]);\n }\n return { page, pageSize, totalLines, totalPages, lines: lines.reverse() };\n}\n\nfunction readJsonBody(req: IncomingMessage, limit: number): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let size = 0;\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > limit) {\n reject(new Error(`request body exceeded ${limit} bytes`));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => {\n try {\n const raw = Buffer.concat(chunks).toString('utf-8');\n resolve(raw ? JSON.parse(raw) : null);\n } catch (e) {\n reject(e);\n }\n });\n req.on('error', reject);\n });\n}\n\nfunction writeJson(res: ServerResponse, status: number, body: unknown): void {\n res.statusCode = status;\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Cache-Control', 'no-store');\n res.end(JSON.stringify(body));\n}\n\nexport function devLogsPlugin(options: DevLogsPluginOptions = {}): Plugin {\n const {\n logDir = process.env.LOG_DIR || './logs',\n fileName = 'client.log',\n bodyLimit = DEFAULT_BODY_LIMIT,\n basePath = '',\n } = options;\n\n const absLogDir = path.isAbsolute(logDir) ? logDir : path.join(process.cwd(), logDir);\n const filePath = path.join(absLogDir, fileName);\n\n const collectPath = `${basePath}/dev/logs/collect`;\n const collectBatchPath = `${basePath}/dev/logs/collect-batch`;\n const filesPrefix = `${basePath}/dev/logs/files/`;\n const serverLogsPath = `${basePath}/dev/logs/server-logs`;\n const serverLogsStreamPath = `${basePath}/dev/logs/server-logs/stream`;\n\n function appendOne(entry: Record<string, unknown>): Promise<void> {\n const line = JSON.stringify({ ...entry, server_time: new Date().toISOString() }) + '\\n';\n return fs.promises.appendFile(filePath, line);\n }\n\n function appendMany(entries: Array<Record<string, unknown>>): Promise<void> {\n const ts = new Date().toISOString();\n const lines = entries.map((e) => JSON.stringify({ ...e, server_time: ts }) + '\\n').join('');\n return fs.promises.appendFile(filePath, lines);\n }\n\n return {\n name: 'miaoda-dev-logs',\n apply: 'serve',\n\n configureServer(server: ViteDevServer) {\n ensureDir(absLogDir);\n\n // SSE 复用一份 watcher(首个连接开 watcher、最后一个连接关)\n const watcher = new LogWatcher();\n const sseClients = new Set<ServerResponse>();\n\n server.middlewares.use(async (req, res, next) => {\n const url = req.url?.split('?')[0] ?? '';\n\n // ── SSE:GET /dev/logs/server-logs/stream ───────────────────────────\n // 必须放在 /server-logs 前面:/server-logs/stream 也是 /server-logs 开头\n if (req.method === 'GET' && url === serverLogsStreamPath) {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n // SSE 长连接:禁用 socket timeout\n res.socket?.setTimeout(0);\n\n const clientId = `sse_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n sseClients.add(res);\n if (watcher.getSubscriberCount() === 0) watcher.start(absLogDir);\n\n const sendEvent = (event: string, data: unknown) => {\n try {\n res.write(formatSSE(event, data));\n return true;\n } catch {\n return false;\n }\n };\n const unsubscribe = watcher.onLog((entry) => sendEvent('log', entry));\n sendEvent('connected', { clientId, timestamp: Date.now() });\n\n const heartbeat = setInterval(() => {\n if (!sendEvent('heartbeat', { timestamp: Date.now() })) clearInterval(heartbeat);\n }, 30_000);\n\n const cleanup = () => {\n clearInterval(heartbeat);\n unsubscribe();\n sseClients.delete(res);\n if (watcher.getSubscriberCount() === 0) watcher.stop();\n };\n req.on('close', cleanup);\n req.on('error', cleanup);\n return;\n }\n\n // ── 读取合并日志:GET /dev/logs/server-logs ─────────────────────────\n if (req.method === 'GET' && url === serverLogsPath) {\n const qs = new URLSearchParams(req.url?.split('?')[1] || '');\n const limit = parseLimit(qs.get('limit') ?? undefined, 100, 1000);\n const offset = parsePositiveInt(qs.get('offset') ?? undefined, 0);\n const levels = qs.get('levels')?.split(',').map((s) => s.trim()).filter(Boolean);\n const sources = qs.get('sources')?.split(',').map((s) => s.trim()).filter(Boolean);\n\n try {\n const result = await readServerLogs(absLogDir, { limit, offset, levels, sources });\n if (!result) {\n writeJson(res, 404, {\n message: 'No log files found',\n hint: `Expected files: ${LOG_FILES.map((c) => c.fileName).join(', ')}`,\n });\n return;\n }\n writeJson(res, 200, result);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n writeJson(res, 500, { message: 'Failed to read server logs', error: { message } });\n }\n return;\n }\n\n // ── 读取单文件:GET /dev/logs/files/:fileName ──────────────────────\n if (req.method === 'GET' && url.startsWith(filesPrefix)) {\n const fileName = decodeURIComponent(url.slice(filesPrefix.length));\n if (!fileName) {\n writeJson(res, 400, { message: 'fileName is required' });\n return;\n }\n // 解析 query string\n const qs = new URLSearchParams(req.url?.split('?')[1] || '');\n const page = parsePositiveInt(qs.get('page') ?? undefined, 1);\n const pageSize = parseLimit(qs.get('pageSize') ?? undefined, 200, 2000);\n\n try {\n const filePath = resolveLogFilePath(absLogDir, fileName);\n const result = await readLogFilePage(filePath, page, pageSize);\n if (!result) {\n writeJson(res, 404, { message: 'log file not found', file: fileName });\n return;\n }\n writeJson(res, 200, { file: path.relative(absLogDir, filePath), ...result });\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n writeJson(res, 500, { message: 'Failed to read log file', error: { message } });\n }\n return;\n }\n\n // ── 写入:POST /dev/logs/collect{,-batch} ───────────────────────────\n if (req.method === 'POST' && (url === collectPath || url === collectBatchPath)) {\n try {\n const body = (await readJsonBody(req, bodyLimit)) as unknown;\n if (url === collectPath) {\n const entry = body as Record<string, unknown>;\n if (!entry?.message) {\n writeJson(res, 400, { message: 'message is required' });\n return;\n }\n await appendOne(entry);\n writeJson(res, 200, { success: true });\n } else {\n if (!Array.isArray(body)) {\n writeJson(res, 400, { message: 'logContents must be an array' });\n return;\n }\n await appendMany(body as Array<Record<string, unknown>>);\n writeJson(res, 200, { success: true });\n }\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n writeJson(res, 500, { message: 'Failed to collect logs', error: { message } });\n }\n return;\n }\n\n next();\n });\n },\n };\n}\n\nexport default devLogsPlugin;\n","import * as path from 'node:path';\nimport type { Connect } from 'vite';\n\n/**\n * `/dev/snapdom-proxy?url=<encoded>` 转发到目标 URL,带上 request cookie。\n * 给客户端截图(snapdom)库做跨域兜底用。仅 dev。\n */\nexport interface SnapDomMiddlewareOptions {\n proxyUrl?: string;\n baseUrl?: string;\n}\n\nexport function registerSnapDomProxyMiddleware(\n middlewares: Connect.Server,\n options: SnapDomMiddlewareOptions = {}\n): void {\n const { proxyUrl = '/dev/snapdom-proxy', baseUrl = '/' } = options;\n const targetUrl = path.join(baseUrl, proxyUrl);\n\n middlewares.use(async (req, res, next) => {\n if (req.method !== 'GET' || !req.url?.startsWith(targetUrl)) {\n return next();\n }\n try {\n const url = new URL(req.url, `http://${req.headers.host}`);\n let targetParam = url.searchParams.get('url');\n if (!targetParam) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'Missing url parameter' }));\n return;\n }\n targetParam = decodeURIComponent(targetParam);\n const response = await fetch(targetParam, {\n headers: { cookie: req.headers.cookie || '' },\n });\n\n const contentType = response.headers.get('content-type');\n if (contentType) res.setHeader('Content-Type', contentType);\n\n const buffer = await response.arrayBuffer();\n res.end(Buffer.from(buffer));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(\n JSON.stringify({\n error: 'Proxy request failed',\n message: (error as Error).message,\n })\n );\n }\n });\n}\n\nexport default registerSnapDomProxyMiddleware;\n"],"mappings":"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","names":["fs","path","fileURLToPath","req","fs","path","fs","path","req","fs","path","fs","path","req","fs","fs","path","fileURLToPath","__dirname","req","req","req","path","fileURLToPath","__dirname","path","fileURLToPath","__dirname","fs","path","req","resolve","fileName","filePath","path","req","__dirname","fileURLToPath","req"]}
|