@jsbot-tellus/core 2.6.0 → 2.8.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.
- package/README.md +16 -4
- package/dist/core/dispatch/command.d.ts +5 -2
- package/dist/core/dispatch/command.d.ts.map +1 -1
- package/dist/core/dispatch/command.js +33 -7
- package/dist/core/dispatch/command.js.map +1 -1
- package/dist/core/dispatch/handler.d.ts +5 -3
- package/dist/core/dispatch/handler.d.ts.map +1 -1
- package/dist/core/dispatch/handler.js +6 -1
- package/dist/core/dispatch/handler.js.map +1 -1
- package/dist/core/dispatch/router.d.ts +4 -2
- package/dist/core/dispatch/router.d.ts.map +1 -1
- package/dist/core/dispatch/router.js +9 -5
- package/dist/core/dispatch/router.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/kernel.d.ts +1 -1
- package/dist/core/kernel.d.ts.map +1 -1
- package/dist/core/kernel.js +4 -1
- package/dist/core/kernel.js.map +1 -1
- package/dist/core/plugin/context.d.ts.map +1 -1
- package/dist/core/plugin/context.js +12 -0
- package/dist/core/plugin/context.js.map +1 -1
- package/dist/core/plugin/loader.d.ts +1 -1
- package/dist/core/plugin/loader.d.ts.map +1 -1
- package/dist/core/plugin/loader.js +31 -46
- package/dist/core/plugin/loader.js.map +1 -1
- package/dist/core/plugin/types.d.ts +9 -1
- package/dist/core/plugin/types.d.ts.map +1 -1
- package/dist/core/plugin/types.js.map +1 -1
- package/dist/webui/assets/ActionsView-B3Q3rh2X.js +1 -0
- package/dist/webui/assets/ConfigView-Baeqfi8s.js +1 -0
- package/dist/webui/assets/DashboardView-DLKD8DqF.js +1 -0
- package/dist/webui/assets/EventsView-CGUPPvRI.js +1 -0
- package/dist/webui/assets/KvView-CeovApuA.js +1 -0
- package/dist/webui/assets/LoginView-C2cfmXmS.js +1 -0
- package/dist/webui/assets/LogsView-K7nWoSFe.js +1 -0
- package/dist/webui/assets/MainLayout-bySbvMWB.js +1 -0
- package/dist/webui/assets/{MainLayout-glfVNbMz.css → MainLayout-qhsp--2k.css} +1 -1
- package/dist/webui/assets/PluginsView-DQZu8in1.js +1 -0
- package/dist/webui/assets/SessionsView-C0vTCqqE.js +1 -0
- package/dist/webui/assets/api-Bm2KUKXH.js +3 -0
- package/dist/webui/assets/index-CFz4VL67.js +50 -0
- package/dist/webui/assets/{index-CePlRZX6.css → index-Cs8jafCm.css} +1 -1
- package/dist/webui/index.html +3 -3
- package/docs/architecture.md +3 -3
- package/docs/configuration.md +3 -3
- package/docs/docker.md +166 -0
- package/docs/feature-parity.md +2 -2
- package/docs/migration.md +1 -1
- package/docs/plugin-api.md +20 -5
- package/docs/plugin-development.md +30 -27
- package/docs/release.md +50 -8
- package/package.json +3 -3
- package/src/core/dispatch/command.ts +53 -1
- package/src/core/dispatch/handler.ts +19 -1
- package/src/core/dispatch/router.ts +20 -3
- package/src/core/index.ts +4 -0
- package/src/core/kernel.ts +8 -1
- package/src/core/plugin/context.ts +21 -0
- package/src/core/plugin/loader.ts +41 -66
- package/src/core/plugin/types.ts +20 -0
- package/dist/webui/assets/ActionsView-BDuXBWG1.js +0 -1
- package/dist/webui/assets/ConfigView-B3Gv2uRG.js +0 -1
- package/dist/webui/assets/DashboardView-n9LGPmQL.js +0 -1
- package/dist/webui/assets/EventsView-DhO8twWb.js +0 -1
- package/dist/webui/assets/KvView-BCz_dOVC.js +0 -1
- package/dist/webui/assets/LoginView-Br3_AC5z.js +0 -1
- package/dist/webui/assets/LogsView-Ba_12frI.js +0 -1
- package/dist/webui/assets/MainLayout-D2LTc57u.js +0 -1
- package/dist/webui/assets/PluginsView-vQKBSCU8.js +0 -1
- package/dist/webui/assets/SessionsView-DSl37qpo.js +0 -1
- package/dist/webui/assets/api-CNzxhTWe.js +0 -3
- package/dist/webui/assets/index-CUvpnClx.js +0 -50
|
@@ -11,17 +11,42 @@ import type {
|
|
|
11
11
|
CommandInfo,
|
|
12
12
|
CommandMatch,
|
|
13
13
|
CommandOptions,
|
|
14
|
+
MessageType,
|
|
15
|
+
MessageTypeFilter,
|
|
14
16
|
} from '../plugin/types.js'
|
|
15
17
|
import type { Permission } from '../security/permission.js'
|
|
16
18
|
|
|
17
19
|
type AnyCommandHandler = CommandHandler<OneBotMessageEvent, any[]>
|
|
18
20
|
|
|
21
|
+
const DEFAULT_MESSAGE_TYPES: MessageType[] = ['group', 'private']
|
|
22
|
+
|
|
23
|
+
export function normalizeMessageTypes(
|
|
24
|
+
value: MessageTypeFilter | undefined
|
|
25
|
+
): MessageType[] {
|
|
26
|
+
if (value === undefined) return [...DEFAULT_MESSAGE_TYPES]
|
|
27
|
+
|
|
28
|
+
const values = typeof value === 'string' ? [value] : value
|
|
29
|
+
const result: MessageType[] = []
|
|
30
|
+
|
|
31
|
+
for (const item of values) {
|
|
32
|
+
if (
|
|
33
|
+
(item === 'group' || item === 'private') &&
|
|
34
|
+
!result.includes(item)
|
|
35
|
+
) {
|
|
36
|
+
result.push(item)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return result.length > 0 ? result : [...DEFAULT_MESSAGE_TYPES]
|
|
41
|
+
}
|
|
42
|
+
|
|
19
43
|
export interface CommandRegistration {
|
|
20
44
|
pluginId: string
|
|
21
45
|
name: string
|
|
22
46
|
aliases: string[]
|
|
23
47
|
prefixes: string[]
|
|
24
48
|
permission: Permission
|
|
49
|
+
messageTypes: MessageType[]
|
|
25
50
|
description?: string | undefined
|
|
26
51
|
params?: string | undefined
|
|
27
52
|
paramsParser?: CompiledCommandParams | undefined
|
|
@@ -35,6 +60,7 @@ export interface CommandGroupRegistration {
|
|
|
35
60
|
aliases: string[]
|
|
36
61
|
prefixes: string[]
|
|
37
62
|
permission: Permission
|
|
63
|
+
messageTypes: MessageType[]
|
|
38
64
|
description?: string | undefined
|
|
39
65
|
params?: string | undefined
|
|
40
66
|
handler?: AnyCommandHandler | undefined
|
|
@@ -188,6 +214,7 @@ export class CommandRegistry {
|
|
|
188
214
|
bases,
|
|
189
215
|
prefixes,
|
|
190
216
|
registration.permission,
|
|
217
|
+
registration.messageTypes,
|
|
191
218
|
children
|
|
192
219
|
)
|
|
193
220
|
|
|
@@ -199,6 +226,7 @@ export class CommandRegistry {
|
|
|
199
226
|
bases,
|
|
200
227
|
prefixes,
|
|
201
228
|
registration.permission,
|
|
229
|
+
registration.messageTypes,
|
|
202
230
|
registration.description,
|
|
203
231
|
registration.params,
|
|
204
232
|
registration.handler,
|
|
@@ -253,6 +281,7 @@ export class CommandRegistry {
|
|
|
253
281
|
name: registration.name,
|
|
254
282
|
aliases: [...registration.aliases],
|
|
255
283
|
permission: registration.permission,
|
|
284
|
+
messageTypes: [...registration.messageTypes],
|
|
256
285
|
...(registration.description !== undefined
|
|
257
286
|
? { description: registration.description }
|
|
258
287
|
: {}),
|
|
@@ -263,7 +292,10 @@ export class CommandRegistry {
|
|
|
263
292
|
}))
|
|
264
293
|
}
|
|
265
294
|
|
|
266
|
-
match(
|
|
295
|
+
match(
|
|
296
|
+
rawMessage: string,
|
|
297
|
+
messageType?: MessageType
|
|
298
|
+
): RegisteredCommand | null {
|
|
267
299
|
const raw = stripLeadingReply(rawMessage.trim()).trim()
|
|
268
300
|
|
|
269
301
|
if (!raw) return null
|
|
@@ -298,6 +330,13 @@ export class CommandRegistry {
|
|
|
298
330
|
|
|
299
331
|
if (!registration) continue
|
|
300
332
|
|
|
333
|
+
if (
|
|
334
|
+
messageType !== undefined &&
|
|
335
|
+
!registration.messageTypes.includes(messageType)
|
|
336
|
+
) {
|
|
337
|
+
continue
|
|
338
|
+
}
|
|
339
|
+
|
|
301
340
|
const start = first.index ?? 0
|
|
302
341
|
const end = (last.index ?? 0) + last[0].length
|
|
303
342
|
|
|
@@ -404,6 +443,7 @@ export class CommandRegistry {
|
|
|
404
443
|
bases: string[],
|
|
405
444
|
prefixes: string[],
|
|
406
445
|
permission: Permission,
|
|
446
|
+
messageTypes: MessageType[],
|
|
407
447
|
children: GroupChild[]
|
|
408
448
|
): GroupScope {
|
|
409
449
|
const disposers: Array<() => void> = []
|
|
@@ -464,6 +504,10 @@ export class CommandRegistry {
|
|
|
464
504
|
aliases: childBases.slice(1),
|
|
465
505
|
prefixes: options.prefixes ?? prefixes,
|
|
466
506
|
permission: options.permission ?? permission,
|
|
507
|
+
messageTypes:
|
|
508
|
+
options.messageType !== undefined
|
|
509
|
+
? normalizeMessageTypes(options.messageType)
|
|
510
|
+
: [...messageTypes],
|
|
467
511
|
...(options.description !== undefined
|
|
468
512
|
? { description: options.description }
|
|
469
513
|
: {}),
|
|
@@ -506,12 +550,17 @@ export class CommandRegistry {
|
|
|
506
550
|
)
|
|
507
551
|
const nestedPrefixes = options.prefixes ?? prefixes
|
|
508
552
|
const nestedPermission = options.permission ?? permission
|
|
553
|
+
const nestedMessageTypes =
|
|
554
|
+
options.messageType !== undefined
|
|
555
|
+
? normalizeMessageTypes(options.messageType)
|
|
556
|
+
: [...messageTypes]
|
|
509
557
|
const nestedChildren: GroupChild[] = []
|
|
510
558
|
const nestedScope = this.createGroupScope(
|
|
511
559
|
pluginId,
|
|
512
560
|
nestedBases,
|
|
513
561
|
nestedPrefixes,
|
|
514
562
|
nestedPermission,
|
|
563
|
+
nestedMessageTypes,
|
|
515
564
|
nestedChildren
|
|
516
565
|
)
|
|
517
566
|
|
|
@@ -523,6 +572,7 @@ export class CommandRegistry {
|
|
|
523
572
|
nestedBases,
|
|
524
573
|
nestedPrefixes,
|
|
525
574
|
nestedPermission,
|
|
575
|
+
nestedMessageTypes,
|
|
526
576
|
options.description,
|
|
527
577
|
options.params,
|
|
528
578
|
options.handler,
|
|
@@ -567,6 +617,7 @@ export class CommandRegistry {
|
|
|
567
617
|
bases: string[],
|
|
568
618
|
prefixes: string[],
|
|
569
619
|
permission: Permission,
|
|
620
|
+
messageTypes: MessageType[],
|
|
570
621
|
description: string | undefined,
|
|
571
622
|
params: string | undefined,
|
|
572
623
|
handler: AnyCommandHandler | undefined,
|
|
@@ -584,6 +635,7 @@ export class CommandRegistry {
|
|
|
584
635
|
aliases: bases.slice(1),
|
|
585
636
|
prefixes,
|
|
586
637
|
permission,
|
|
638
|
+
messageTypes: [...messageTypes],
|
|
587
639
|
...(description !== undefined ? { description } : {}),
|
|
588
640
|
...(params !== undefined ? { params } : {}),
|
|
589
641
|
handler: handler ?? createGroupUsageHandler(children),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
OneBotMessageEvent,
|
|
2
3
|
OneBotNoticeEvent,
|
|
3
4
|
OneBotRequestEvent,
|
|
4
5
|
SnowLumaEvent,
|
|
@@ -9,6 +10,7 @@ import type {
|
|
|
9
10
|
EventContext,
|
|
10
11
|
EventType,
|
|
11
12
|
MessageHandler,
|
|
13
|
+
MessageType,
|
|
12
14
|
NoticeHandler,
|
|
13
15
|
RequestHandler,
|
|
14
16
|
} from '../plugin/types.js'
|
|
@@ -16,6 +18,7 @@ import type { MessageSender } from '../messaging/sender.js'
|
|
|
16
18
|
|
|
17
19
|
export interface MessageRegistration {
|
|
18
20
|
pluginId: string
|
|
21
|
+
messageType?: MessageType | undefined
|
|
19
22
|
handler: MessageHandler
|
|
20
23
|
}
|
|
21
24
|
|
|
@@ -96,9 +99,14 @@ export class HandlerRegistry {
|
|
|
96
99
|
private noticeRegistrations: NoticeRegistration[] = []
|
|
97
100
|
private requestRegistrations: RequestRegistration[] = []
|
|
98
101
|
|
|
99
|
-
registerMessage(
|
|
102
|
+
registerMessage(
|
|
103
|
+
pluginId: string,
|
|
104
|
+
handler: MessageHandler,
|
|
105
|
+
messageType?: MessageType
|
|
106
|
+
): () => void {
|
|
100
107
|
const registration: MessageRegistration = {
|
|
101
108
|
pluginId,
|
|
109
|
+
...(messageType !== undefined ? { messageType } : {}),
|
|
102
110
|
handler,
|
|
103
111
|
}
|
|
104
112
|
|
|
@@ -156,6 +164,16 @@ export class HandlerRegistry {
|
|
|
156
164
|
}
|
|
157
165
|
}
|
|
158
166
|
|
|
167
|
+
export function isMessageOf(
|
|
168
|
+
event: OneBotMessageEvent,
|
|
169
|
+
registration: MessageRegistration
|
|
170
|
+
): boolean {
|
|
171
|
+
return (
|
|
172
|
+
registration.messageType === undefined ||
|
|
173
|
+
registration.messageType === event.message_type
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
159
177
|
export function isNoticeOf(
|
|
160
178
|
event: OneBotNoticeEvent,
|
|
161
179
|
registration: NoticeRegistration
|
|
@@ -15,6 +15,8 @@ import type {
|
|
|
15
15
|
CommandInfo,
|
|
16
16
|
EventType,
|
|
17
17
|
MessageHandler,
|
|
18
|
+
MessageType,
|
|
19
|
+
MessageTypeFilter,
|
|
18
20
|
MiddlewareOptions,
|
|
19
21
|
NoticeHandler,
|
|
20
22
|
NoticeOptions,
|
|
@@ -27,6 +29,7 @@ import { PermissionRefuser } from '../security/refuse.js'
|
|
|
27
29
|
import type { Permission } from '../security/permission.js'
|
|
28
30
|
import {
|
|
29
31
|
CommandRegistry,
|
|
32
|
+
normalizeMessageTypes,
|
|
30
33
|
type CommandGroupRegistration,
|
|
31
34
|
type CommandRegistration,
|
|
32
35
|
} from './command.js'
|
|
@@ -34,6 +37,7 @@ import {
|
|
|
34
37
|
createEventContext,
|
|
35
38
|
eventTypeOf,
|
|
36
39
|
HandlerRegistry,
|
|
40
|
+
isMessageOf,
|
|
37
41
|
isNoticeOf,
|
|
38
42
|
isRequestOf,
|
|
39
43
|
} from './handler.js'
|
|
@@ -64,6 +68,7 @@ export interface RegisterCommandOptions {
|
|
|
64
68
|
aliases?: string[] | undefined
|
|
65
69
|
prefixes?: string[] | undefined
|
|
66
70
|
permission?: Permission | undefined
|
|
71
|
+
messageType?: MessageTypeFilter | undefined
|
|
67
72
|
description?: string | undefined
|
|
68
73
|
params?: string | undefined
|
|
69
74
|
handler: AnyCommandHandler
|
|
@@ -75,6 +80,7 @@ export interface RegisterCommandGroupOptions {
|
|
|
75
80
|
aliases?: string[] | undefined
|
|
76
81
|
prefixes?: string[] | undefined
|
|
77
82
|
permission?: Permission | undefined
|
|
83
|
+
messageType?: MessageTypeFilter | undefined
|
|
78
84
|
description?: string | undefined
|
|
79
85
|
params?: string | undefined
|
|
80
86
|
handler?: AnyCommandHandler | undefined
|
|
@@ -160,7 +166,10 @@ export class Router {
|
|
|
160
166
|
if (context.stopped) return
|
|
161
167
|
|
|
162
168
|
if (isMessageEvent(event)) {
|
|
163
|
-
const found = this.commands.match(
|
|
169
|
+
const found = this.commands.match(
|
|
170
|
+
event.raw_message,
|
|
171
|
+
event.message_type
|
|
172
|
+
)
|
|
164
173
|
|
|
165
174
|
if (found) {
|
|
166
175
|
sdkContext.stopPropagation()
|
|
@@ -257,6 +266,7 @@ export class Router {
|
|
|
257
266
|
aliases: options.aliases ?? [],
|
|
258
267
|
prefixes: options.prefixes ?? ['/'],
|
|
259
268
|
permission: options.permission ?? 'User',
|
|
269
|
+
messageTypes: normalizeMessageTypes(options.messageType),
|
|
260
270
|
...(options.description !== undefined
|
|
261
271
|
? { description: options.description }
|
|
262
272
|
: {}),
|
|
@@ -277,6 +287,7 @@ export class Router {
|
|
|
277
287
|
aliases: options.aliases ?? [],
|
|
278
288
|
prefixes: options.prefixes ?? ['/'],
|
|
279
289
|
permission: options.permission ?? 'User',
|
|
290
|
+
messageTypes: normalizeMessageTypes(options.messageType),
|
|
280
291
|
...(options.description !== undefined
|
|
281
292
|
? { description: options.description }
|
|
282
293
|
: {}),
|
|
@@ -289,8 +300,12 @@ export class Router {
|
|
|
289
300
|
return this.commands.group(registration, setup)
|
|
290
301
|
}
|
|
291
302
|
|
|
292
|
-
registerMessage(
|
|
293
|
-
|
|
303
|
+
registerMessage(
|
|
304
|
+
pluginId: string,
|
|
305
|
+
handler: MessageHandler,
|
|
306
|
+
messageType?: MessageType
|
|
307
|
+
): () => void {
|
|
308
|
+
return this.handlers.registerMessage(pluginId, handler, messageType)
|
|
294
309
|
}
|
|
295
310
|
|
|
296
311
|
registerNotice(options: RegisterNoticeOptions): () => void {
|
|
@@ -431,6 +446,8 @@ export class Router {
|
|
|
431
446
|
for (const registration of this.handlers.messages()) {
|
|
432
447
|
if (messageContext.stopped) return
|
|
433
448
|
|
|
449
|
+
if (!isMessageOf(event, registration)) continue
|
|
450
|
+
|
|
434
451
|
if (!this.gate.isEnabled(registration.pluginId, event)) {
|
|
435
452
|
continue
|
|
436
453
|
}
|
package/src/core/index.ts
CHANGED
|
@@ -30,8 +30,11 @@ export type {
|
|
|
30
30
|
EventContext,
|
|
31
31
|
EventRegistrar,
|
|
32
32
|
EventType,
|
|
33
|
+
GroupMessageHandler,
|
|
33
34
|
InstalledPackageInfo,
|
|
34
35
|
MessageHandler,
|
|
36
|
+
MessageType,
|
|
37
|
+
MessageTypeFilter,
|
|
35
38
|
MiddlewareOptions,
|
|
36
39
|
MiddlewareRegistrar,
|
|
37
40
|
NoticeHandler,
|
|
@@ -46,6 +49,7 @@ export type {
|
|
|
46
49
|
PluginStatus,
|
|
47
50
|
PluginStatusEntry,
|
|
48
51
|
PluginUpdateResult,
|
|
52
|
+
PrivateMessageHandler,
|
|
49
53
|
RequestHandler,
|
|
50
54
|
RequestOptions,
|
|
51
55
|
} from './plugin/types.js'
|
package/src/core/kernel.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { isMessageEvent, type SnowLumaEvent } from '@snowluma/sdk'
|
|
2
2
|
import type { BotClient } from './client.js'
|
|
3
3
|
import type { AppConfig } from './config/schema.js'
|
|
4
4
|
import { createBotApi, type BotApi } from './api.js'
|
|
@@ -93,6 +93,13 @@ export class Kernel {
|
|
|
93
93
|
.listCommands()
|
|
94
94
|
.filter((command) =>
|
|
95
95
|
gate.isEnabled(command.pluginId, event)
|
|
96
|
+
)
|
|
97
|
+
.filter(
|
|
98
|
+
(command) =>
|
|
99
|
+
!isMessageEvent(event) ||
|
|
100
|
+
command.messageTypes.includes(
|
|
101
|
+
event.message_type
|
|
102
|
+
)
|
|
96
103
|
),
|
|
97
104
|
},
|
|
98
105
|
plugins: {
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
CommandHandler,
|
|
13
13
|
CommandOptions,
|
|
14
14
|
CoreServices,
|
|
15
|
+
MessageHandler,
|
|
15
16
|
PluginContext,
|
|
16
17
|
PluginDefinition,
|
|
17
18
|
} from './types.js'
|
|
@@ -63,6 +64,9 @@ export function createPluginContext<TConfig>(
|
|
|
63
64
|
...(options.permission !== undefined
|
|
64
65
|
? { permission: options.permission }
|
|
65
66
|
: {}),
|
|
67
|
+
...(options.messageType !== undefined
|
|
68
|
+
? { messageType: options.messageType }
|
|
69
|
+
: {}),
|
|
66
70
|
...(options.description !== undefined
|
|
67
71
|
? { description: options.description }
|
|
68
72
|
: {}),
|
|
@@ -89,6 +93,9 @@ export function createPluginContext<TConfig>(
|
|
|
89
93
|
...(options.permission !== undefined
|
|
90
94
|
? { permission: options.permission }
|
|
91
95
|
: {}),
|
|
96
|
+
...(options.messageType !== undefined
|
|
97
|
+
? { messageType: options.messageType }
|
|
98
|
+
: {}),
|
|
92
99
|
...(options.description !== undefined
|
|
93
100
|
? { description: options.description }
|
|
94
101
|
: {}),
|
|
@@ -111,6 +118,20 @@ export function createPluginContext<TConfig>(
|
|
|
111
118
|
onMessage(handler) {
|
|
112
119
|
return deps.router.registerMessage(id, handler)
|
|
113
120
|
},
|
|
121
|
+
onGroupMessage(handler) {
|
|
122
|
+
return deps.router.registerMessage(
|
|
123
|
+
id,
|
|
124
|
+
handler as MessageHandler,
|
|
125
|
+
'group'
|
|
126
|
+
)
|
|
127
|
+
},
|
|
128
|
+
onPrivateMessage(handler) {
|
|
129
|
+
return deps.router.registerMessage(
|
|
130
|
+
id,
|
|
131
|
+
handler as MessageHandler,
|
|
132
|
+
'private'
|
|
133
|
+
)
|
|
134
|
+
},
|
|
114
135
|
onNotice(options, handler) {
|
|
115
136
|
return deps.router.registerNotice({
|
|
116
137
|
pluginId: id,
|
|
@@ -4,7 +4,7 @@ import { pathToFileURL } from 'node:url'
|
|
|
4
4
|
import fg from 'fast-glob'
|
|
5
5
|
import type { Logger } from '../logging/logger.js'
|
|
6
6
|
import { collectPluginExports } from './exports.js'
|
|
7
|
-
import {
|
|
7
|
+
import { readJsonFile } from './install-dir.js'
|
|
8
8
|
import { NpmCliRunner, type NpmRunner } from './npm-runner.js'
|
|
9
9
|
import type { AnyPluginDefinition } from './types.js'
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@ type LoaderLogger = Pick<Logger, 'warn' | 'error'> & {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface LocalPluginLoaderOptions {
|
|
16
|
-
/**
|
|
16
|
+
/** Rebuild local plugins that have a build script on every load. Defaults to true. */
|
|
17
17
|
autoBuild?: boolean | undefined
|
|
18
18
|
/** Timeout for a single local plugin build. Defaults to 120 seconds. */
|
|
19
19
|
buildTimeoutMs?: number | undefined
|
|
@@ -49,19 +49,7 @@ async function readBuildScript(directory: string): Promise<string | undefined> {
|
|
|
49
49
|
: undefined
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
root: string
|
|
54
|
-
): Promise<Set<string> | null> {
|
|
55
|
-
try {
|
|
56
|
-
const state = await readInstallState(root)
|
|
57
|
-
|
|
58
|
-
return new Set(
|
|
59
|
-
Object.values(state.packages).map((record) => record.dir)
|
|
60
|
-
)
|
|
61
|
-
} catch {
|
|
62
|
-
return null
|
|
63
|
-
}
|
|
64
|
-
}
|
|
52
|
+
type BuildOutcome = 'built' | 'missing-node-modules' | 'failed'
|
|
65
53
|
|
|
66
54
|
async function buildLocalPlugin(
|
|
67
55
|
directory: string,
|
|
@@ -69,22 +57,15 @@ async function buildLocalPlugin(
|
|
|
69
57
|
logger: LoaderLogger | undefined,
|
|
70
58
|
runner: NpmRunner,
|
|
71
59
|
timeoutMs: number
|
|
72
|
-
): Promise<
|
|
73
|
-
if ((await readBuildScript(directory)) === undefined) {
|
|
74
|
-
logger?.warn(
|
|
75
|
-
`skipping local plugin ${name}: dist directory not found and package.json has no build script`
|
|
76
|
-
)
|
|
77
|
-
return false
|
|
78
|
-
}
|
|
79
|
-
|
|
60
|
+
): Promise<BuildOutcome> {
|
|
80
61
|
if (!(await directoryExists(join(directory, 'node_modules')))) {
|
|
81
62
|
logger?.warn(
|
|
82
|
-
`
|
|
63
|
+
`cannot build local plugin ${name}: node_modules is missing; run npm install --prefix ${directory}`
|
|
83
64
|
)
|
|
84
|
-
return
|
|
65
|
+
return 'missing-node-modules'
|
|
85
66
|
}
|
|
86
67
|
|
|
87
|
-
logger?.info?.(`building local plugin ${name}
|
|
68
|
+
logger?.info?.(`building local plugin ${name}`)
|
|
88
69
|
|
|
89
70
|
try {
|
|
90
71
|
await runner.run(['run', 'build'], {
|
|
@@ -93,13 +74,12 @@ async function buildLocalPlugin(
|
|
|
93
74
|
})
|
|
94
75
|
} catch (error) {
|
|
95
76
|
logger?.error(`failed to build local plugin ${name}`, error)
|
|
96
|
-
|
|
97
|
-
return false
|
|
77
|
+
return 'failed'
|
|
98
78
|
}
|
|
99
79
|
|
|
100
80
|
logger?.info?.(`built local plugin ${name}`)
|
|
101
81
|
|
|
102
|
-
return
|
|
82
|
+
return 'built'
|
|
103
83
|
}
|
|
104
84
|
|
|
105
85
|
export async function loadPluginsFromDirectory(
|
|
@@ -127,7 +107,14 @@ export async function loadPluginsFromDirectory(
|
|
|
127
107
|
let imported: unknown
|
|
128
108
|
|
|
129
109
|
try {
|
|
130
|
-
|
|
110
|
+
const info = await stat(file).catch(() => null)
|
|
111
|
+
const url = pathToFileURL(file)
|
|
112
|
+
|
|
113
|
+
if (info !== null) {
|
|
114
|
+
url.searchParams.set('v', String(info.mtimeMs))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
imported = await import(url.href)
|
|
131
118
|
} catch (error) {
|
|
132
119
|
logger?.error(`failed to import plugin file: ${file}`, error)
|
|
133
120
|
invalid.push(
|
|
@@ -170,22 +157,7 @@ export async function loadLocalPlugins(
|
|
|
170
157
|
)
|
|
171
158
|
const plugins: AnyPluginDefinition[] = []
|
|
172
159
|
|
|
173
|
-
|
|
174
|
-
let managed = new Set<string>()
|
|
175
|
-
|
|
176
|
-
if (autoBuild) {
|
|
177
|
-
const directories = await readManagedDirectories(absolute)
|
|
178
|
-
|
|
179
|
-
if (directories === null) {
|
|
180
|
-
logger?.warn(
|
|
181
|
-
'cannot read plugin install state; automatic local plugin build is disabled'
|
|
182
|
-
)
|
|
183
|
-
autoBuild = false
|
|
184
|
-
} else {
|
|
185
|
-
managed = directories
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
160
|
+
const autoBuild = options.autoBuild !== false
|
|
189
161
|
const runner = options.runner ?? new NpmCliRunner()
|
|
190
162
|
const timeoutMs = options.buildTimeoutMs ?? DEFAULT_BUILD_TIMEOUT_MS
|
|
191
163
|
|
|
@@ -195,24 +167,11 @@ export async function loadLocalPlugins(
|
|
|
195
167
|
|
|
196
168
|
const directory = join(absolute, entry.name)
|
|
197
169
|
const dist = join(directory, 'dist')
|
|
170
|
+
const hasBuildScript = (await readBuildScript(directory)) !== undefined
|
|
198
171
|
let distInfo = await stat(dist).catch(() => null)
|
|
199
172
|
|
|
200
|
-
if (
|
|
201
|
-
|
|
202
|
-
logger?.warn(
|
|
203
|
-
`skipping local plugin ${entry.name}: dist directory not found`
|
|
204
|
-
)
|
|
205
|
-
continue
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (managed.has(entry.name)) {
|
|
209
|
-
logger?.warn(
|
|
210
|
-
`skipping local plugin ${entry.name}: dist directory not found (installed package is expected to include dist)`
|
|
211
|
-
)
|
|
212
|
-
continue
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const built = await buildLocalPlugin(
|
|
173
|
+
if (autoBuild && hasBuildScript) {
|
|
174
|
+
const outcome = await buildLocalPlugin(
|
|
216
175
|
directory,
|
|
217
176
|
entry.name,
|
|
218
177
|
logger,
|
|
@@ -220,16 +179,32 @@ export async function loadLocalPlugins(
|
|
|
220
179
|
timeoutMs
|
|
221
180
|
)
|
|
222
181
|
|
|
223
|
-
if (!built) continue
|
|
224
|
-
|
|
225
182
|
distInfo = await stat(dist).catch(() => null)
|
|
226
183
|
|
|
227
184
|
if (!distInfo?.isDirectory()) {
|
|
185
|
+
const reason =
|
|
186
|
+
outcome === 'built'
|
|
187
|
+
? 'build finished but dist directory not found'
|
|
188
|
+
: outcome === 'missing-node-modules'
|
|
189
|
+
? 'node_modules is missing and dist directory not found'
|
|
190
|
+
: 'build failed and dist directory not found'
|
|
191
|
+
|
|
192
|
+
logger?.warn(`skipping local plugin ${entry.name}: ${reason}`)
|
|
193
|
+
continue
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (outcome !== 'built') {
|
|
228
197
|
logger?.warn(
|
|
229
|
-
`
|
|
198
|
+
`using existing dist for local plugin ${entry.name}: rebuild failed`
|
|
230
199
|
)
|
|
231
|
-
continue
|
|
232
200
|
}
|
|
201
|
+
} else if (!distInfo?.isDirectory()) {
|
|
202
|
+
logger?.warn(
|
|
203
|
+
hasBuildScript
|
|
204
|
+
? `skipping local plugin ${entry.name}: dist directory not found and automatic build is disabled`
|
|
205
|
+
: `skipping local plugin ${entry.name}: dist directory not found and package.json has no build script`
|
|
206
|
+
)
|
|
207
|
+
continue
|
|
233
208
|
}
|
|
234
209
|
|
|
235
210
|
plugins.push(...(await loadPluginsFromDirectory(dist, logger)))
|
package/src/core/plugin/types.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
OneBotGroupMessageEvent,
|
|
2
3
|
OneBotMessageEvent,
|
|
3
4
|
OneBotNoticeEvent,
|
|
5
|
+
OneBotPrivateMessageEvent,
|
|
4
6
|
OneBotRequestEvent,
|
|
5
7
|
OutgoingMessage,
|
|
6
8
|
SnowLumaEvent,
|
|
@@ -17,6 +19,10 @@ import type { CommandParamArgs } from './command-params.js'
|
|
|
17
19
|
|
|
18
20
|
export type EventType = 'message' | 'notice' | 'request' | 'meta'
|
|
19
21
|
|
|
22
|
+
export type MessageType = 'group' | 'private'
|
|
23
|
+
|
|
24
|
+
export type MessageTypeFilter = MessageType | readonly MessageType[]
|
|
25
|
+
|
|
20
26
|
export interface CommandMatch {
|
|
21
27
|
command: string
|
|
22
28
|
prefix: string
|
|
@@ -28,6 +34,7 @@ export interface CommandInfo {
|
|
|
28
34
|
name: string
|
|
29
35
|
aliases: string[]
|
|
30
36
|
permission: Permission
|
|
37
|
+
messageTypes: MessageType[]
|
|
31
38
|
description?: string | undefined
|
|
32
39
|
usage?: string | undefined
|
|
33
40
|
pluginId: string
|
|
@@ -59,6 +66,16 @@ export type MessageHandler = (
|
|
|
59
66
|
context: EventContext<OneBotMessageEvent>
|
|
60
67
|
) => void | Promise<void>
|
|
61
68
|
|
|
69
|
+
export type GroupMessageHandler = (
|
|
70
|
+
event: OneBotGroupMessageEvent,
|
|
71
|
+
context: EventContext<OneBotGroupMessageEvent>
|
|
72
|
+
) => void | Promise<void>
|
|
73
|
+
|
|
74
|
+
export type PrivateMessageHandler = (
|
|
75
|
+
event: OneBotPrivateMessageEvent,
|
|
76
|
+
context: EventContext<OneBotPrivateMessageEvent>
|
|
77
|
+
) => void | Promise<void>
|
|
78
|
+
|
|
62
79
|
export type NoticeHandler = (
|
|
63
80
|
event: OneBotNoticeEvent,
|
|
64
81
|
context: EventContext<OneBotNoticeEvent>
|
|
@@ -80,6 +97,7 @@ export interface CommandOptions<Declaration extends string = string> {
|
|
|
80
97
|
aliases?: string[] | undefined
|
|
81
98
|
prefixes?: string[] | undefined
|
|
82
99
|
permission?: Permission | undefined
|
|
100
|
+
messageType?: MessageTypeFilter | undefined
|
|
83
101
|
description?: string | undefined
|
|
84
102
|
params?: Declaration | undefined
|
|
85
103
|
}
|
|
@@ -127,6 +145,8 @@ export interface CommandRegistrar extends CommandGroupRegistrar {
|
|
|
127
145
|
|
|
128
146
|
export interface EventRegistrar {
|
|
129
147
|
onMessage(handler: MessageHandler): () => void
|
|
148
|
+
onGroupMessage(handler: GroupMessageHandler): () => void
|
|
149
|
+
onPrivateMessage(handler: PrivateMessageHandler): () => void
|
|
130
150
|
onNotice(options: NoticeOptions, handler: NoticeHandler): () => void
|
|
131
151
|
onRequest(options: RequestOptions, handler: RequestHandler): () => void
|
|
132
152
|
}
|
|
@@ -1 +0,0 @@
|
|
|
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};
|
|
@@ -1 +0,0 @@
|
|
|
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};
|
|
@@ -1 +0,0 @@
|
|
|
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};
|