@zhin.js/console 1.0.51 → 1.0.53

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 (65) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +22 -0
  3. package/browser.tsconfig.json +19 -0
  4. package/client/src/components/PageHeader.tsx +26 -0
  5. package/client/src/components/ui/accordion.tsx +2 -1
  6. package/client/src/components/ui/badge.tsx +1 -3
  7. package/client/src/components/ui/scroll-area.tsx +5 -2
  8. package/client/src/components/ui/select.tsx +7 -3
  9. package/client/src/components/ui/separator.tsx +5 -2
  10. package/client/src/components/ui/tabs.tsx +4 -2
  11. package/client/src/layouts/dashboard.tsx +223 -121
  12. package/client/src/main.tsx +34 -34
  13. package/client/src/pages/bot-detail/MessageBody.tsx +110 -0
  14. package/client/src/pages/bot-detail/date-utils.ts +8 -0
  15. package/client/src/pages/bot-detail/index.tsx +798 -0
  16. package/client/src/pages/bot-detail/types.ts +92 -0
  17. package/client/src/pages/bot-detail/useBotConsole.tsx +600 -0
  18. package/client/src/pages/bots.tsx +111 -73
  19. package/client/src/pages/database/constants.ts +16 -0
  20. package/client/src/pages/database/database-page.tsx +170 -0
  21. package/client/src/pages/database/document-collection-view.tsx +155 -0
  22. package/client/src/pages/database/index.tsx +1 -0
  23. package/client/src/pages/database/json-field.tsx +11 -0
  24. package/client/src/pages/database/kv-bucket-view.tsx +169 -0
  25. package/client/src/pages/database/related-table-view.tsx +221 -0
  26. package/client/src/pages/env.tsx +38 -28
  27. package/client/src/pages/files/code-editor.tsx +85 -0
  28. package/client/src/pages/files/editor-constants.ts +9 -0
  29. package/client/src/pages/files/file-editor.tsx +133 -0
  30. package/client/src/pages/files/file-icons.tsx +25 -0
  31. package/client/src/pages/files/files-page.tsx +92 -0
  32. package/client/src/pages/files/hljs-global.d.ts +10 -0
  33. package/client/src/pages/files/index.tsx +1 -0
  34. package/client/src/pages/files/language.ts +18 -0
  35. package/client/src/pages/files/tree-node.tsx +69 -0
  36. package/client/src/pages/files/use-hljs-theme.ts +23 -0
  37. package/client/src/pages/logs.tsx +77 -22
  38. package/client/src/style.css +144 -0
  39. package/client/src/utils/parseComposerContent.ts +57 -0
  40. package/client/tailwind.config.js +1 -0
  41. package/client/tsconfig.json +3 -1
  42. package/dist/assets/index-COKXlFo2.js +124 -0
  43. package/dist/assets/style-kkLO-vsa.css +3 -0
  44. package/dist/client.js +482 -464
  45. package/dist/index.html +2 -2
  46. package/dist/style.css +1 -1
  47. package/lib/index.js +1010 -81
  48. package/lib/transform.js +16 -2
  49. package/lib/websocket.js +845 -28
  50. package/node.tsconfig.json +18 -0
  51. package/package.json +13 -15
  52. package/src/bin.ts +24 -0
  53. package/src/bot-db-models.ts +74 -0
  54. package/src/bot-hub.ts +240 -0
  55. package/src/bot-persistence.ts +270 -0
  56. package/src/build.ts +90 -0
  57. package/src/dev.ts +107 -0
  58. package/src/index.ts +337 -0
  59. package/src/transform.ts +199 -0
  60. package/src/websocket.ts +1369 -0
  61. package/client/src/pages/database.tsx +0 -708
  62. package/client/src/pages/files.tsx +0 -470
  63. package/client/src/pages/login-assist.tsx +0 -225
  64. package/dist/assets/index-DS4RbHWX.js +0 -124
  65. package/dist/assets/style-DS-m6WEr.css +0 -3
@@ -0,0 +1,199 @@
1
+ /**
2
+ * esbuild 按需转译模块
3
+ *
4
+ * 在生产模式下,对请求的 .ts/.tsx/.jsx 文件进行实时转译:
5
+ * 1. 读取源文件
6
+ * 2. esbuild.transform() 转为 ESM JS(React 17+ automatic JSX)
7
+ * 3. 重写相对 import 路径(补全扩展名,移除 CSS import)
8
+ * 4. 以 mtime 为校验的内存缓存
9
+ */
10
+
11
+ import { transform } from "esbuild";
12
+ import * as fs from "fs";
13
+ import * as path from "path";
14
+
15
+ // ── 缓存 ──────────────────────────────────────────────────────────────────────
16
+
17
+ interface CacheEntry {
18
+ mtime: number;
19
+ code: string;
20
+ }
21
+
22
+ const cache = new Map<string, CacheEntry>();
23
+
24
+ // ── 扩展名探测 ────────────────────────────────────────────────────────────────
25
+
26
+ /** 需要转译的扩展名 */
27
+ const TRANSFORMABLE_EXTS = [".ts", ".tsx", ".jsx"];
28
+
29
+ /** 解析无扩展名的 import 路径,按优先级探测 */
30
+ const RESOLVE_EXTS = [".tsx", ".ts", ".jsx", ".js"];
31
+
32
+ /**
33
+ * 判断文件是否需要转译
34
+ */
35
+ export function isTransformable(filePath: string): boolean {
36
+ const ext = path.extname(filePath).toLowerCase();
37
+ return TRANSFORMABLE_EXTS.includes(ext);
38
+ }
39
+
40
+ // ── import 路径重写 ───────────────────────────────────────────────────────────
41
+
42
+ /**
43
+ * 匹配 import/export 语句中的路径:
44
+ * - import X from './Foo'
45
+ * - import { X } from '../utils'
46
+ * - export { X } from './bar'
47
+ * - import('./Foo')
48
+ * - import X from "./Foo"
49
+ */
50
+ const IMPORT_RE =
51
+ /(?:import|export)\s+.*?\s+from\s+['"]([^'"]+)['"]|import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
52
+
53
+ /**
54
+ * 匹配 CSS import(用于移除):
55
+ * - import './style.css'
56
+ * - import "../theme.css"
57
+ */
58
+ const CSS_IMPORT_RE =
59
+ /import\s+['"][^'"]+\.css['"]\s*;?\n?/g;
60
+
61
+ /**
62
+ * 判断是否为相对路径(./ 或 ../)
63
+ */
64
+ function isRelative(specifier: string): boolean {
65
+ return specifier.startsWith("./") || specifier.startsWith("../");
66
+ }
67
+
68
+ /**
69
+ * 判断路径是否已有文件扩展名
70
+ */
71
+ function hasExtension(specifier: string): boolean {
72
+ const base = path.basename(specifier);
73
+ return base.includes(".") && !base.startsWith(".");
74
+ }
75
+
76
+ /**
77
+ * 源码写 import './x.js'(TS 输出惯例)但磁盘仅有 x.ts / x.tsx 时,映射到真实文件。
78
+ * 否则 /vite/@ext/ 会按字面请求 .js 导致 404。
79
+ */
80
+ function resolveJsSpecifierToSource(specifier: string, fromFile: string): string {
81
+ if (!isRelative(specifier) || !specifier.endsWith(".js")) return specifier;
82
+ const dir = path.dirname(fromFile);
83
+ const jsPath = path.resolve(dir, specifier);
84
+ if (fs.existsSync(jsPath)) return specifier;
85
+ const base = specifier.slice(0, -3);
86
+ for (const ext of [".tsx", ".ts", ".jsx"]) {
87
+ if (fs.existsSync(path.resolve(dir, base + ext))) {
88
+ return base + ext;
89
+ }
90
+ }
91
+ return specifier;
92
+ }
93
+
94
+ /**
95
+ * 探测并补全相对 import 的扩展名
96
+ *
97
+ * ./Foo → 探测 Foo.tsx > Foo.ts > Foo.jsx > Foo.js > Foo/index.tsx > ...
98
+ */
99
+ function resolveRelativeImport(
100
+ specifier: string,
101
+ fromFile: string,
102
+ ): string {
103
+ if (!isRelative(specifier)) return specifier;
104
+ if (hasExtension(specifier)) {
105
+ return resolveJsSpecifierToSource(specifier, fromFile);
106
+ }
107
+
108
+ const dir = path.dirname(fromFile);
109
+ const target = path.resolve(dir, specifier);
110
+
111
+ // 1. 直接探测文件
112
+ for (const ext of RESOLVE_EXTS) {
113
+ if (fs.existsSync(target + ext)) {
114
+ return specifier + ext;
115
+ }
116
+ }
117
+
118
+ // 2. 探测目录下的 index 文件
119
+ if (fs.existsSync(target) && fs.statSync(target).isDirectory()) {
120
+ for (const ext of RESOLVE_EXTS) {
121
+ if (fs.existsSync(path.join(target, `index${ext}`))) {
122
+ return specifier + `/index${ext}`;
123
+ }
124
+ }
125
+ }
126
+
127
+ // 无法解析,原样返回
128
+ return specifier;
129
+ }
130
+
131
+ /**
132
+ * 重写转译后代码中的 import 路径:
133
+ * - 移除 CSS import
134
+ * - 补全相对 import 的扩展名
135
+ */
136
+ function rewriteImports(code: string, fromFile: string): string {
137
+ // 1. 移除 CSS import
138
+ code = code.replace(CSS_IMPORT_RE, "");
139
+
140
+ // 2. 补全相对 import 的扩展名
141
+ code = code.replace(IMPORT_RE, (match, fromSpecifier, dynamicSpecifier) => {
142
+ const specifier = fromSpecifier || dynamicSpecifier;
143
+ if (!specifier || !isRelative(specifier)) return match;
144
+
145
+ const resolved = resolveRelativeImport(specifier, fromFile);
146
+ if (resolved === specifier) return match;
147
+
148
+ return match.replace(specifier, resolved);
149
+ });
150
+
151
+ return code;
152
+ }
153
+
154
+ // ── 核心转译函数 ──────────────────────────────────────────────────────────────
155
+
156
+ /**
157
+ * 转译单个 TS/TSX/JSX 文件为 ESM JavaScript
158
+ *
159
+ * @param filePath 文件绝对路径
160
+ * @returns 转译后的 JS 代码
161
+ */
162
+ export async function transformFile(filePath: string): Promise<string> {
163
+ // 检查缓存
164
+ const stat = fs.statSync(filePath);
165
+ const cached = cache.get(filePath);
166
+ if (cached && cached.mtime === stat.mtimeMs) {
167
+ return cached.code;
168
+ }
169
+
170
+ const source = fs.readFileSync(filePath, "utf-8");
171
+ const ext = path.extname(filePath).toLowerCase();
172
+
173
+ const loader =
174
+ ext === ".tsx" ? "tsx" : ext === ".ts" ? "ts" : ext === ".jsx" ? "jsx" : "js";
175
+
176
+ const result = await transform(source, {
177
+ loader,
178
+ jsx: "automatic",
179
+ jsxImportSource: "react",
180
+ format: "esm",
181
+ sourcemap: "inline",
182
+ target: "es2022",
183
+ });
184
+
185
+ // 重写 import 路径
186
+ const code = rewriteImports(result.code, filePath);
187
+
188
+ // 写入缓存
189
+ cache.set(filePath, { mtime: stat.mtimeMs, code });
190
+
191
+ return code;
192
+ }
193
+
194
+ /**
195
+ * 清空转译缓存
196
+ */
197
+ export function clearTransformCache(): void {
198
+ cache.clear();
199
+ }