@lark-apaas/coding-preset-vite-react 1.0.12-alpha.1 → 1.0.12

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.
Files changed (134) hide show
  1. package/lib/index.d.ts +9 -1
  2. package/lib/index.d.ts.map +1 -1
  3. package/lib/index.js +153 -114
  4. package/lib/index.js.map +1 -1
  5. package/lib/plugins/{basename-injection.d.ts → basename.d.ts} +4 -4
  6. package/lib/plugins/basename.d.ts.map +1 -0
  7. package/lib/plugins/{basename-injection.js → basename.js} +7 -15
  8. package/lib/plugins/basename.js.map +1 -0
  9. package/lib/plugins/capabilities.d.ts +9 -6
  10. package/lib/plugins/capabilities.d.ts.map +1 -1
  11. package/lib/plugins/capabilities.js +27 -29
  12. package/lib/plugins/capabilities.js.map +1 -1
  13. package/lib/plugins/dev-proxy.d.ts +41 -0
  14. package/lib/plugins/dev-proxy.d.ts.map +1 -0
  15. package/lib/plugins/dev-proxy.js +229 -0
  16. package/lib/plugins/dev-proxy.js.map +1 -0
  17. package/lib/plugins/fonts-mirror.d.ts.map +1 -1
  18. package/lib/plugins/fonts-mirror.js +28 -0
  19. package/lib/plugins/fonts-mirror.js.map +1 -1
  20. package/lib/plugins/html-output.d.ts +21 -0
  21. package/lib/plugins/html-output.d.ts.map +1 -0
  22. package/lib/plugins/html-output.js +171 -0
  23. package/lib/plugins/html-output.js.map +1 -0
  24. package/lib/plugins/server-log.d.ts +45 -0
  25. package/lib/plugins/server-log.d.ts.map +1 -0
  26. package/lib/plugins/server-log.js +60 -0
  27. package/lib/plugins/server-log.js.map +1 -0
  28. package/lib/plugins/view-context.d.ts +0 -5
  29. package/lib/plugins/view-context.d.ts.map +1 -1
  30. package/lib/plugins/view-context.js +0 -3
  31. package/lib/plugins/view-context.js.map +1 -1
  32. package/lib/server-log/compat.d.ts +36 -0
  33. package/lib/server-log/compat.d.ts.map +1 -0
  34. package/lib/server-log/compat.js +73 -0
  35. package/lib/server-log/compat.js.map +1 -0
  36. package/lib/server-log/dev-logs/api-list-handler.d.ts +6 -0
  37. package/lib/server-log/dev-logs/api-list-handler.d.ts.map +1 -0
  38. package/lib/server-log/dev-logs/api-list-handler.js +132 -0
  39. package/lib/server-log/dev-logs/api-list-handler.js.map +1 -0
  40. package/lib/server-log/dev-logs/controller.d.ts +45 -0
  41. package/lib/server-log/dev-logs/controller.d.ts.map +1 -0
  42. package/lib/server-log/dev-logs/controller.js +239 -0
  43. package/lib/server-log/dev-logs/controller.js.map +1 -0
  44. package/lib/server-log/dev-logs/health.controller.d.ts +15 -0
  45. package/lib/server-log/dev-logs/health.controller.d.ts.map +1 -0
  46. package/lib/server-log/dev-logs/health.controller.js +79 -0
  47. package/lib/server-log/dev-logs/health.controller.js.map +1 -0
  48. package/lib/server-log/dev-logs/helper/path-matcher.d.ts +117 -0
  49. package/lib/server-log/dev-logs/helper/path-matcher.d.ts.map +1 -0
  50. package/lib/server-log/dev-logs/helper/path-matcher.js +214 -0
  51. package/lib/server-log/dev-logs/helper/path-matcher.js.map +1 -0
  52. package/lib/server-log/dev-logs/index.d.ts +12 -0
  53. package/lib/server-log/dev-logs/index.d.ts.map +1 -0
  54. package/lib/server-log/dev-logs/index.js +61 -0
  55. package/lib/server-log/dev-logs/index.js.map +1 -0
  56. package/lib/server-log/dev-logs/router.d.ts +7 -0
  57. package/lib/server-log/dev-logs/router.d.ts.map +1 -0
  58. package/lib/server-log/dev-logs/router.js +40 -0
  59. package/lib/server-log/dev-logs/router.js.map +1 -0
  60. package/lib/server-log/dev-logs/services/capability.service.d.ts +33 -0
  61. package/lib/server-log/dev-logs/services/capability.service.d.ts.map +1 -0
  62. package/lib/server-log/dev-logs/services/capability.service.js +127 -0
  63. package/lib/server-log/dev-logs/services/capability.service.js.map +1 -0
  64. package/lib/server-log/dev-logs/services/file-reader.d.ts +10 -0
  65. package/lib/server-log/dev-logs/services/file-reader.d.ts.map +1 -0
  66. package/lib/server-log/dev-logs/services/file-reader.js +67 -0
  67. package/lib/server-log/dev-logs/services/file-reader.js.map +1 -0
  68. package/lib/server-log/dev-logs/services/index.d.ts +8 -0
  69. package/lib/server-log/dev-logs/services/index.d.ts.map +1 -0
  70. package/lib/server-log/dev-logs/services/index.js +30 -0
  71. package/lib/server-log/dev-logs/services/index.js.map +1 -0
  72. package/lib/server-log/dev-logs/services/parsers.d.ts +23 -0
  73. package/lib/server-log/dev-logs/services/parsers.d.ts.map +1 -0
  74. package/lib/server-log/dev-logs/services/parsers.js +157 -0
  75. package/lib/server-log/dev-logs/services/parsers.js.map +1 -0
  76. package/lib/server-log/dev-logs/services/server-log.service.d.ts +17 -0
  77. package/lib/server-log/dev-logs/services/server-log.service.d.ts.map +1 -0
  78. package/lib/server-log/dev-logs/services/server-log.service.js +119 -0
  79. package/lib/server-log/dev-logs/services/server-log.service.js.map +1 -0
  80. package/lib/server-log/dev-logs/services/trace.service.d.ts +14 -0
  81. package/lib/server-log/dev-logs/services/trace.service.d.ts.map +1 -0
  82. package/lib/server-log/dev-logs/services/trace.service.js +162 -0
  83. package/lib/server-log/dev-logs/services/trace.service.js.map +1 -0
  84. package/lib/server-log/dev-logs/services/trigger.service.d.ts +14 -0
  85. package/lib/server-log/dev-logs/services/trigger.service.d.ts.map +1 -0
  86. package/lib/server-log/dev-logs/services/trigger.service.js +153 -0
  87. package/lib/server-log/dev-logs/services/trigger.service.js.map +1 -0
  88. package/lib/server-log/dev-logs/services.d.ts +7 -0
  89. package/lib/server-log/dev-logs/services.d.ts.map +1 -0
  90. package/lib/server-log/dev-logs/services.js +20 -0
  91. package/lib/server-log/dev-logs/services.js.map +1 -0
  92. package/lib/server-log/dev-logs/sse/client-manager.d.ts +61 -0
  93. package/lib/server-log/dev-logs/sse/client-manager.d.ts.map +1 -0
  94. package/lib/server-log/dev-logs/sse/client-manager.js +140 -0
  95. package/lib/server-log/dev-logs/sse/client-manager.js.map +1 -0
  96. package/lib/server-log/dev-logs/sse/index.d.ts +5 -0
  97. package/lib/server-log/dev-logs/sse/index.d.ts.map +1 -0
  98. package/lib/server-log/dev-logs/sse/index.js +11 -0
  99. package/lib/server-log/dev-logs/sse/index.js.map +1 -0
  100. package/lib/server-log/dev-logs/sse/log-watcher.d.ts +51 -0
  101. package/lib/server-log/dev-logs/sse/log-watcher.d.ts.map +1 -0
  102. package/lib/server-log/dev-logs/sse/log-watcher.js +381 -0
  103. package/lib/server-log/dev-logs/sse/log-watcher.js.map +1 -0
  104. package/lib/server-log/dev-logs/sse/sse.controller.d.ts +25 -0
  105. package/lib/server-log/dev-logs/sse/sse.controller.d.ts.map +1 -0
  106. package/lib/server-log/dev-logs/sse/sse.controller.js +95 -0
  107. package/lib/server-log/dev-logs/sse/sse.controller.js.map +1 -0
  108. package/lib/server-log/dev-logs/types.d.ts +104 -0
  109. package/lib/server-log/dev-logs/types.d.ts.map +1 -0
  110. package/lib/server-log/dev-logs/types.js +3 -0
  111. package/lib/server-log/dev-logs/types.js.map +1 -0
  112. package/lib/server-log/dev-logs/utils.d.ts +68 -0
  113. package/lib/server-log/dev-logs/utils.d.ts.map +1 -0
  114. package/lib/server-log/dev-logs/utils.js +151 -0
  115. package/lib/server-log/dev-logs/utils.js.map +1 -0
  116. package/lib/server-log/register.d.ts +34 -0
  117. package/lib/server-log/register.d.ts.map +1 -0
  118. package/lib/server-log/register.js +196 -0
  119. package/lib/server-log/register.js.map +1 -0
  120. package/lib/server-log/types.d.ts +99 -0
  121. package/lib/server-log/types.d.ts.map +1 -0
  122. package/lib/server-log/types.js +3 -0
  123. package/lib/server-log/types.js.map +1 -0
  124. package/lib/utils/local-dev.d.ts +46 -0
  125. package/lib/utils/local-dev.d.ts.map +1 -0
  126. package/lib/utils/local-dev.js +96 -0
  127. package/lib/utils/local-dev.js.map +1 -0
  128. package/lib/utils/proxy-error.d.ts +29 -0
  129. package/lib/utils/proxy-error.d.ts.map +1 -0
  130. package/lib/utils/proxy-error.js +158 -0
  131. package/lib/utils/proxy-error.js.map +1 -0
  132. package/package.json +3 -1
  133. package/lib/plugins/basename-injection.d.ts.map +0 -1
  134. package/lib/plugins/basename-injection.js.map +0 -1
@@ -46,14 +46,17 @@ const DEFAULT_DIRS = ['shared/capabilities'];
46
46
  * `@lark-apaas/client-capability` SDK(被 client-toolkit-lite 内联使用)会
47
47
  * `import map from 'virtual:capabilities'` 取这个 map。SDK 在 dev 预览 / 沙箱
48
48
  * 加载流程中依赖这个模块存在,所以即使 capabilities 目录为空,也必须把模块
49
- * 注册成解析成功(空 map),否则 rolldown 在 build 时直接 fail。
49
+ * 注册成解析成功(空 map),否则 build 时直接 fail。
50
50
  *
51
- * 同时通过 `optimizeDeps.esbuildOptions.plugins` 在 depOptimizer 那条路径上
52
- * 也提供解析——因为 client-toolkit-lite pre-bundle 进来的,pre-bundle
53
- * esbuild 不会经过 Vite pipeline 的 plugin 链。
51
+ * 解析挂两处:
52
+ * 1. Vite pipeline `resolveId` / `load` —— dev 运行时 + production build 都走它。
53
+ * 2. depOptimizer 里把 `virtual:capabilities` 标记为 external(`optimizeDeps.exclude`),
54
+ * 让被预打包的 client-toolkit-lite(内联了 client-capability)保留运行时
55
+ * `import 'virtual:capabilities'`,交给主 pipeline 动态解析。详见下方 config() 注释。
54
56
  *
55
- * V1 限制:dev 期更改 capability JSON 后,pre-bundle 产物里的 map 是启动时快照,
56
- * 不会自动刷新;新增 / 修改 capability 后需要重启 dev server。
57
+ * 这样 dev 期新增 / 修改 capability JSON 后,configureServer
58
+ * invalidateModule + full-reload 能即时刷新(旧实现把 map 内联进预打包快照,
59
+ * watch 刷不到,需重启 dev server —— 现已修复)。
57
60
  */
58
61
  function capabilitiesBundlePlugin(options = {}) {
59
62
  let rootDir = process.cwd();
@@ -87,31 +90,26 @@ function capabilitiesBundlePlugin(options = {}) {
87
90
  configResolved(config) {
88
91
  rootDir = config.root;
89
92
  },
90
- // 同时通过 depOptimizer Rolldown 注入解析,让 client-toolkit-lite 这种
91
- // pre-bundle 进来的依赖也能把 `import 'virtual:capabilities'` 解掉。
92
- // Vite 8 Rolldown 替换了 esbuild 做 depOptimize,所以走 rolldownOptions.plugins。
93
- config(_userConfig, _env) {
94
- // `rolldownOptions` Vite 8 引入的 depOptimizer 新 API,
95
- // 当前 Vite 类型还没覆盖,需要 as any 绕过
93
+ // depOptimizer 里把 `virtual:capabilities` 标记为 external,让被预打包的依赖
94
+ // (client-capability,内联进 client-toolkit-lite)保留运行时
95
+ // `import 'virtual:capabilities'`,由下面主 pipeline resolveId/load 动态解析。
96
+ //
97
+ // 为什么不在 depOptimizer 里解析 + 内联(旧实现走 rolldownOptions.plugins):
98
+ // 那样 map 会被烤成 optimize 时的快照固化进预打包 chunk。dev 期新增 / 修改
99
+ // capability JSON 后,configureServer 的 invalidateModule + full-reload 作用在
100
+ // 主 pipeline 的虚拟模块上,而预打包消费者读的是 chunk 里那份内联快照 —— 两者
101
+ // 不是同一个模块,watch 永远刷不到(实测:inline 模式 getModuleById(RESOLVED)
102
+ // 返回 null,invalidate 是 no-op;首屏 optimize 时目录还空 → map 一直空,只有
103
+ // 重启 / re-optimize 才更新)。external 后虚拟模块进入运行时模块图,
104
+ // configureServer 的 invalidate + full-reload 才真正命中被读的模块、即时刷新。
105
+ //
106
+ // external 也顺带替代了"必须在 optimizer 里解析否则 build/optimize fail"的诉求:
107
+ // 标记 external 后 optimizer 不再尝试解析它(不会 fail);build 不经 depOptimizer,
108
+ // 由主 pipeline 解析内联,产物不受影响。
109
+ config() {
96
110
  return {
97
111
  optimizeDeps: {
98
- rolldownOptions: {
99
- plugins: [
100
- {
101
- name: 'miaoda-capabilities-rolldown',
102
- resolveId(source) {
103
- if (source === VIRTUAL_ID)
104
- return RESOLVED;
105
- return null;
106
- },
107
- load(id) {
108
- if (id !== RESOLVED)
109
- return null;
110
- return `export default ${JSON.stringify(loadMap())};`;
111
- },
112
- },
113
- ],
114
- },
112
+ exclude: [VIRTUAL_ID],
115
113
  },
116
114
  };
117
115
  },
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/plugins/capabilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/plugins/capabilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Dev Server Proxy(vite dev → Nest backend)for nestjs-vite-react fullstack 形态。
3
+ *
4
+ * 命名澄清:这是**构建工具层**的 vite `server.proxy` 配置(HTTP 反代),跟 client-toolkit
5
+ * AppContainer 内置的 `api-proxy` / `childApi`(**运行时**的 postMessage 桥,给妙搭外壳
6
+ * 接口测试面板用)是不同概念,请勿混淆。
7
+ *
8
+ * fullstack 应用 dev 时 Vite(8080)是**用户入口**、Nest(3000)服务后端,二者分进程。
9
+ * 本 plugin 同时承担两件事:
10
+ *
11
+ * A. `config()` 注入 `server.proxy`:把 `/api`、`/openapi`、`/__innerapi__` 反代到 Nest,
12
+ * 且模拟沙箱网关的两件事:
13
+ * 1. 注入 `x-larkgw-suda-webuser` header(身份)—— 本地从 SUDA_WEBUSER env 取
14
+ * 2. 注入 `x-suda-csrf-token` header(csrf double-submit)—— per-request 从 cookie 抠
15
+ * 否则 Nest 端 ViewController 拿不到 appId(→ window.appId="" → auth-sdk URL 拼错),
16
+ * csrf middleware 也会拦下请求。
17
+ *
18
+ * B. `configureServer()` 挂 HTML 反代 middleware:用户访问 `vite-8080/<path>` 拿页面时,
19
+ * vite 默认走自己的 index.html。但 fullstack 形态要 Nest 渲染 HBS(注入 appId / csrf /
20
+ * platform-data 等),所以拦截所有 `accept: text/html` 请求转发到 Nest 3000。
21
+ * 白名单避开 vite dev-only 路径(`/@vite`、`/@fs`、`/__vite`、`/@id`、`/node_modules`、
22
+ * `/dev/`、`.hot-update`)和静态资源(.js / .css / 图片 / 字体),这些应该走 vite 自身。
23
+ *
24
+ * 实现搬自 fullstack-vite-preset/src/preset.ts 的 server.proxy + HTML proxy 段,逻辑一致。
25
+ */
26
+ import type { Plugin } from 'vite';
27
+ export interface DevProxyPluginOptions {
28
+ /** Nest server 监听端口。默认 3000 */
29
+ serverPort?: number;
30
+ /** client base path,跟 normalizeBasePath 处理后一致(如 `/app/<id>` 或空串) */
31
+ clientBasePath?: string;
32
+ /** 从 clientBasePath 提取的 appId,用于挂老路径兼容 proxy(`/af/p/<appId>/...`) */
33
+ appId?: string;
34
+ }
35
+ /**
36
+ * Vite plugin: 注入 dev server proxy 配置(仅 dev,build 时不挂)。
37
+ * 通过 `config()` hook 返回 `server.proxy` 让 vite mergeConfig 自动合并。
38
+ */
39
+ export declare function devProxyPlugin(options?: DevProxyPluginOptions): Plugin;
40
+ export default devProxyPlugin;
41
+ //# sourceMappingURL=dev-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-proxy.d.ts","sourceRoot":"","sources":["../../src/plugins/dev-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,MAAM,CAAC;AAUjD,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAgL1E;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ /**
3
+ * Dev Server Proxy(vite dev → Nest backend)for nestjs-vite-react fullstack 形态。
4
+ *
5
+ * 命名澄清:这是**构建工具层**的 vite `server.proxy` 配置(HTTP 反代),跟 client-toolkit
6
+ * AppContainer 内置的 `api-proxy` / `childApi`(**运行时**的 postMessage 桥,给妙搭外壳
7
+ * 接口测试面板用)是不同概念,请勿混淆。
8
+ *
9
+ * fullstack 应用 dev 时 Vite(8080)是**用户入口**、Nest(3000)服务后端,二者分进程。
10
+ * 本 plugin 同时承担两件事:
11
+ *
12
+ * A. `config()` 注入 `server.proxy`:把 `/api`、`/openapi`、`/__innerapi__` 反代到 Nest,
13
+ * 且模拟沙箱网关的两件事:
14
+ * 1. 注入 `x-larkgw-suda-webuser` header(身份)—— 本地从 SUDA_WEBUSER env 取
15
+ * 2. 注入 `x-suda-csrf-token` header(csrf double-submit)—— per-request 从 cookie 抠
16
+ * 否则 Nest 端 ViewController 拿不到 appId(→ window.appId="" → auth-sdk URL 拼错),
17
+ * csrf middleware 也会拦下请求。
18
+ *
19
+ * B. `configureServer()` 挂 HTML 反代 middleware:用户访问 `vite-8080/<path>` 拿页面时,
20
+ * vite 默认走自己的 index.html。但 fullstack 形态要 Nest 渲染 HBS(注入 appId / csrf /
21
+ * platform-data 等),所以拦截所有 `accept: text/html` 请求转发到 Nest 3000。
22
+ * 白名单避开 vite dev-only 路径(`/@vite`、`/@fs`、`/__vite`、`/@id`、`/node_modules`、
23
+ * `/dev/`、`.hot-update`)和静态资源(.js / .css / 图片 / 字体),这些应该走 vite 自身。
24
+ *
25
+ * 实现搬自 fullstack-vite-preset/src/preset.ts 的 server.proxy + HTML proxy 段,逻辑一致。
26
+ */
27
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ var desc = Object.getOwnPropertyDescriptor(m, k);
30
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
31
+ desc = { enumerable: true, get: function() { return m[k]; } };
32
+ }
33
+ Object.defineProperty(o, k2, desc);
34
+ }) : (function(o, m, k, k2) {
35
+ if (k2 === undefined) k2 = k;
36
+ o[k2] = m[k];
37
+ }));
38
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
39
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
40
+ }) : function(o, v) {
41
+ o["default"] = v;
42
+ });
43
+ var __importStar = (this && this.__importStar) || (function () {
44
+ var ownKeys = function(o) {
45
+ ownKeys = Object.getOwnPropertyNames || function (o) {
46
+ var ar = [];
47
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
48
+ return ar;
49
+ };
50
+ return ownKeys(o);
51
+ };
52
+ return function (mod) {
53
+ if (mod && mod.__esModule) return mod;
54
+ var result = {};
55
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
56
+ __setModuleDefault(result, mod);
57
+ return result;
58
+ };
59
+ })();
60
+ Object.defineProperty(exports, "__esModule", { value: true });
61
+ exports.devProxyPlugin = devProxyPlugin;
62
+ const http = __importStar(require("node:http"));
63
+ const local_dev_1 = require("../utils/local-dev");
64
+ const proxy_error_1 = require("../utils/proxy-error");
65
+ /**
66
+ * Vite plugin: 注入 dev server proxy 配置(仅 dev,build 时不挂)。
67
+ * 通过 `config()` hook 返回 `server.proxy` 让 vite mergeConfig 自动合并。
68
+ */
69
+ function devProxyPlugin(options = {}) {
70
+ const serverPort = options.serverPort ?? 3000;
71
+ const clientBasePath = options.clientBasePath ?? '';
72
+ const appId = options.appId;
73
+ return {
74
+ name: 'nestjs-vite-react-dev-proxy',
75
+ apply: 'serve',
76
+ config() {
77
+ const localDev = (0, local_dev_1.isLocalDev)();
78
+ const sandboxBase = (0, local_dev_1.resolveSandboxOrigin)();
79
+ const { cookie: outboundCookie, csrfToken: outboundCsrfToken } = (0, local_dev_1.composeSandboxOutboundAuth)();
80
+ // 解析 SUDA_WEBUSER(沙箱注入到 .env.local,dotenv@17 转义边界容错)
81
+ let localDevWebUserHeader = '';
82
+ const parsedSudaWebUser = (0, local_dev_1.parseSudaWebUserEnv)(process.env.SUDA_WEBUSER);
83
+ if (parsedSudaWebUser) {
84
+ try {
85
+ localDevWebUserHeader = encodeURIComponent(JSON.stringify(parsedSudaWebUser));
86
+ }
87
+ catch {
88
+ /* ignore */
89
+ }
90
+ }
91
+ const proxy = {};
92
+ // 本地反代沙箱的平台 runtime API(条件性)
93
+ if (localDev && sandboxBase) {
94
+ proxy[`${clientBasePath}/__runtime__`] = {
95
+ target: sandboxBase,
96
+ changeOrigin: true,
97
+ headers: {
98
+ ...(outboundCookie ? { cookie: outboundCookie } : {}),
99
+ ...(outboundCsrfToken ? { 'x-suda-csrf-token': outboundCsrfToken } : {}),
100
+ },
101
+ };
102
+ }
103
+ // API proxy。本地 dev 没有 larkgw 经过这条 incoming 链路,server 端 NestJS 缺:
104
+ // 1. x-larkgw-suda-webuser header(身份) → ViewController 拿不到 appId
105
+ // 2. x-suda-csrf-token header(csrf double-submit) → csrf middleware 403
106
+ // 在 dev server 这层模拟 larkgw 注入这两样
107
+ proxy[`${clientBasePath}/api`] = {
108
+ target: `http://localhost:${serverPort}`,
109
+ changeOrigin: true,
110
+ ...(localDev && localDevWebUserHeader
111
+ ? { headers: { 'x-larkgw-suda-webuser': localDevWebUserHeader } }
112
+ : {}),
113
+ configure: (proxyServer) => {
114
+ proxyServer.on('error', (err, req, res) => {
115
+ (0, proxy_error_1.handleDevProxyError)(err, req, res, {
116
+ target: `http://localhost:${serverPort}`,
117
+ });
118
+ });
119
+ if (localDev) {
120
+ proxyServer.on('proxyReq', (proxyReq, req) => {
121
+ if (proxyReq.getHeader('x-suda-csrf-token'))
122
+ return;
123
+ const cookie = req.headers.cookie;
124
+ if (!cookie)
125
+ return;
126
+ const m = /(?:^|;\s*)suda-csrf-token=([^;]+)/.exec(cookie);
127
+ if (m)
128
+ proxyReq.setHeader('x-suda-csrf-token', m[1]);
129
+ });
130
+ }
131
+ },
132
+ };
133
+ // OpenAPI proxy
134
+ proxy[`${clientBasePath}/openapi`] = {
135
+ target: `http://localhost:${serverPort}`,
136
+ changeOrigin: true,
137
+ configure: (proxyServer) => {
138
+ proxyServer.on('error', (err, req, res) => {
139
+ (0, proxy_error_1.handleDevProxyError)(err, req, res, {
140
+ target: `http://localhost:${serverPort}`,
141
+ });
142
+ });
143
+ },
144
+ };
145
+ // Inner API proxy
146
+ proxy[`${clientBasePath}/__innerapi__`] = {
147
+ target: `http://localhost:${serverPort}`,
148
+ changeOrigin: true,
149
+ configure: (proxyServer) => {
150
+ proxyServer.on('error', (err, req, res) => {
151
+ (0, proxy_error_1.handleDevProxyError)(err, req, res, {
152
+ target: `http://localhost:${serverPort}`,
153
+ });
154
+ });
155
+ },
156
+ };
157
+ // 旧路径(/af/p/:appId)兼容代理(仅在 appId 已知时挂)
158
+ if (appId) {
159
+ proxy[`/af/p/${appId}/api`] = {
160
+ target: `http://localhost:${serverPort}`,
161
+ changeOrigin: true,
162
+ configure: (proxyServer) => {
163
+ proxyServer.on('error', (err, req, res) => {
164
+ (0, proxy_error_1.handleDevProxyError)(err, req, res, {
165
+ target: `http://localhost:${serverPort}`,
166
+ });
167
+ });
168
+ },
169
+ };
170
+ proxy[`/af/p/${appId}/__innerapi__`] = {
171
+ target: `http://localhost:${serverPort}`,
172
+ changeOrigin: true,
173
+ configure: (proxyServer) => {
174
+ proxyServer.on('error', (err, req, res) => {
175
+ (0, proxy_error_1.handleDevProxyError)(err, req, res, {
176
+ target: `http://localhost:${serverPort}`,
177
+ });
178
+ });
179
+ },
180
+ };
181
+ }
182
+ return {
183
+ server: { proxy },
184
+ };
185
+ },
186
+ configureServer(server) {
187
+ // HTML 反代到 Nest:fullstack 入口是 vite (8080),但 HTML 由 Nest hbs 渲染
188
+ server.middlewares.use((req, res, next) => {
189
+ const devServerWhiteList = [
190
+ '/@vite',
191
+ '/@fs',
192
+ '/__vite',
193
+ '/@id',
194
+ '/node_modules',
195
+ '/dev/',
196
+ '.hot-update',
197
+ '/@react-refresh',
198
+ '/@ws-watchdog',
199
+ '/@error-overlay',
200
+ ];
201
+ const isHtmlRequest = req.headers.accept?.includes('text/html');
202
+ const pathname = req.url?.split('?')[0] || '';
203
+ const isDevServerPath = devServerWhiteList.some((item) => pathname.includes(item));
204
+ const isStaticAsset = /\.(js|mjs|cjs|css|map|png|jpg|jpeg|gif|svg|ico|webp|woff|woff2|ttf|eot)$/i.test(pathname);
205
+ if (!isHtmlRequest || isDevServerPath || isStaticAsset) {
206
+ return next();
207
+ }
208
+ const proxyReq = http.request({
209
+ hostname: 'localhost',
210
+ port: serverPort,
211
+ path: req.url,
212
+ method: req.method,
213
+ headers: req.headers,
214
+ }, (proxyRes) => {
215
+ res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
216
+ proxyRes.pipe(res);
217
+ });
218
+ proxyReq.on('error', (err) => {
219
+ (0, proxy_error_1.handleDevProxyError)(err, req, res, {
220
+ target: `http://localhost:${serverPort}`,
221
+ });
222
+ });
223
+ req.pipe(proxyReq);
224
+ });
225
+ },
226
+ };
227
+ }
228
+ exports.default = devProxyPlugin;
229
+ //# sourceMappingURL=dev-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-proxy.js","sourceRoot":"","sources":["../../src/plugins/dev-proxy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fonts-mirror.d.ts","sourceRoot":"","sources":["../../src/plugins/fonts-mirror.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAgBnC,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB;IAClB,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CAC/B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,GAAG,KAAK,CAwDxF;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"fonts-mirror.d.ts","sourceRoot":"","sources":["../../src/plugins/fonts-mirror.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAsBnC,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB;IAClB,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CAC/B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,GAAG,KAAK,CA8ExF;AAED,eAAe,iBAAiB,CAAC"}
@@ -9,6 +9,12 @@ exports.fontsMirrorPlugin = fontsMirrorPlugin;
9
9
  * - URL pathname 保持与 Google Fonts 一致(`/css`、`/css2?family=...&wght=...`),
10
10
  * 任意模型输出形式都能被代理;只换域名
11
11
  * - 关闭:`{ disabled: true }` 或环境变量 `MIAODA_FONTS_MIRROR_OFF=1`
12
+ *
13
+ * 兜底策略(generateBundle):
14
+ * - postcss-import / @tailwindcss/postcss 内联子 CSS 时用 fs.readFile 直接读盘,
15
+ * 不走 Vite plugin 流水线 → transform 钩子漏过
16
+ * - 因此在 build 阶段对最终产出的 CSS asset 再扫一遍,确保替换不漏
17
+ * - transform 已替换过的文件,HAS_GOOGLE_FONTS 检测自动跳过,不重复计数
12
18
  */
13
19
  const DEFAULT_MIRROR = 'https://miaoda.feishu.cn/fonts';
14
20
  const GOOGLE_FONTS_RE = /https?:\/\/fonts\.(googleapis|gstatic)\.com/g;
@@ -59,6 +65,28 @@ function fontsMirrorPlugin(options = {}) {
59
65
  }
60
66
  return { code: code.replace(GOOGLE_FONTS_RE, mirror), map: null };
61
67
  },
68
+ generateBundle(_options, bundle) {
69
+ for (const file of Object.values(bundle)) {
70
+ if (file.type !== 'asset')
71
+ continue;
72
+ if (!/\.css$/.test(file.fileName))
73
+ continue;
74
+ const src = typeof file.source === 'string'
75
+ ? file.source
76
+ : Buffer.from(file.source).toString('utf-8');
77
+ if (!HAS_GOOGLE_FONTS.test(src))
78
+ continue;
79
+ const matches = src.match(GOOGLE_FONTS_RE);
80
+ if (!matches)
81
+ continue;
82
+ file.source = src.replace(GOOGLE_FONTS_RE, mirror);
83
+ stats.files += 1;
84
+ stats.occurrences += matches.length;
85
+ if (warn) {
86
+ console.warn(`[miaoda-fonts-mirror] rewrote ${matches.length} occurrence(s) in ${file.fileName}`);
87
+ }
88
+ }
89
+ },
62
90
  closeBundle() {
63
91
  if (stats.files > 0) {
64
92
  console.log(`[miaoda-fonts-mirror] ✓ rewrote ${stats.occurrences} occurrence(s) across ${stats.files} file(s) → ${mirror}`);
@@ -1 +1 @@
1
- {"version":3,"file":"fonts-mirror.js","sourceRoot":"","sources":["../../src/plugins/fonts-mirror.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fonts-mirror.js","sourceRoot":"","sources":["../../src/plugins/fonts-mirror.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Plugin } from 'vite';
2
+ /**
3
+ * Minify HTML while preserving HBS (Handlebars) template expressions.
4
+ *
5
+ * HBS expressions like {{csrfToken}} and {{{appAvatar}}} are temporarily
6
+ * replaced with safe placeholders before minification, then restored after.
7
+ */
8
+ export declare function minifyHtmlWithHbsProtection(html: string): Promise<string>;
9
+ export interface HtmlOutputPluginOptions {
10
+ /** Whether running in development mode */
11
+ isDev: boolean;
12
+ /** Output directory for built files */
13
+ outDir: string;
14
+ }
15
+ /**
16
+ * Vite plugin to handle HTML output:
17
+ * 1. In production: fixes HTML output path (removes extra 'client' directory)
18
+ * 2. In development: writes transformed HTML to disk for backend to serve
19
+ */
20
+ export declare function htmlOutputPlugin(options: HtmlOutputPluginOptions): Plugin;
21
+ //# sourceMappingURL=html-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-output.d.ts","sourceRoot":"","sources":["../../src/plugins/html-output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,MAAM,CAAC;AAGlE;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B/E;AAED,MAAM,WAAW,uBAAuB;IACtC,0CAA0C;IAC1C,KAAK,EAAE,OAAO,CAAC;IACf,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAwIzE"}
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.minifyHtmlWithHbsProtection = minifyHtmlWithHbsProtection;
7
+ exports.htmlOutputPlugin = htmlOutputPlugin;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const html_minifier_terser_1 = require("html-minifier-terser");
11
+ /**
12
+ * Minify HTML while preserving HBS (Handlebars) template expressions.
13
+ *
14
+ * HBS expressions like {{csrfToken}} and {{{appAvatar}}} are temporarily
15
+ * replaced with safe placeholders before minification, then restored after.
16
+ */
17
+ async function minifyHtmlWithHbsProtection(html) {
18
+ // Replace HBS expressions with placeholders before minification
19
+ // to prevent html-minifier-terser from corrupting them
20
+ const hbsPlaceholders = [];
21
+ let processed = html.replace(/\{\{\{?.+?\}\}\}?/g, (match) => {
22
+ const index = hbsPlaceholders.length;
23
+ hbsPlaceholders.push(match);
24
+ return `__HBS_${index}__`;
25
+ });
26
+ processed = await (0, html_minifier_terser_1.minify)(processed, {
27
+ collapseWhitespace: true,
28
+ removeComments: true,
29
+ removeRedundantAttributes: true,
30
+ removeEmptyAttributes: true,
31
+ minifyCSS: true,
32
+ // Do NOT minifyJS — inline scripts may reference HBS placeholders
33
+ minifyJS: false,
34
+ });
35
+ // Restore HBS expressions
36
+ processed = processed.replace(/__HBS_(\d+)__/g, (_, index) => {
37
+ return hbsPlaceholders[Number(index)];
38
+ });
39
+ return processed;
40
+ }
41
+ /**
42
+ * Vite plugin to handle HTML output:
43
+ * 1. In production: fixes HTML output path (removes extra 'client' directory)
44
+ * 2. In development: writes transformed HTML to disk for backend to serve
45
+ */
46
+ function htmlOutputPlugin(options) {
47
+ const { isDev, outDir } = options;
48
+ let config;
49
+ let server = null;
50
+ /**
51
+ * Transform and write HTML to disk for backend to serve
52
+ */
53
+ async function writeHtmlToDisk() {
54
+ if (!server || !config)
55
+ return;
56
+ try {
57
+ // Find the input HTML file from rollup options
58
+ const rollupInput = config.build.rollupOptions?.input;
59
+ let htmlPath;
60
+ if (typeof rollupInput === 'string') {
61
+ htmlPath = rollupInput;
62
+ }
63
+ else if (Array.isArray(rollupInput)) {
64
+ htmlPath = rollupInput.find((f) => f.endsWith('.html')) || '';
65
+ }
66
+ else if (rollupInput && typeof rollupInput === 'object') {
67
+ htmlPath =
68
+ Object.values(rollupInput).find((f) => f.endsWith('.html')) || '';
69
+ }
70
+ else {
71
+ htmlPath = path_1.default.resolve(config.root, 'index.html');
72
+ }
73
+ if (!htmlPath || !fs_1.default.existsSync(htmlPath)) {
74
+ console.warn(`[html-output] HTML file not found: ${htmlPath}`);
75
+ return;
76
+ }
77
+ // Read the source HTML
78
+ let html = fs_1.default.readFileSync(htmlPath, 'utf-8');
79
+ // Apply Vite's HTML transformations (this calls all plugin's transformIndexHtml hooks)
80
+ const url = '/' + path_1.default.relative(config.root, htmlPath);
81
+ html = await server.transformIndexHtml(url, html);
82
+ // Write to output directory
83
+ const outputPath = path_1.default.resolve(outDir, 'index.html');
84
+ // Ensure output directory exists
85
+ const dir = path_1.default.dirname(outputPath);
86
+ if (!fs_1.default.existsSync(dir)) {
87
+ fs_1.default.mkdirSync(dir, { recursive: true });
88
+ }
89
+ fs_1.default.writeFileSync(outputPath, html);
90
+ console.log(`[html-output] Written to: ${outputPath}`);
91
+ }
92
+ catch (e) {
93
+ console.error(`[html-output] Failed to write HTML:`, e);
94
+ }
95
+ }
96
+ return {
97
+ name: 'vite-html-output',
98
+ configResolved(resolvedConfig) {
99
+ config = resolvedConfig;
100
+ },
101
+ configureServer(devServer) {
102
+ if (!isDev)
103
+ return;
104
+ server = devServer;
105
+ // Return a post hook to run after all plugins' configureServer and
106
+ // Vite's internal middlewares are set up
107
+ return () => {
108
+ writeHtmlToDisk();
109
+ // Watch for HTML file changes
110
+ const rollupInput = config.build.rollupOptions?.input;
111
+ let htmlPath;
112
+ if (typeof rollupInput === 'string' && rollupInput.endsWith('.html')) {
113
+ htmlPath = rollupInput;
114
+ }
115
+ else if (rollupInput && typeof rollupInput === 'object') {
116
+ const inputs = Array.isArray(rollupInput)
117
+ ? rollupInput
118
+ : Object.values(rollupInput);
119
+ htmlPath = inputs.find((f) => f.endsWith('.html'));
120
+ }
121
+ if (htmlPath) {
122
+ devServer.watcher.add(htmlPath);
123
+ devServer.watcher.on('change', (file) => {
124
+ if (file === htmlPath) {
125
+ console.log(`[html-output] HTML changed, regenerating...`);
126
+ writeHtmlToDisk();
127
+ }
128
+ });
129
+ }
130
+ };
131
+ },
132
+ // In production, fix the HTML output path and minify after build
133
+ async closeBundle() {
134
+ if (!isDev && config) {
135
+ const outDir = config.build.outDir;
136
+ const wrongPath = path_1.default.resolve(outDir, 'client/index.html');
137
+ const correctPath = path_1.default.resolve(outDir, 'index.html');
138
+ // Check if HTML was output to wrong location
139
+ if (fs_1.default.existsSync(wrongPath)) {
140
+ // Move HTML to correct location
141
+ fs_1.default.renameSync(wrongPath, correctPath);
142
+ console.log(`[html-output] Moved: ${wrongPath} -> ${correctPath}`);
143
+ // Remove empty client directory if it exists
144
+ const clientDir = path_1.default.resolve(outDir, 'client');
145
+ try {
146
+ const files = fs_1.default.readdirSync(clientDir);
147
+ if (files.length === 0) {
148
+ fs_1.default.rmdirSync(clientDir);
149
+ }
150
+ }
151
+ catch {
152
+ // Directory doesn't exist or not empty, ignore
153
+ }
154
+ }
155
+ // Minify HTML (protect HBS templates like {{csrfToken}}, {{{appAvatar}}})
156
+ if (fs_1.default.existsSync(correctPath)) {
157
+ try {
158
+ const html = fs_1.default.readFileSync(correctPath, 'utf-8');
159
+ const minified = await minifyHtmlWithHbsProtection(html);
160
+ fs_1.default.writeFileSync(correctPath, minified);
161
+ console.log(`[html-output] Minified: ${correctPath}`);
162
+ }
163
+ catch (e) {
164
+ console.warn(`[html-output] HTML minification failed, skipping:`, e);
165
+ }
166
+ }
167
+ }
168
+ },
169
+ };
170
+ }
171
+ //# sourceMappingURL=html-output.js.map