@jsbot-tellus/core 2.3.0 → 2.4.0

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 (110) hide show
  1. package/README.md +19 -0
  2. package/bot.config.example.json +3 -0
  3. package/dist/app.js +215 -98
  4. package/dist/app.js.map +1 -1
  5. package/dist/core/client.d.ts +1 -0
  6. package/dist/core/client.d.ts.map +1 -1
  7. package/dist/core/client.js +3 -0
  8. package/dist/core/client.js.map +1 -1
  9. package/dist/core/config/schema.d.ts +19 -0
  10. package/dist/core/config/schema.d.ts.map +1 -1
  11. package/dist/core/config/schema.js +37 -0
  12. package/dist/core/config/schema.js.map +1 -1
  13. package/dist/core/dispatch/router.d.ts +3 -0
  14. package/dist/core/dispatch/router.d.ts.map +1 -1
  15. package/dist/core/dispatch/router.js +13 -0
  16. package/dist/core/dispatch/router.js.map +1 -1
  17. package/dist/core/index.d.ts +2 -2
  18. package/dist/core/index.d.ts.map +1 -1
  19. package/dist/core/index.js.map +1 -1
  20. package/dist/core/kernel.d.ts +8 -0
  21. package/dist/core/kernel.d.ts.map +1 -1
  22. package/dist/core/kernel.js +17 -0
  23. package/dist/core/kernel.js.map +1 -1
  24. package/dist/core/logging/log-buffer.d.ts +27 -0
  25. package/dist/core/logging/log-buffer.d.ts.map +1 -0
  26. package/dist/core/logging/log-buffer.js +71 -0
  27. package/dist/core/logging/log-buffer.js.map +1 -0
  28. package/dist/core/logging/logger.d.ts +3 -0
  29. package/dist/core/logging/logger.d.ts.map +1 -1
  30. package/dist/core/logging/logger.js +6 -3
  31. package/dist/core/logging/logger.js.map +1 -1
  32. package/dist/core/storage/session.d.ts +15 -0
  33. package/dist/core/storage/session.d.ts.map +1 -1
  34. package/dist/core/storage/session.js +55 -0
  35. package/dist/core/storage/session.js.map +1 -1
  36. package/dist/core/web/api.d.ts +16 -0
  37. package/dist/core/web/api.d.ts.map +1 -0
  38. package/dist/core/web/api.js +617 -0
  39. package/dist/core/web/api.js.map +1 -0
  40. package/dist/core/web/auth.d.ts +43 -0
  41. package/dist/core/web/auth.d.ts.map +1 -0
  42. package/dist/core/web/auth.js +161 -0
  43. package/dist/core/web/auth.js.map +1 -0
  44. package/dist/core/web/config-store.d.ts +30 -0
  45. package/dist/core/web/config-store.d.ts.map +1 -0
  46. package/dist/core/web/config-store.js +216 -0
  47. package/dist/core/web/config-store.js.map +1 -0
  48. package/dist/core/web/event-feed.d.ts +26 -0
  49. package/dist/core/web/event-feed.d.ts.map +1 -0
  50. package/dist/core/web/event-feed.js +107 -0
  51. package/dist/core/web/event-feed.js.map +1 -0
  52. package/dist/core/web/http.d.ts +39 -0
  53. package/dist/core/web/http.d.ts.map +1 -0
  54. package/dist/core/web/http.js +233 -0
  55. package/dist/core/web/http.js.map +1 -0
  56. package/dist/core/web/index.d.ts +11 -0
  57. package/dist/core/web/index.d.ts.map +1 -0
  58. package/dist/core/web/index.js +6 -0
  59. package/dist/core/web/index.js.map +1 -0
  60. package/dist/core/web/server.d.ts +30 -0
  61. package/dist/core/web/server.d.ts.map +1 -0
  62. package/dist/core/web/server.js +437 -0
  63. package/dist/core/web/server.js.map +1 -0
  64. package/dist/core/web/types.d.ts +84 -0
  65. package/dist/core/web/types.d.ts.map +1 -0
  66. package/dist/core/web/types.js +2 -0
  67. package/dist/core/web/types.js.map +1 -0
  68. package/dist/webui/assets/ActionsView-BDuXBWG1.js +1 -0
  69. package/dist/webui/assets/ActionsView-Ciib5lC6.css +1 -0
  70. package/dist/webui/assets/ConfigView-B3Gv2uRG.js +1 -0
  71. package/dist/webui/assets/ConfigView-CrEpss2y.css +1 -0
  72. package/dist/webui/assets/DashboardView-DR6yCaqs.css +1 -0
  73. package/dist/webui/assets/DashboardView-n9LGPmQL.js +1 -0
  74. package/dist/webui/assets/EventsView-DhO8twWb.js +1 -0
  75. package/dist/webui/assets/EventsView-PMkYKxZ-.css +1 -0
  76. package/dist/webui/assets/KvView-BCz_dOVC.js +1 -0
  77. package/dist/webui/assets/KvView-CaMvbxUz.css +1 -0
  78. package/dist/webui/assets/LoginView-BVnFkwSW.css +1 -0
  79. package/dist/webui/assets/LoginView-Br3_AC5z.js +1 -0
  80. package/dist/webui/assets/LogsView-Ba_12frI.js +1 -0
  81. package/dist/webui/assets/LogsView-NR4L1-XY.css +1 -0
  82. package/dist/webui/assets/MainLayout-D2LTc57u.js +1 -0
  83. package/dist/webui/assets/MainLayout-glfVNbMz.css +1 -0
  84. package/dist/webui/assets/PluginsView-DL9OxGph.css +1 -0
  85. package/dist/webui/assets/PluginsView-vQKBSCU8.js +1 -0
  86. package/dist/webui/assets/SessionsView-DSl37qpo.js +1 -0
  87. package/dist/webui/assets/SessionsView-p-u3JGTV.css +1 -0
  88. package/dist/webui/assets/api-CNzxhTWe.js +3 -0
  89. package/dist/webui/assets/index-CUvpnClx.js +50 -0
  90. package/dist/webui/assets/index-CePlRZX6.css +1 -0
  91. package/dist/webui/index.html +110 -0
  92. package/docs/webui.md +142 -0
  93. package/package.json +14 -3
  94. package/src/app.ts +286 -118
  95. package/src/core/client.ts +4 -0
  96. package/src/core/config/schema.ts +40 -0
  97. package/src/core/dispatch/router.ts +15 -0
  98. package/src/core/index.ts +3 -0
  99. package/src/core/kernel.ts +25 -1
  100. package/src/core/logging/log-buffer.ts +109 -0
  101. package/src/core/logging/logger.ts +7 -3
  102. package/src/core/storage/session.ts +95 -0
  103. package/src/core/web/api.ts +932 -0
  104. package/src/core/web/auth.ts +245 -0
  105. package/src/core/web/config-store.ts +333 -0
  106. package/src/core/web/event-feed.ts +163 -0
  107. package/src/core/web/http.ts +340 -0
  108. package/src/core/web/index.ts +25 -0
  109. package/src/core/web/server.ts +621 -0
  110. package/src/core/web/types.ts +100 -0
@@ -0,0 +1,437 @@
1
+ import { createServer, } from 'node:http';
2
+ import { createReadStream, readFileSync } from 'node:fs';
3
+ import { stat } from 'node:fs/promises';
4
+ import { extname, join, resolve, sep } from 'node:path';
5
+ import { createHash } from 'node:crypto';
6
+ import { AuthManager } from './auth.js';
7
+ import { handleApiRoute } from './api.js';
8
+ import { assertCsrf, assertSameOrigin, clearCookie, clientIp, isImmutableAsset, mimeType, parseCookies, readJsonBody, respondWithError, safeStringify, sendError, sendData, serializeCookie, withTimeout, } from './http.js';
9
+ import { HttpError } from './http.js';
10
+ const SESSION_COOKIE = 'jsbot_webui';
11
+ const WRITE_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
12
+ const SECURITY_HEADERS = {
13
+ 'x-content-type-options': 'nosniff',
14
+ 'x-frame-options': 'DENY',
15
+ 'referrer-policy': 'no-referrer',
16
+ 'cross-origin-opener-policy': 'same-origin',
17
+ };
18
+ /**
19
+ * CSP for the WebUI. webui/index.html ships a single authorized inline
20
+ * script (the no-flash appearance bootstrap for the first paint); its exact
21
+ * hash is derived from the built index.html on disk so editing the bootstrap
22
+ * only needs a rebuild, never a source edit. Every other inline script
23
+ * stays blocked.
24
+ */
25
+ function buildCsp(scriptSrc) {
26
+ return `default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src ${scriptSrc}; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'`;
27
+ }
28
+ /** Extracts the bootstrap script's sha256 from a built index.html. */
29
+ function cspForStaticDir(staticDir) {
30
+ try {
31
+ const html = readFileSync(join(staticDir, 'index.html'), 'utf8');
32
+ const match = /<script>([\s\S]*?)<\/script>/.exec(html);
33
+ const bootstrap = match?.[1];
34
+ if (bootstrap === undefined)
35
+ return null;
36
+ const hash = createHash('sha256')
37
+ .update(bootstrap, 'utf8')
38
+ .digest('base64');
39
+ return buildCsp(`'self' 'sha256-${hash}'`);
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ const SSE_HEARTBEAT_MS = 15_000;
46
+ const DEFAULT_MAX_SSE_CLIENTS = 20;
47
+ const SSE_TIMEOUT_MS = 60_000;
48
+ const FALLBACK_BODY = (options) => `<!doctype html>
49
+ <html lang="zh-CN"><head><meta charset="utf-8">
50
+ <title>JsBot WebUI</title>
51
+ <style>body{font-family:system-ui,sans-serif;max-width:36em;margin:4rem auto;padding:0 1rem;color:#333}</style>
52
+ </head><body>
53
+ <h1>WebUI 前端未构建</h1>
54
+ <p>管理 API 正常运行,但静态资源缺失。请在项目根目录执行:</p>
55
+ <pre><code>npm run build:webui</code></pre>
56
+ <p>然后重启进程,访问 <code>${options.listening}</code>。</p>
57
+ <p>API 仍可通过 <code>/api/health</code>、登录和各接口访问。</p>
58
+ </body></html>
59
+ `;
60
+ function errorPayload(error) {
61
+ if (error instanceof HttpError) {
62
+ return {
63
+ status: error.status,
64
+ message: error.message,
65
+ details: error.details,
66
+ };
67
+ }
68
+ return {
69
+ status: 500,
70
+ message: error instanceof Error ? error.message : 'internal error',
71
+ details: undefined,
72
+ };
73
+ }
74
+ function parseSearch(req) {
75
+ const index = (req.url ?? '').indexOf('?');
76
+ const query = index >= 0 ? (req.url ?? '').slice(index + 1) : '';
77
+ return new URLSearchParams(query);
78
+ }
79
+ function segmentsOf(pathname) {
80
+ return pathname
81
+ .split('/')
82
+ .filter((segment) => segment.length > 0)
83
+ .map((segment) => {
84
+ try {
85
+ return decodeURIComponent(segment);
86
+ }
87
+ catch {
88
+ return segment;
89
+ }
90
+ });
91
+ }
92
+ function pathnameOf(req) {
93
+ const url = req.url ?? '/';
94
+ const index = url.indexOf('?');
95
+ const raw = index >= 0 ? url.slice(0, index) : url;
96
+ if (raw.includes('%')) {
97
+ try {
98
+ return decodeURIComponent(raw);
99
+ }
100
+ catch {
101
+ return raw;
102
+ }
103
+ }
104
+ return raw;
105
+ }
106
+ export class WebUiServer {
107
+ deps;
108
+ maxSseClients;
109
+ bodyLimit;
110
+ loginMaxFailures;
111
+ loginWindowMs;
112
+ auth;
113
+ sse = new Set();
114
+ fallbackBody;
115
+ httpServer = null;
116
+ listening = null;
117
+ cspCache = null;
118
+ constructor(options) {
119
+ const { config, deps } = options;
120
+ this.deps = deps;
121
+ this.maxSseClients = options.maxSseClients ?? DEFAULT_MAX_SSE_CLIENTS;
122
+ this.bodyLimit = options.bodyLimitBytes ?? 1_048_576;
123
+ this.loginMaxFailures = options.loginMaxFailures;
124
+ this.loginWindowMs = options.loginWindowMs;
125
+ this.fallbackBody = FALLBACK_BODY({
126
+ listening: `http://${config.host}:${config.port}`,
127
+ });
128
+ this.auth = new AuthManager({
129
+ getConfig: () => deps.getWebUiConfig(),
130
+ ...(options.loginMaxFailures !== undefined
131
+ ? { maxFailures: options.loginMaxFailures }
132
+ : {}),
133
+ ...(options.loginWindowMs !== undefined
134
+ ? { windowMs: options.loginWindowMs }
135
+ : {}),
136
+ });
137
+ }
138
+ get address() {
139
+ return this.listening;
140
+ }
141
+ async start(config) {
142
+ if (this.httpServer !== null)
143
+ return this.listening;
144
+ const server = createServer(this.handleRequest.bind(this));
145
+ try {
146
+ await new Promise((resolvePromise, reject) => {
147
+ server.once('error', reject);
148
+ server.listen(config.port, config.host, () => {
149
+ server.off('error', reject);
150
+ resolvePromise();
151
+ });
152
+ });
153
+ const address = server.address();
154
+ if (address === null) {
155
+ this.listening = {
156
+ host: config.host,
157
+ port: config.port,
158
+ };
159
+ }
160
+ else if (typeof address === 'string') {
161
+ this.listening = { host: address, port: config.port };
162
+ }
163
+ else {
164
+ this.listening = {
165
+ host: config.host,
166
+ port: address.port,
167
+ };
168
+ }
169
+ this.httpServer = server;
170
+ this.deps.logger.info(`webui listening on http://${config.host}:${this.listening.port}`);
171
+ return this.listening;
172
+ }
173
+ catch (error) {
174
+ this.deps.logger.error('webui listen failed', error);
175
+ server.close();
176
+ return null;
177
+ }
178
+ }
179
+ get requiresRestart() {
180
+ return this.httpServer !== null;
181
+ }
182
+ async stop() {
183
+ for (const connection of [...this.sse])
184
+ connection.close();
185
+ this.sse.clear();
186
+ this.auth.invalidateAll();
187
+ const server = this.httpServer;
188
+ if (server === null)
189
+ return;
190
+ this.httpServer = null;
191
+ this.listening = null;
192
+ await new Promise((resolvePromise) => {
193
+ server.close(() => resolvePromise());
194
+ });
195
+ }
196
+ invalidateSessions() {
197
+ this.auth.invalidateAll();
198
+ }
199
+ applySecurityHeaders(res) {
200
+ for (const [key, value] of Object.entries(SECURITY_HEADERS)) {
201
+ res.setHeader(key, value);
202
+ }
203
+ if (this.cspCache === null) {
204
+ // Derived once per server instance from the built index.html.
205
+ const staticDir = this.deps.paths.staticDir;
206
+ this.cspCache =
207
+ staticDir !== null
208
+ ? (cspForStaticDir(staticDir) ?? buildCsp("'self'"))
209
+ : buildCsp("'self'");
210
+ }
211
+ res.setHeader('content-security-policy', this.cspCache);
212
+ }
213
+ async handleRequest(req, res) {
214
+ this.applySecurityHeaders(res);
215
+ try {
216
+ const pathname = pathnameOf(req);
217
+ if (pathname === '/api/health') {
218
+ res.setHeader('cache-control', 'no-store');
219
+ sendData(res, 200, { ok: true });
220
+ return;
221
+ }
222
+ if (!pathname.startsWith('/api/') && pathname !== '/api') {
223
+ await this.serveStatic(req, res, pathname);
224
+ return;
225
+ }
226
+ if (!WRITE_METHODS.has(req.method ?? 'GET')) {
227
+ assertSameOrigin(req, this.deps.getWebUiConfig().trustProxy);
228
+ }
229
+ else {
230
+ assertSameOrigin(req, this.deps.getWebUiConfig().trustProxy);
231
+ assertCsrf(req);
232
+ }
233
+ const segments = segmentsOf(pathname);
234
+ if (segments[1] === 'auth') {
235
+ await this.handleAuth(req, res, segments[2]);
236
+ return;
237
+ }
238
+ const session = this.authenticate(req);
239
+ if (session === null) {
240
+ throw new HttpError(401, '未登录或会话已过期');
241
+ }
242
+ if (segments[1] === 'logs' && segments[2] === 'stream') {
243
+ this.openSse(req, res, (listener) => this.deps.logs.subscribe(listener), Date.now());
244
+ return;
245
+ }
246
+ if (segments[1] === 'events' && segments[2] === 'stream') {
247
+ this.openSse(req, res, (listener) => this.deps.events.subscribe(listener), Date.now());
248
+ return;
249
+ }
250
+ const handled = await handleApiRoute({
251
+ deps: this.deps,
252
+ req,
253
+ res,
254
+ method: req.method ?? 'GET',
255
+ pathname,
256
+ segments,
257
+ search: parseSearch(req),
258
+ session,
259
+ });
260
+ if (handled)
261
+ return;
262
+ throw new HttpError(404, `not found: ${req.method} ${pathname}`);
263
+ }
264
+ catch (error) {
265
+ respondWithError(res, error);
266
+ }
267
+ }
268
+ authenticate(req) {
269
+ const cookies = parseCookies(req.headers.cookie);
270
+ return this.auth.authenticate(cookies[SESSION_COOKIE]);
271
+ }
272
+ async handleAuth(req, res, action) {
273
+ const method = req.method ?? 'GET';
274
+ if (action === 'login' && method === 'POST') {
275
+ const body = await readJsonBody(req, this.bodyLimit);
276
+ const value = typeof body === 'object' && body !== null
277
+ ? body
278
+ : {};
279
+ const ip = clientIp(req, this.deps.getWebUiConfig().trustProxy);
280
+ const result = await this.auth.login(value['username'], value['password'], ip);
281
+ if (!result.ok || !result.session) {
282
+ const headers = {};
283
+ if (result.retryAfterSeconds !== undefined) {
284
+ headers['retry-after'] = String(result.retryAfterSeconds);
285
+ }
286
+ sendError(res, result.status, result.message ?? 'login failed', undefined, headers);
287
+ return;
288
+ }
289
+ res.setHeader('set-cookie', serializeCookie(SESSION_COOKIE, result.session.token, {
290
+ maxAgeSeconds: this.deps.getWebUiConfig().sessionTtlHours * 3600,
291
+ secure: this.isSecure(req),
292
+ }));
293
+ sendData(res, result.status, {
294
+ username: result.session.username,
295
+ expiresAt: result.session.expiresAt,
296
+ });
297
+ return;
298
+ }
299
+ if (action === 'logout' && method === 'POST') {
300
+ const session = this.authenticate(req);
301
+ this.auth.logout(this.tokenOf(req));
302
+ this.deps.logger.info(`webui logout: ${session?.username ?? 'unknown'}`);
303
+ res.setHeader('set-cookie', clearCookie(SESSION_COOKIE));
304
+ sendData(res, 200, { ok: true });
305
+ return;
306
+ }
307
+ if (action === 'me' && method === 'GET') {
308
+ const session = this.authenticate(req);
309
+ if (session === null) {
310
+ throw new HttpError(401, '未登录或会话已过期');
311
+ }
312
+ sendData(res, 200, {
313
+ username: session.username,
314
+ expiresAt: session.expiresAt,
315
+ });
316
+ return;
317
+ }
318
+ throw new HttpError(404, `not found: ${method} /api/auth/${action ?? ''}`);
319
+ }
320
+ tokenOf(req) {
321
+ const cookies = parseCookies(req.headers.cookie);
322
+ return cookies[SESSION_COOKIE];
323
+ }
324
+ isSecure(req) {
325
+ if (!this.deps.getWebUiConfig().trustProxy)
326
+ return false;
327
+ const proto = req.headers['x-forwarded-proto'];
328
+ return (typeof proto === 'string' && proto.split(',')[0]?.trim() === 'https');
329
+ }
330
+ openSse(req, res, subscribe, openedAt) {
331
+ if (this.sse.size >= this.maxSseClients) {
332
+ throw new HttpError(503, '实时连接数量已达上限');
333
+ }
334
+ res.writeHead(200, {
335
+ 'content-type': 'text/event-stream; charset=utf-8',
336
+ 'cache-control': 'no-store, no-transform',
337
+ connection: 'keep-alive',
338
+ });
339
+ res.write(':ok\n\n');
340
+ const connection = {
341
+ res,
342
+ close: () => {
343
+ unsubscribe();
344
+ clearInterval(heartbeat);
345
+ this.sse.delete(connection);
346
+ try {
347
+ res.end();
348
+ }
349
+ catch {
350
+ // Already closed.
351
+ }
352
+ },
353
+ };
354
+ let closing = false;
355
+ const unsubscribe = subscribe((entry) => {
356
+ if (closing)
357
+ return;
358
+ res.write(`data: ${safeStringify(entry)}\n\n`);
359
+ });
360
+ const heartbeat = setInterval(() => {
361
+ res.write(`:keepalive ${Date.now() - openedAt}\n\n`);
362
+ }, SSE_HEARTBEAT_MS);
363
+ req.on('close', () => {
364
+ if (closing)
365
+ return;
366
+ closing = true;
367
+ unsubscribe();
368
+ clearInterval(heartbeat);
369
+ this.sse.delete(connection);
370
+ });
371
+ this.sse.add(connection);
372
+ }
373
+ async serveStatic(req, res, pathname) {
374
+ if (req.method !== 'GET' && req.method !== 'HEAD') {
375
+ throw new HttpError(405, `method not allowed: ${req.method}`);
376
+ }
377
+ const staticDir = this.deps.paths.staticDir;
378
+ if (staticDir === null) {
379
+ res.setHeader('content-type', 'text/html; charset=utf-8');
380
+ res.setHeader('cache-control', 'no-store');
381
+ res.writeHead(503);
382
+ res.end(this.fallbackBody);
383
+ return;
384
+ }
385
+ const cleaned = pathname.replace(/\/+$/, '') || '/';
386
+ let filePath = cleaned === '/'
387
+ ? join(staticDir, 'index.html')
388
+ : resolve(staticDir, `.${cleaned}`);
389
+ if (!filePath.startsWith(staticDir + sep) && filePath !== staticDir) {
390
+ throw new HttpError(403, 'forbidden');
391
+ }
392
+ let fileStat = await this.statOrNull(filePath);
393
+ if (fileStat?.isDirectory()) {
394
+ filePath = join(filePath, 'index.html');
395
+ fileStat = await this.statOrNull(filePath);
396
+ }
397
+ if (fileStat === null) {
398
+ // SPA fallback: only routes without a file extension.
399
+ if (extname(cleaned) === '') {
400
+ filePath = join(staticDir, 'index.html');
401
+ fileStat = await this.statOrNull(filePath);
402
+ }
403
+ if (fileStat === null)
404
+ throw new HttpError(404, 'not found');
405
+ }
406
+ const cacheControl = isImmutableAsset(cleaned)
407
+ ? 'public, max-age=31536000, immutable'
408
+ : 'no-cache';
409
+ res.setHeader('content-type', mimeType(filePath));
410
+ res.setHeader('cache-control', cacheControl);
411
+ res.setHeader('content-length', String(fileStat.size));
412
+ res.writeHead(200);
413
+ if (req.method === 'HEAD') {
414
+ res.end();
415
+ return;
416
+ }
417
+ const stream = createReadStream(filePath);
418
+ stream.on('error', () => {
419
+ try {
420
+ res.end();
421
+ }
422
+ catch {
423
+ // Already closed.
424
+ }
425
+ });
426
+ stream.pipe(res);
427
+ }
428
+ async statOrNull(filePath) {
429
+ try {
430
+ return await withTimeout(stat(filePath), 1_000);
431
+ }
432
+ catch {
433
+ return null;
434
+ }
435
+ }
436
+ }
437
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/core/web/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import type { BotApi } from '../api.js';
2
+ import type { AppConfig, WebUiConfig } from '../config/schema.js';
3
+ import type { Kernel } from '../kernel.js';
4
+ import type { LogBuffer } from '../logging/log-buffer.js';
5
+ import type { Logger } from '../logging/logger.js';
6
+ import type { AnyPluginDefinition, PluginInstaller } from '../plugin/types.js';
7
+ import type { Database } from '../storage/database.js';
8
+ import type { EventFeed } from './event-feed.js';
9
+ export interface WebUiRuntime {
10
+ generation: number;
11
+ config: AppConfig;
12
+ kernel: Kernel;
13
+ api: BotApi;
14
+ database: Database;
15
+ installer: PluginInstaller;
16
+ plugins: AnyPluginDefinition[];
17
+ }
18
+ export interface WebUiPaths {
19
+ configPath: string;
20
+ dataDir: string;
21
+ pluginDir: string;
22
+ staticDir: string | null;
23
+ }
24
+ export interface WebUiAddress {
25
+ host: string;
26
+ port: number;
27
+ }
28
+ export interface ConfigDocument {
29
+ path: string;
30
+ raw: string;
31
+ hash: string;
32
+ config: AppConfig;
33
+ }
34
+ export interface ConfigValidationIssue {
35
+ path: string;
36
+ message: string;
37
+ }
38
+ export interface ConfigValidationResult {
39
+ ok: boolean;
40
+ issues: ConfigValidationIssue[];
41
+ config?: AppConfig;
42
+ }
43
+ export interface ConfigApplyResult {
44
+ ok: boolean;
45
+ hash?: string;
46
+ issues?: ConfigValidationIssue[];
47
+ error?: string;
48
+ }
49
+ export interface WebUiDeps {
50
+ logger: Logger;
51
+ paths: WebUiPaths;
52
+ version: string;
53
+ logs: LogBuffer;
54
+ events: EventFeed;
55
+ /** Current webui settings; picked up after runtime restarts. */
56
+ getWebUiConfig(): WebUiConfig;
57
+ readConfig(): Promise<ConfigDocument>;
58
+ validateConfig(value: unknown): Promise<ConfigValidationResult>;
59
+ applyConfig(value: unknown, baseHash?: string | undefined): Promise<ConfigApplyResult>;
60
+ restart(): Promise<boolean>;
61
+ requestRestart(): void;
62
+ pause(): void;
63
+ resume(): void;
64
+ getListening(): WebUiAddress | null;
65
+ invalidateSessions(): void;
66
+ runExclusive<T>(task: () => Promise<T>): Promise<T>;
67
+ getRuntime(): WebUiRuntime | null;
68
+ isRestarting(): boolean;
69
+ getStartupError(): string | null;
70
+ getRequiresProcessRestart(): boolean;
71
+ }
72
+ export interface WebUiServerOptions {
73
+ config: WebUiConfig;
74
+ deps: WebUiDeps;
75
+ /** Maximum number of concurrent SSE clients. Defaults to 20. */
76
+ maxSseClients?: number | undefined;
77
+ /** Maximum JSON request body size. Defaults to 1 MiB. */
78
+ bodyLimitBytes?: number | undefined;
79
+ /** Login failures allowed per IP inside the window. Defaults to 5. */
80
+ loginMaxFailures?: number | undefined;
81
+ /** Login failure window. Defaults to 15 minutes. */
82
+ loginWindowMs?: number | undefined;
83
+ }
84
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/web/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC9E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,WAAW,YAAY;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,SAAS,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,EAAE,eAAe,CAAA;IAC1B,OAAO,EAAE,mBAAmB,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,SAAS,CAAA;CACpB;AAED,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,qBAAqB,EAAE,CAAA;IAC/B,MAAM,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,UAAU,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,SAAS,CAAA;IAEjB,gEAAgE;IAChE,cAAc,IAAI,WAAW,CAAA;IAE7B,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAAA;IACrC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IAC/D,WAAW,CACP,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAE7B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3B,cAAc,IAAI,IAAI,CAAA;IACtB,KAAK,IAAI,IAAI,CAAA;IACb,MAAM,IAAI,IAAI,CAAA;IAEd,YAAY,IAAI,YAAY,GAAG,IAAI,CAAA;IACnC,kBAAkB,IAAI,IAAI,CAAA;IAC1B,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAEnD,UAAU,IAAI,YAAY,GAAG,IAAI,CAAA;IACjC,YAAY,IAAI,OAAO,CAAA;IACvB,eAAe,IAAI,MAAM,GAAG,IAAI,CAAA;IAChC,yBAAyB,IAAI,OAAO,CAAA;CACvC;AAED,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,WAAW,CAAA;IACnB,IAAI,EAAE,SAAS,CAAA;IACf,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/web/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ import{Ki as e,Ri as t,Si as n,Ti as r,c as i,ci as a,d as o,f as s,ga as c,ii as l,ki as u,li as d,p as f,r as p,si as m,ti as h}from"./api-CNzxhTWe.js";var g={class:`result`},_=s(d({__name:`ActionsView`,setup(s){let d=e(`get_login_info`),_=e(`{}`),v=e(``),y=e(!1),b=e(!0),x=async()=>{let e={};if(_.value.trim().length>0&&_.value.trim()!==`{}`)try{e=JSON.parse(_.value)}catch{f.error(`params 必须是合法 JSON`);return}y.value=!0;try{let t=await p(`/api/actions`,{action:d.value,params:e});v.value=JSON.stringify(t.result,void 0,2)}catch(e){o(e)}finally{y.value=!1}};return n(()=>{i().then(e=>{b.value=e.runtime===null}).catch(()=>{b.value=!0})}),(e,n)=>{let i=u(`el-alert`),o=u(`el-input`),s=u(`el-form-item`),f=u(`el-button`),p=u(`el-form`),S=u(`el-divider`),C=u(`el-card`);return r(),l(`div`,null,[a(i,{title:`直接向 OneBot 调用任意 action。此功能等同完全特权接口,请谨慎使用。`,type:`warning`,closable:!1,class:`block`}),a(C,{class:`block`},{default:t(()=>[a(p,{"label-width":`100px`,size:`small`},{default:t(()=>[a(s,{label:`action`},{default:t(()=>[a(o,{modelValue:d.value,"onUpdate:modelValue":n[0]||=e=>d.value=e,placeholder:`如 get_login_info / send_private_msg`,style:{width:`320px`}},null,8,[`modelValue`])]),_:1}),a(s,{label:`params (JSON)`},{default:t(()=>[a(o,{modelValue:_.value,"onUpdate:modelValue":n[1]||=e=>_.value=e,type:`textarea`,rows:5,spellcheck:`false`,placeholder:`{}`},null,8,[`modelValue`])]),_:1}),a(s,null,{default:t(()=>[a(f,{type:`primary`,loading:y.value,disabled:b.value,onClick:x},{default:t(()=>[...n[2]||=[m(` 调用 `,-1)]]),_:1},8,[`loading`,`disabled`])]),_:1})]),_:1}),a(S,null,{default:t(()=>[...n[3]||=[m(`结果`,-1)]]),_:1}),h(`pre`,g,c(v.value),1)]),_:1})])}}}),[[`__scopeId`,`data-v-ceeaf662`]]);export{_ as default};
@@ -0,0 +1 @@
1
+ .block[data-v-ceeaf662]{margin-bottom:16px}.result[data-v-ceeaf662]{background:var(--app-bg);border:1px solid var(--app-border);color:var(--app-text);white-space:pre-wrap;border-radius:10px;min-height:80px;margin:0;padding:12px;font-family:SF Mono,ui-monospace,Menlo,Consolas,monospace;font-size:12px}
@@ -0,0 +1 @@
1
+ import{Di as e,Ki as t,Ri as n,Si as r,Ti as i,Xr as a,ci as o,d as s,f as c,ga as l,i as u,ii as d,ki as f,li as p,n as m,ni as h,p as g,r as _,ri as v,si as y,ti as b}from"./api-CNzxhTWe.js";var x={class:`block`},S={class:`issues`},C=c(p({__name:`ConfigView`,setup(c){let p=t(`form`),C=t({url:``,accessToken:``,roles:{superadmin:[],admin:[]},message:{charThreshold:50,lineThreshold:3},webui:{enabled:!1,host:`127.0.0.1`,port:8787,username:``,password:``,sessionTtlHours:12,trustProxy:!1},installer:{enabled:!1,registry:`https://registry.npmjs.org/`,allowedPackages:[],allowScripts:!1,timeoutMs:12e4}}),w=t(``),T=t({path:``,hash:``,accessTokenSet:!1,webuiPasswordSet:!1}),E=t(``),D=t([]),O=t(!1),k=()=>{let e=JSON.parse(JSON.stringify(C.value)),t=e.webui;return w.value===``?delete t.password:t.password=w.value,e.accessToken===``&&delete e.accessToken,e},A=()=>{E.value=JSON.stringify(k(),null,4)},j=()=>{try{let e=JSON.parse(E.value),t=e.webui??{};typeof t.password==`string`&&(w.value=t.password===``?``:`00000000`),typeof e.accessToken==`string`&&e.accessToken===``?e.accessToken=``:typeof e.accessToken==`string`&&(e.accessToken=`00000000`),C.value=e,g.success(`已应用到表单`)}catch(e){g.error(`JSON 格式错误`),console.warn(e)}},M=async e=>{let t=await _(`/api/config/validate`,{config:e});return D.value=t.issues,t.ok},N=async()=>{O.value=!0;try{await M(k())&&g.success(`校验通过`)}catch(e){s(e)}finally{O.value=!1}},P=async()=>{let e;try{e=JSON.parse(E.value)}catch{g.error(`JSON 格式错误`);return}await I(e,w.value)},F=async()=>{let e=k();w.value=e.webui.password,await I(e,w.value),D.value=[]},I=async(e,t)=>{O.value=!0;try{if(!await M(e)&&D.value.length>0){g.error(`校验失败`);return}let t=await u(`/api/config`,{config:e,baseHash:T.value.hash});if(!t.ok){g.error(t.error??`保存失败`);return}g.success(`已保存并重启运行时`),await L()}catch(e){s(e)}finally{O.value=!1}},L=async()=>{try{let e=await m(`/api/config`);C.value=e.config,T.value=e.meta,w.value=(e.meta.webuiPasswordSet&&e.config.webui.password,``),E.value=JSON.stringify(e.config,null,4)}catch(e){s(e)}},R=e=>e.join(`, `);function z(e,t,n,r){let i=n.split(/[,,]/).map(e=>e.trim()).filter(e=>e.length>0);e[t]=r?i.map(r):i}return r(()=>void L()),(t,r)=>{let s=f(`el-divider`),c=f(`el-input`),u=f(`el-form-item`),m=f(`el-switch`),g=f(`el-input-number`),_=f(`el-space`),k=f(`el-button`),M=f(`el-form`),I=f(`el-tab-pane`),L=f(`el-tabs`),B=f(`el-alert`);return i(),d(`div`,null,[o(L,{modelValue:p.value,"onUpdate:modelValue":r[19]||=e=>p.value=e},{default:n(()=>[o(I,{label:`常用设置`,name:`form`},{default:n(()=>[o(M,{"label-width":`140px`,size:`small`,class:`form`},{default:n(()=>[o(s,{"content-position":`left`},{default:n(()=>[...r[20]||=[y(`连接`,-1)]]),_:1}),o(u,{label:`ws url`},{default:n(()=>[o(c,{modelValue:C.value.url,"onUpdate:modelValue":r[0]||=e=>C.value.url=e},null,8,[`modelValue`])]),_:1}),o(u,{label:`accessToken`},{default:n(()=>[o(c,{modelValue:C.value.accessToken,"onUpdate:modelValue":r[1]||=e=>C.value.accessToken=e,placeholder:T.value.accessTokenSet?`留空保持不变`:`未设置`},null,8,[`modelValue`,`placeholder`])]),_:1}),o(s,{"content-position":`left`},{default:n(()=>[...r[21]||=[y(`WebUI`,-1)]]),_:1}),o(u,{label:`enabled`},{default:n(()=>[o(m,{modelValue:C.value.webui.enabled,"onUpdate:modelValue":r[2]||=e=>C.value.webui.enabled=e},null,8,[`modelValue`])]),_:1}),o(u,{label:`host / port`},{default:n(()=>[o(_,null,{default:n(()=>[o(c,{modelValue:C.value.webui.host,"onUpdate:modelValue":r[3]||=e=>C.value.webui.host=e,style:{width:`160px`}},null,8,[`modelValue`]),o(g,{modelValue:C.value.webui.port,"onUpdate:modelValue":r[4]||=e=>C.value.webui.port=e,min:1,max:65535},null,8,[`modelValue`])]),_:1})]),_:1}),o(u,{label:`username`},{default:n(()=>[o(c,{modelValue:C.value.webui.username,"onUpdate:modelValue":r[5]||=e=>C.value.webui.username=e,style:{width:`200px`}},null,8,[`modelValue`])]),_:1}),o(u,{label:`password`},{default:n(()=>[o(c,{modelValue:w.value,"onUpdate:modelValue":r[6]||=e=>w.value=e,"show-password":``,placeholder:T.value.webuiPasswordSet?`留空保持不变`:`未设置`,style:{width:`240px`}},null,8,[`modelValue`,`placeholder`])]),_:1}),o(u,{label:`sessionTtlHours`},{default:n(()=>[o(g,{modelValue:C.value.webui.sessionTtlHours,"onUpdate:modelValue":r[7]||=e=>C.value.webui.sessionTtlHours=e,min:1,max:720},null,8,[`modelValue`])]),_:1}),o(u,{label:`trustProxy`},{default:n(()=>[o(m,{modelValue:C.value.webui.trustProxy,"onUpdate:modelValue":r[8]||=e=>C.value.webui.trustProxy=e},null,8,[`modelValue`])]),_:1}),o(s,{"content-position":`left`},{default:n(()=>[...r[22]||=[y(`消息聚合`,-1)]]),_:1}),o(u,{label:`charThreshold`},{default:n(()=>[o(g,{modelValue:C.value.message.charThreshold,"onUpdate:modelValue":r[9]||=e=>C.value.message.charThreshold=e,min:1},null,8,[`modelValue`])]),_:1}),o(u,{label:`lineThreshold`},{default:n(()=>[o(g,{modelValue:C.value.message.lineThreshold,"onUpdate:modelValue":r[10]||=e=>C.value.message.lineThreshold=e,min:1},null,8,[`modelValue`])]),_:1}),o(s,{"content-position":`left`},{default:n(()=>[...r[23]||=[y(`安装器`,-1)]]),_:1}),o(u,{label:`enabled`},{default:n(()=>[o(m,{modelValue:C.value.installer.enabled,"onUpdate:modelValue":r[11]||=e=>C.value.installer.enabled=e},null,8,[`modelValue`])]),_:1}),o(u,{label:`registry`},{default:n(()=>[o(c,{modelValue:C.value.installer.registry,"onUpdate:modelValue":r[12]||=e=>C.value.installer.registry=e},null,8,[`modelValue`])]),_:1}),o(u,{label:`allowedPackages`},{default:n(()=>[o(c,{"model-value":R(C.value.installer.allowedPackages),"onUpdate:modelValue":r[13]||=e=>z(C.value.installer,`allowedPackages`,e)},null,8,[`model-value`])]),_:1}),o(u,{label:`allowScripts`},{default:n(()=>[o(m,{modelValue:C.value.installer.allowScripts,"onUpdate:modelValue":r[14]||=e=>C.value.installer.allowScripts=e},null,8,[`modelValue`])]),_:1}),o(u,{label:`timeoutMs`},{default:n(()=>[o(g,{modelValue:C.value.installer.timeoutMs,"onUpdate:modelValue":r[15]||=e=>C.value.installer.timeoutMs=e,min:1e3,max:6e5},null,8,[`modelValue`])]),_:1}),o(s,{"content-position":`left`},{default:n(()=>[...r[24]||=[y(`角色`,-1)]]),_:1}),o(u,{label:`superadmin`},{default:n(()=>[o(c,{"model-value":R(C.value.roles.superadmin),placeholder:`逗号分隔的 QQ 号`,"onUpdate:modelValue":r[16]||=e=>z(C.value.roles,`superadmin`,e,Number)},null,8,[`model-value`])]),_:1}),o(u,{label:`admin`},{default:n(()=>[o(c,{"model-value":R(C.value.roles.admin),placeholder:`逗号分隔的 QQ 号`,"onUpdate:modelValue":r[17]||=e=>z(C.value.roles,`admin`,e,Number)},null,8,[`model-value`])]),_:1}),o(u,null,{default:n(()=>[o(_,null,{default:n(()=>[o(k,{type:`primary`,loading:O.value,onClick:F},{default:n(()=>[...r[25]||=[y(` 校验并保存 `,-1)]]),_:1},8,[`loading`]),o(k,{onClick:N},{default:n(()=>[...r[26]||=[y(` 仅校验 `,-1)]]),_:1})]),_:1})]),_:1})]),_:1})]),_:1}),o(I,{label:`JSON 编辑器`,name:`json`},{default:n(()=>[o(c,{modelValue:E.value,"onUpdate:modelValue":r[18]||=e=>E.value=e,type:`textarea`,rows:24,spellcheck:`false`,class:`json-editor`},null,8,[`modelValue`]),b(`div`,x,[o(_,null,{default:n(()=>[o(k,{onClick:A},{default:n(()=>[...r[27]||=[y(`从表单生成`,-1)]]),_:1}),o(k,{onClick:j},{default:n(()=>[...r[28]||=[y(`应用到表单`,-1)]]),_:1}),o(k,{type:`primary`,loading:O.value,onClick:P},{default:n(()=>[...r[29]||=[y(` 校验并保存 `,-1)]]),_:1},8,[`loading`])]),_:1})])]),_:1})]),_:1},8,[`modelValue`]),D.value.length>0?(i(),h(B,{key:0,type:`error`,closable:!1,class:`block`},{default:n(()=>[b(`ul`,S,[(i(!0),d(a,null,e(D.value,(e,t)=>(i(),d(`li`,{key:t},l(e.path?e.path+`: `:``)+l(e.message),1))),128))])]),_:1})):v(``,!0)])}}}),[[`__scopeId`,`data-v-3e321bed`]]);export{C as default};
@@ -0,0 +1 @@
1
+ .form[data-v-3e321bed]{max-width:640px}.block[data-v-3e321bed]{margin-top:12px}.json-editor[data-v-3e321bed]{font-family:monospace}.issues[data-v-3e321bed]{margin:0;padding-left:18px;font-size:12px}
@@ -0,0 +1 @@
1
+ .block[data-v-5b803405]{margin-bottom:16px}.stat[data-v-5b803405]{align-items:flex-start;gap:14px;display:flex}.chip[data-v-5b803405]{border-radius:11px;flex:none;justify-content:center;align-items:center;width:40px;height:40px;display:flex}.chip.sky[data-v-5b803405]{color:color-mix(in oklab, var(--app-accent) 85%, black);background:color-mix(in oklab, var(--app-accent) 12%, transparent)}.chip.emerald[data-v-5b803405]{color:var(--app-ok);background:color-mix(in oklab, var(--app-ok) 12%, transparent)}.chip.violet[data-v-5b803405]{color:var(--app-violet);background:color-mix(in oklab, var(--app-violet) 12%, transparent)}.chip.amber[data-v-5b803405]{color:var(--app-warn);background:color-mix(in oklab, var(--app-warn) 12%, transparent)}.label[data-v-5b803405]{color:var(--app-muted);margin:0;font-size:12.5px}.value[data-v-5b803405]{color:var(--app-text);margin:6px 0 0;font-size:21px;font-weight:700;line-height:1.25}.value.small[data-v-5b803405]{font-size:16px}.unit[data-v-5b803405]{color:var(--app-muted);font-size:12px;font-weight:500}.sub[data-v-5b803405]{color:var(--app-muted);word-break:break-all;margin:4px 0 0;font-size:11.5px}.warn-text[data-v-5b803405]{color:var(--app-warn)}.error-text[data-v-5b803405]{white-space:pre-wrap;margin:8px 0 0;font-size:12px}
@@ -0,0 +1 @@
1
+ import{Ci as e,I as t,Ki as n,M as r,Q as i,Ri as a,Si as o,Ti as s,a as c,bt as l,c as u,ci as d,d as f,ea as p,ei as m,f as h,ga as g,ii as _,ki as v,l as y,li as b,ni as x,r as S,ri as C,s as w,si as T,ti as E,u as D}from"./api-CNzxhTWe.js";var O={class:`error-text`},k={class:`stat`},ee={class:`chip sky`},te={class:`value small`},A={class:`sub`},j={class:`stat`},M={class:`chip emerald`},N={class:`value`},P={class:`sub`},F={class:`stat`},I={class:`chip violet`},L={class:`value`},R={class:`unit`},z={class:`sub`},B={class:`stat`},V={class:`chip amber`},H={class:`value`},U={class:`unit`},W={class:`sub`},G={key:0,class:`sub warn-text`},K=h(b({__name:`DashboardView`,setup(h){let b=n(null),K=n([]),q=n([]),J=n(!1),Y=m(()=>b.value?.runtime??null),X=m(()=>Y.value?D(Y.value.uptimeMs):`-`),Z=async()=>{try{b.value=await u()}catch(e){f(e)}},ne=async()=>{J.value=!0;try{await S(`/api/runtime/restart`),await Z()}catch(e){f(e)}finally{J.value=!1}},re=async()=>{try{await S(`/api/runtime/pause`),await Z()}catch(e){f(e)}},ie=async()=>{try{await S(`/api/runtime/resume`),await Z()}catch(e){f(e)}},Q=null,$=null;return o(async()=>{await Z(),K.value=await w().catch(()=>[]),Q=c(`/api/events/stream?limit=20`,e=>{q.value.unshift(e),q.value.length>30&&q.value.pop()});let e=setInterval(()=>void Z(),1e4);$=()=>clearInterval(e)}),e(()=>{Q?.(),$?.()}),(e,n)=>{let o=v(`el-alert`),c=v(`el-icon`),u=v(`el-card`),f=v(`el-col`),m=v(`el-row`),h=v(`el-button`),S=v(`el-space`),w=v(`el-table-column`),D=v(`el-table`);return s(),_(`div`,null,[b.value?.startupError?(s(),x(o,{key:0,title:`运行时启动失败`,type:`error`,closable:!1,class:`block`},{default:a(()=>[E(`pre`,O,g(b.value.startupError),1)]),_:1})):b.value?.restarting?(s(),x(o,{key:1,title:`运行时正在重启…`,type:`warning`,closable:!1,class:`block`})):C(``,!0),d(m,{gutter:16,class:`block`},{default:a(()=>[d(f,{span:6},{default:a(()=>[d(u,{class:`stat-card`},{default:a(()=>[E(`div`,k,[E(`div`,ee,[d(c,{size:18},{default:a(()=>[d(p(i))]),_:1})]),E(`div`,null,[n[0]||=E(`p`,{class:`label`},`连接状态`,-1),E(`p`,te,g(Y.value?.connected?`已连接`:`未连接`),1),E(`p`,A,g(Y.value?.login?`${Y.value.login.nickname} · ${Y.value.login.userId}`:`—`),1)])])]),_:1})]),_:1}),d(f,{span:6},{default:a(()=>[d(u,{class:`stat-card`},{default:a(()=>[E(`div`,j,[E(`div`,M,[d(c,{size:18},{default:a(()=>[d(p(l))]),_:1})]),E(`div`,null,[n[1]||=E(`p`,{class:`label`},`运行时长`,-1),E(`p`,N,g(X.value),1),E(`p`,P,` state: `+g(Y.value?.state??`—`)+` · gen `+g(Y.value?.generation??`—`),1)])])]),_:1})]),_:1}),d(f,{span:6},{default:a(()=>[d(u,{class:`stat-card`},{default:a(()=>[E(`div`,F,[E(`div`,I,[d(c,{size:18},{default:a(()=>[d(p(r))]),_:1})]),E(`div`,null,[n[2]||=E(`p`,{class:`label`},`插件`,-1),E(`p`,L,[T(g(Y.value?.counts.loadedPlugins??`—`),1),E(`span`,R,` / `+g(Y.value?.counts.plugins??`—`)+` 已加载`,1)]),E(`p`,z,` 启用 `+g(Y.value?.counts.enabledPlugins??`—`),1)])])]),_:1})]),_:1}),d(f,{span:6},{default:a(()=>[d(u,{class:`stat-card`},{default:a(()=>[E(`div`,B,[E(`div`,V,[d(c,{size:18},{default:a(()=>[d(p(t))]),_:1})]),E(`div`,null,[n[3]||=E(`p`,{class:`label`},`会话`,-1),E(`p`,H,[T(g(Y.value?.counts.sessions??`—`),1),E(`span`,U,` · `+g(Y.value?.counts.kvPlugins??`—`)+` KV 插件`,1)]),n[4]||=E(`p`,{class:`sub`},`session 记录数`,-1)])])]),_:1})]),_:1})]),_:1}),d(u,{class:`block`},{header:a(()=>[...n[5]||=[T(`运行时控制`,-1)]]),default:a(()=>[d(S,null,{default:a(()=>[d(h,{type:`danger`,loading:J.value,onClick:ne},{default:a(()=>[...n[6]||=[T(` 重启运行时 `,-1)]]),_:1},8,[`loading`]),d(h,{onClick:re},{default:a(()=>[...n[7]||=[T(`暂停`,-1)]]),_:1}),d(h,{onClick:ie},{default:a(()=>[...n[8]||=[T(`恢复`,-1)]]),_:1})]),_:1}),E(`p`,W,` version: `+g(b.value?.version??`-`)+` · paths: `+g(b.value?.paths.config),1),b.value?.webui.requiresProcessRestart?(s(),_(`p`,G,` webui 绑定配置已修改,需要重启进程生效。 `)):C(``,!0)]),_:1}),d(u,{class:`block`},{header:a(()=>[...n[9]||=[T(`命令列表`,-1)]]),default:a(()=>[d(D,{data:K.value,size:`small`,"max-height":`320`},{default:a(()=>[d(w,{prop:`id`,label:`命令`,width:`220`}),d(w,{prop:`pluginId`,label:`插件`,width:`180`}),d(w,{prop:`description`,label:`说明`})]),_:1},8,[`data`])]),_:1}),d(u,{class:`block`},{header:a(()=>[...n[10]||=[T(`最近事件`,-1)]]),default:a(()=>[d(D,{data:q.value,size:`small`,"max-height":`320`},{default:a(()=>[d(w,{label:`时间`,width:`170`},{default:a(({row:e})=>[T(g(p(y)(e.time)),1)]),_:1}),d(w,{prop:`type`,label:`类型`,width:`100`}),d(w,{prop:`summary`,label:`摘要`})]),_:1},8,[`data`])]),_:1})])}}}),[[`__scopeId`,`data-v-5b803405`]]);export{K as default};
@@ -0,0 +1 @@
1
+ import{Ci as e,Ii as t,Ki as n,Ri as r,Si as i,Ti as a,a as o,ci as s,d as c,ea as l,f as u,ga as d,ii as f,ki as p,l as m,li as h,n as g,si as _,ti as v}from"./api-CNzxhTWe.js";var y={class:`json`},b=u(h({__name:`EventsView`,setup(u){let h=n(``),b=n(`on`),x=n([]),S=n(!1),C=n(``),w=async()=>{try{let e=new URLSearchParams({limit:`300`});h.value&&e.set(`type`,h.value),x.value=await g(`/api/events?${e.toString()}`)}catch(e){c(e)}},T=null,E=()=>{T?.(),T=null,b.value===`on`&&(T=o(`/api/events/stream`,e=>{let t=e;h.value&&t.type!==h.value||(x.value.unshift(t),x.value.length>500&&(x.value.length=500))}))};t(b,E),t(h,async()=>{await w(),E()});let D=e=>{C.value=JSON.stringify(e.event,void 0,2),S.value=!0};return i(async()=>{await w(),E()}),e(()=>{T?.()}),(e,t)=>{let n=p(`el-option`),i=p(`el-select`),o=p(`el-button`),c=p(`el-space`),u=p(`el-card`),g=p(`el-table-column`),T=p(`el-table`),E=p(`el-drawer`);return a(),f(`div`,null,[s(u,{class:`block`},{default:r(()=>[s(c,null,{default:r(()=>[s(i,{modelValue:h.value,"onUpdate:modelValue":t[0]||=e=>h.value=e,placeholder:`全部类型`,style:{width:`140px`},clearable:``},{default:r(()=>[s(n,{label:`message`,value:`message`}),s(n,{label:`notice`,value:`notice`}),s(n,{label:`request`,value:`request`}),s(n,{label:`meta`,value:`meta`}),s(n,{label:`other`,value:`other`})]),_:1},8,[`modelValue`]),s(i,{modelValue:b.value,"onUpdate:modelValue":t[1]||=e=>b.value=e,style:{width:`90px`}},{default:r(()=>[s(n,{label:`实时`,value:`on`}),s(n,{label:`暂停`,value:`off`})]),_:1},8,[`modelValue`]),s(o,{type:`primary`,onClick:w},{default:r(()=>[...t[3]||=[_(`刷新`,-1)]]),_:1})]),_:1})]),_:1}),s(u,null,{default:r(()=>[s(T,{data:x.value,size:`small`,"max-height":`640`},{default:r(()=>[s(g,{label:`时间`,width:`170`},{default:r(({row:e})=>[_(d(l(m)(e.time)),1)]),_:1}),s(g,{prop:`type`,label:`类型`,width:`100`}),s(g,{prop:`summary`,label:`摘要`,"show-overflow-tooltip":``}),s(g,{label:`详情`,width:`90`},{default:r(({row:e})=>[s(o,{size:`small`,onClick:t=>D(e)},{default:r(()=>[...t[4]||=[_(` 查看 `,-1)]]),_:1},8,[`onClick`])]),_:1})]),_:1},8,[`data`])]),_:1}),s(E,{modelValue:S.value,"onUpdate:modelValue":t[2]||=e=>S.value=e,title:`事件详情`,size:`50%`},{default:r(()=>[v(`pre`,y,d(C.value),1)]),_:1},8,[`modelValue`])])}}}),[[`__scopeId`,`data-v-ffa9bb28`]]);export{b as default};
@@ -0,0 +1 @@
1
+ .block[data-v-ffa9bb28]{margin-bottom:16px}.json[data-v-ffa9bb28]{white-space:pre-wrap;font-size:12px}
@@ -0,0 +1 @@
1
+ import{Ai as e,Di as t,Ki as n,Ri as r,Si as i,Ti as a,Xr as o,ci as s,d as c,ea as l,f as u,ga as d,i as f,ii as p,ki as m,l as h,li as g,n as _,ni as v,p as y,qr as b,ri as x,si as S,t as C,zi as w}from"./api-CNzxhTWe.js";var T=50,E=u(g({__name:`KvView`,setup(u){let g=n([]),E=n(``),D=n(``),O=n([]),k=n(0),A=n(1),j=n(!1),M=n(!1),N=n(``),P=n(``),F=n(`create`),I=async()=>{if(E.value){j.value=!0;try{let e=(A.value-1)*T,t=new URLSearchParams({pluginId:E.value,limit:String(T),offset:String(e)});D.value&&t.set(`prefix`,D.value);let n=await _(`/api/kv?${t.toString()}`);O.value=n.items,k.value=n.total}catch(e){c(e)}finally{j.value=!1}}},L=e=>{A.value=e,I()},R=()=>{F.value=`create`,N.value=``,P.value=`null`,M.value=!0},z=e=>{F.value=`update`,N.value=e.key,P.value=JSON.stringify(e.value,void 0,2),M.value=!0},B=async()=>{let e;try{e=JSON.parse(P.value)}catch{y.error(`不是合法的 JSON`);return}try{await f(`/api/kv`,{pluginId:E.value,key:N.value,value:e}),M.value=!1,await I()}catch(e){c(e)}},V=async e=>{try{await C(`/api/kv?pluginId=${encodeURIComponent(E.value)}&key=${encodeURIComponent(e.key)}`),await I()}catch(e){c(e)}},H=e=>typeof e==`string`?e.length>120?e.slice(0,120)+`…`:e:JSON.stringify(e)?.slice(0,120)??``;return i(async()=>{try{g.value=await _(`/api/kv/plugins`),g.value.length>0&&(E.value=g.value[0]?.pluginId??``,await I())}catch(e){c(e)}}),(n,i)=>{let c=m(`el-option`),u=m(`el-select`),f=m(`el-card`),_=m(`el-input`),y=m(`el-button`),C=m(`el-space`),U=m(`el-table-column`),W=m(`el-table`),G=m(`el-pagination`),K=m(`el-form-item`),q=m(`el-form`),J=m(`el-dialog`),Y=e(`loading`);return a(),p(`div`,null,[s(f,{class:`block`},{default:r(()=>[s(u,{modelValue:E.value,"onUpdate:modelValue":i[0]||=e=>E.value=e,placeholder:`选择插件`,style:{width:`240px`},onChange:I},{default:r(()=>[(a(!0),p(o,null,t(g.value,e=>(a(),v(c,{key:e.pluginId,label:`${e.pluginId} (${e.count})`,value:e.pluginId},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`])]),_:1}),E.value?(a(),v(f,{key:0},{default:r(()=>[s(C,{class:`block`},{default:r(()=>[s(_,{modelValue:D.value,"onUpdate:modelValue":i[1]||=e=>D.value=e,placeholder:`key 前缀过滤`,style:{width:`200px`},onKeyup:b(I,[`enter`])},null,8,[`modelValue`]),s(y,{onClick:I},{default:r(()=>[...i[6]||=[S(`过滤`,-1)]]),_:1}),s(y,{type:`primary`,onClick:R},{default:r(()=>[...i[7]||=[S(`新增 KV`,-1)]]),_:1})]),_:1}),w((a(),v(W,{data:O.value,size:`small`},{default:r(()=>[s(U,{prop:`key`,label:`Key`,"show-overflow-tooltip":``}),s(U,{label:`Value`,"show-overflow-tooltip":``},{default:r(({row:e})=>[S(d(H(e.value)),1)]),_:1}),s(U,{label:`更新时间`,width:`180`},{default:r(({row:e})=>[S(d(l(h)(e.updatedAt)),1)]),_:1}),s(U,{label:`操作`,width:`150`},{default:r(({row:e})=>[s(y,{size:`small`,onClick:t=>z(e)},{default:r(()=>[...i[8]||=[S(`编辑`,-1)]]),_:1},8,[`onClick`]),s(y,{size:`small`,type:`danger`,onClick:t=>V(e)},{default:r(()=>[...i[9]||=[S(`删除`,-1)]]),_:1},8,[`onClick`])]),_:1})]),_:1},8,[`data`])),[[Y,j.value]]),s(G,{class:`pager`,layout:`total, prev, pager, next`,total:k.value,"page-size":T,"current-page":A.value,onCurrentChange:L},null,8,[`total`,`current-page`])]),_:1})):x(``,!0),s(J,{modelValue:M.value,"onUpdate:modelValue":i[5]||=e=>M.value=e,title:`KV 编辑`,width:`560px`},{footer:r(()=>[s(y,{onClick:i[4]||=e=>M.value=!1},{default:r(()=>[...i[10]||=[S(`取消`,-1)]]),_:1}),s(y,{type:`primary`,onClick:B},{default:r(()=>[...i[11]||=[S(`保存`,-1)]]),_:1})]),default:r(()=>[s(q,{"label-width":`80px`},{default:r(()=>[s(K,{label:`key`},{default:r(()=>[s(_,{modelValue:N.value,"onUpdate:modelValue":i[2]||=e=>N.value=e,disabled:F.value===`update`},null,8,[`modelValue`,`disabled`])]),_:1}),s(K,{label:`value (JSON)`},{default:r(()=>[s(_,{modelValue:P.value,"onUpdate:modelValue":i[3]||=e=>P.value=e,type:`textarea`,rows:6,spellcheck:`false`},null,8,[`modelValue`])]),_:1})]),_:1})]),_:1},8,[`modelValue`])])}}}),[[`__scopeId`,`data-v-6e1ecb0b`]]);export{E as default};
@@ -0,0 +1 @@
1
+ .block[data-v-6e1ecb0b]{margin-bottom:12px}.pager[data-v-6e1ecb0b]{margin-top:12px}
@@ -0,0 +1 @@
1
+ .login-page[data-v-57590040]{background:var(--app-bg);justify-content:center;align-items:center;height:100%;min-height:100%;display:flex;position:relative;overflow:hidden}.login-card[data-v-57590040]{z-index:1;background:var(--app-glass);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);width:372px;box-shadow:var(--card-shadow), 0 32px 80px -40px oklch(0% 0 0/.35);position:relative}.brand[data-v-57590040]{text-align:center;margin-bottom:26px}.logo[data-v-57590040]{width:52px;height:52px;color:var(--app-accent-fg);background:linear-gradient(135deg,oklch(68.5% .155 230),oklch(56% .15 250));border-radius:15px;justify-content:center;align-items:center;margin-bottom:16px;font-size:22px;font-weight:700;display:inline-flex;box-shadow:inset 0 1px oklch(100% 0 0/.22),0 12px 28px oklch(68.5% .155 230/.4)}.brand h2[data-v-57590040]{color:var(--app-text);letter-spacing:.02em;margin:0;font-size:18px}.brand p[data-v-57590040]{color:var(--app-muted);margin:6px 0 0;font-size:13px}.submit[data-v-57590040]{letter-spacing:.35em;width:100%;margin-top:6px;font-weight:600}