@zhin.js/core 1.0.25 → 1.0.26
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/CHANGELOG.md +10 -0
- package/README.md +84 -342
- package/lib/adapter.d.ts +17 -0
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +84 -2
- package/lib/adapter.js.map +1 -1
- package/lib/ai/agent.d.ts +126 -0
- package/lib/ai/agent.d.ts.map +1 -0
- package/lib/ai/agent.js +645 -0
- package/lib/ai/agent.js.map +1 -0
- package/lib/ai/context-manager.d.ts +213 -0
- package/lib/ai/context-manager.d.ts.map +1 -0
- package/lib/ai/context-manager.js +313 -0
- package/lib/ai/context-manager.js.map +1 -0
- package/lib/ai/conversation-memory.d.ts +181 -0
- package/lib/ai/conversation-memory.d.ts.map +1 -0
- package/lib/ai/conversation-memory.js +581 -0
- package/lib/ai/conversation-memory.js.map +1 -0
- package/lib/ai/follow-up.d.ts +131 -0
- package/lib/ai/follow-up.d.ts.map +1 -0
- package/lib/ai/follow-up.js +265 -0
- package/lib/ai/follow-up.js.map +1 -0
- package/lib/ai/index.d.ts +29 -0
- package/lib/ai/index.d.ts.map +1 -0
- package/lib/ai/index.js +34 -0
- package/lib/ai/index.js.map +1 -0
- package/lib/ai/init.d.ts +30 -0
- package/lib/ai/init.d.ts.map +1 -0
- package/lib/ai/init.js +424 -0
- package/lib/ai/init.js.map +1 -0
- package/lib/ai/output.d.ts +93 -0
- package/lib/ai/output.d.ts.map +1 -0
- package/lib/ai/output.js +176 -0
- package/lib/ai/output.js.map +1 -0
- package/lib/ai/providers/anthropic.d.ts +23 -0
- package/lib/ai/providers/anthropic.d.ts.map +1 -0
- package/lib/ai/providers/anthropic.js +322 -0
- package/lib/ai/providers/anthropic.js.map +1 -0
- package/lib/ai/providers/base.d.ts +43 -0
- package/lib/ai/providers/base.d.ts.map +1 -0
- package/lib/ai/providers/base.js +135 -0
- package/lib/ai/providers/base.js.map +1 -0
- package/lib/ai/providers/index.d.ts +12 -0
- package/lib/ai/providers/index.d.ts.map +1 -0
- package/lib/ai/providers/index.js +9 -0
- package/lib/ai/providers/index.js.map +1 -0
- package/lib/ai/providers/ollama.d.ts +25 -0
- package/lib/ai/providers/ollama.d.ts.map +1 -0
- package/lib/ai/providers/ollama.js +243 -0
- package/lib/ai/providers/ollama.js.map +1 -0
- package/lib/ai/providers/openai.d.ts +46 -0
- package/lib/ai/providers/openai.d.ts.map +1 -0
- package/lib/ai/providers/openai.js +132 -0
- package/lib/ai/providers/openai.js.map +1 -0
- package/lib/ai/rate-limiter.d.ts +38 -0
- package/lib/ai/rate-limiter.d.ts.map +1 -0
- package/lib/ai/rate-limiter.js +86 -0
- package/lib/ai/rate-limiter.js.map +1 -0
- package/lib/ai/service.d.ts +81 -0
- package/lib/ai/service.d.ts.map +1 -0
- package/lib/ai/service.js +274 -0
- package/lib/ai/service.js.map +1 -0
- package/lib/ai/session.d.ts +186 -0
- package/lib/ai/session.d.ts.map +1 -0
- package/lib/ai/session.js +443 -0
- package/lib/ai/session.js.map +1 -0
- package/lib/ai/tone-detector.d.ts +19 -0
- package/lib/ai/tone-detector.d.ts.map +1 -0
- package/lib/ai/tone-detector.js +72 -0
- package/lib/ai/tone-detector.js.map +1 -0
- package/lib/ai/tools.d.ts +45 -0
- package/lib/ai/tools.d.ts.map +1 -0
- package/lib/ai/tools.js +206 -0
- package/lib/ai/tools.js.map +1 -0
- package/lib/ai/types.d.ts +264 -0
- package/lib/ai/types.d.ts.map +1 -0
- package/lib/ai/types.js +6 -0
- package/lib/ai/types.js.map +1 -0
- package/lib/ai/user-profile.d.ts +56 -0
- package/lib/ai/user-profile.d.ts.map +1 -0
- package/lib/ai/user-profile.js +130 -0
- package/lib/ai/user-profile.js.map +1 -0
- package/lib/ai/zhin-agent.d.ts +165 -0
- package/lib/ai/zhin-agent.d.ts.map +1 -0
- package/lib/ai/zhin-agent.js +707 -0
- package/lib/ai/zhin-agent.js.map +1 -0
- package/lib/built/ai-trigger.d.ts.map +1 -1
- package/lib/built/ai-trigger.js +7 -3
- package/lib/built/ai-trigger.js.map +1 -1
- package/lib/built/command.d.ts +33 -17
- package/lib/built/command.d.ts.map +1 -1
- package/lib/built/command.js +71 -44
- package/lib/built/command.js.map +1 -1
- package/lib/built/component.d.ts +42 -15
- package/lib/built/component.d.ts.map +1 -1
- package/lib/built/component.js +84 -52
- package/lib/built/component.js.map +1 -1
- package/lib/built/config.d.ts +54 -5
- package/lib/built/config.d.ts.map +1 -1
- package/lib/built/config.js +76 -10
- package/lib/built/config.js.map +1 -1
- package/lib/built/cron.d.ts +41 -18
- package/lib/built/cron.d.ts.map +1 -1
- package/lib/built/cron.js +106 -63
- package/lib/built/cron.js.map +1 -1
- package/lib/built/database.d.ts +55 -6
- package/lib/built/database.d.ts.map +1 -1
- package/lib/built/database.js +93 -22
- package/lib/built/database.js.map +1 -1
- package/lib/built/dispatcher.d.ts +118 -0
- package/lib/built/dispatcher.d.ts.map +1 -0
- package/lib/built/dispatcher.js +196 -0
- package/lib/built/dispatcher.js.map +1 -0
- package/lib/built/permission.d.ts +45 -5
- package/lib/built/permission.d.ts.map +1 -1
- package/lib/built/permission.js +56 -11
- package/lib/built/permission.js.map +1 -1
- package/lib/built/skill.d.ts +117 -0
- package/lib/built/skill.d.ts.map +1 -0
- package/lib/built/skill.js +191 -0
- package/lib/built/skill.js.map +1 -0
- package/lib/built/tool.d.ts +71 -164
- package/lib/built/tool.d.ts.map +1 -1
- package/lib/built/tool.js +212 -297
- package/lib/built/tool.js.map +1 -1
- package/lib/feature.d.ts +75 -0
- package/lib/feature.d.ts.map +1 -0
- package/lib/feature.js +69 -0
- package/lib/feature.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -1
- package/lib/plugin.d.ts +25 -17
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +180 -20
- package/lib/plugin.js.map +1 -1
- package/lib/types.d.ts +4 -9
- package/lib/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/adapter.ts +101 -2
- package/src/ai/agent.ts +772 -0
- package/src/ai/context-manager.ts +440 -0
- package/src/ai/conversation-memory.ts +774 -0
- package/src/ai/follow-up.ts +357 -0
- package/src/ai/index.ts +128 -0
- package/src/ai/init.ts +502 -0
- package/src/ai/output.ts +261 -0
- package/src/ai/providers/anthropic.ts +375 -0
- package/src/ai/providers/base.ts +173 -0
- package/src/ai/providers/index.ts +13 -0
- package/src/ai/providers/ollama.ts +292 -0
- package/src/ai/providers/openai.ts +167 -0
- package/src/ai/rate-limiter.ts +129 -0
- package/src/ai/service.ts +319 -0
- package/src/ai/session.ts +544 -0
- package/src/ai/tone-detector.ts +89 -0
- package/src/ai/tools.ts +218 -0
- package/src/ai/types.ts +296 -0
- package/src/ai/user-profile.ts +181 -0
- package/src/ai/zhin-agent.ts +845 -0
- package/src/built/ai-trigger.ts +6 -3
- package/src/built/command.ts +75 -69
- package/src/built/component.ts +94 -76
- package/src/built/config.ts +238 -128
- package/src/built/cron.ts +117 -101
- package/src/built/database.ts +128 -33
- package/src/built/dispatcher.ts +332 -0
- package/src/built/permission.ts +146 -54
- package/src/built/skill.ts +280 -0
- package/src/built/tool.ts +245 -366
- package/src/feature.ts +113 -0
- package/src/index.ts +7 -0
- package/src/plugin.ts +198 -33
- package/src/types.ts +6 -10
- package/tests/adapter.test.ts +153 -1
- package/tests/ai/agent.test.ts +614 -0
- package/tests/ai/ai-trigger.test.ts +368 -0
- package/tests/ai/context-manager.test.ts +413 -0
- package/tests/ai/conversation-memory.test.ts +128 -0
- package/tests/ai/follow-up.test.ts +175 -0
- package/tests/ai/integration.test.ts +584 -0
- package/tests/ai/output.test.ts +128 -0
- package/tests/ai/providers.integration.test.ts +227 -0
- package/tests/ai/rate-limiter.test.ts +108 -0
- package/tests/ai/session.test.ts +375 -0
- package/tests/ai/setup.ts +308 -0
- package/tests/ai/tone-detector.test.ts +80 -0
- package/tests/ai/tool.test.ts +800 -0
- package/tests/ai/tools-builtin.test.ts +346 -0
- package/tests/ai/user-profile.test.ts +73 -0
- package/tests/ai/zhin-agent.test.ts +177 -0
- package/tests/config.test.ts +46 -0
- package/tests/cron.test.ts +94 -5
- package/tests/dispatcher.test.ts +146 -0
- package/tests/feature.test.ts +145 -0
- package/tests/features-builtin.test.ts +191 -0
- package/tests/plugin.test.ts +88 -14
- package/tests/skill-feature.test.ts +179 -0
- package/tests/tool-feature.test.ts +254 -0
package/lib/built/database.js
CHANGED
|
@@ -1,28 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatabaseFeature
|
|
3
|
+
* 数据库服务,管理数据模型定义,继承自 Feature 抽象类
|
|
4
|
+
*/
|
|
1
5
|
import { Registry } from "@zhin.js/database";
|
|
2
|
-
import {
|
|
6
|
+
import { Feature } from "../feature.js";
|
|
7
|
+
import { getPlugin } from "../plugin.js";
|
|
3
8
|
import { SystemLogDefinition } from "../models/system-log.js";
|
|
4
9
|
import { UserDefinition } from "../models/user.js";
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
export class DatabaseFeature extends Feature {
|
|
11
|
+
name = 'database';
|
|
12
|
+
icon = 'Database';
|
|
13
|
+
desc = '数据模型';
|
|
14
|
+
/** 内部数据库实例 */
|
|
15
|
+
db;
|
|
16
|
+
/** 按模型名索引 */
|
|
17
|
+
byName = new Map();
|
|
18
|
+
constructor(config) {
|
|
19
|
+
super();
|
|
20
|
+
this.db = Registry.create(config.dialect, config, {
|
|
21
|
+
SystemLog: SystemLogDefinition,
|
|
22
|
+
User: UserDefinition,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// ====================================================================
|
|
26
|
+
// 向后兼容代理:旧代码 inject('database').xxx 可直接使用
|
|
27
|
+
// ====================================================================
|
|
28
|
+
get models() {
|
|
29
|
+
return this.db.models;
|
|
30
|
+
}
|
|
31
|
+
define(name, definition) {
|
|
32
|
+
return this.db.define(name, definition);
|
|
33
|
+
}
|
|
34
|
+
start() {
|
|
35
|
+
return this.db.start();
|
|
36
|
+
}
|
|
37
|
+
stop() {
|
|
38
|
+
return this.db.stop();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 添加模型定义
|
|
42
|
+
*/
|
|
43
|
+
add(record, pluginName) {
|
|
44
|
+
this.db.define(record.name, record.definition);
|
|
45
|
+
this.byName.set(record.name, record);
|
|
46
|
+
return super.add(record, pluginName);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 移除模型定义
|
|
50
|
+
*/
|
|
51
|
+
remove(record) {
|
|
52
|
+
this.byName.delete(record.name);
|
|
53
|
+
return super.remove(record);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 生命周期: 启动数据库
|
|
57
|
+
*/
|
|
58
|
+
async mounted(plugin) {
|
|
59
|
+
plugin.logger.info('Database service started');
|
|
60
|
+
await this.db.start();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 生命周期: 停止数据库
|
|
64
|
+
*/
|
|
65
|
+
async dispose() {
|
|
66
|
+
await this.db.stop();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 序列化为 JSON
|
|
70
|
+
*/
|
|
71
|
+
toJSON(pluginName) {
|
|
72
|
+
const list = pluginName ? this.getByPlugin(pluginName) : this.items;
|
|
73
|
+
return {
|
|
74
|
+
name: this.name,
|
|
75
|
+
icon: this.icon,
|
|
76
|
+
desc: this.desc,
|
|
77
|
+
count: list.length,
|
|
78
|
+
items: list.map(r => ({
|
|
79
|
+
name: r.name,
|
|
80
|
+
})),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 提供给 Plugin.prototype 的扩展方法
|
|
85
|
+
*/
|
|
86
|
+
get extensions() {
|
|
87
|
+
const feature = this;
|
|
88
|
+
return {
|
|
22
89
|
defineModel(name, definition) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
90
|
+
const plugin = getPlugin();
|
|
91
|
+
const record = { name: name, definition };
|
|
92
|
+
const dispose = feature.add(record, plugin.name);
|
|
93
|
+
plugin.recordFeatureContribution(feature.name, name);
|
|
94
|
+
plugin.onDispose(dispose);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
27
98
|
}
|
|
28
99
|
//# sourceMappingURL=database.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/built/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/built/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageDispatcher — 消息调度器
|
|
3
|
+
*
|
|
4
|
+
* 取代原先的"大杂烩中间件链",将消息处理分为三个清晰阶段:
|
|
5
|
+
*
|
|
6
|
+
* ┌────────────────────────────────────────┐
|
|
7
|
+
* │ Stage 1: Guardrail(护栏) │
|
|
8
|
+
* │ 鉴权、限流、安全过滤、日志记录 │
|
|
9
|
+
* │ 始终执行,不可被 AI 跳过 │
|
|
10
|
+
* └──────────────┬─────────────────────────┘
|
|
11
|
+
* ▼
|
|
12
|
+
* ┌────────────────────────────────────────┐
|
|
13
|
+
* │ Stage 2: Route(路径判定) │
|
|
14
|
+
* │ 精确命令 → Command 快速路径 │
|
|
15
|
+
* │ 其它消息 → AI Agent 路径 │
|
|
16
|
+
* └──────────────┬─────────────────────────┘
|
|
17
|
+
* ▼
|
|
18
|
+
* ┌────────────────────────────────────────┐
|
|
19
|
+
* │ Stage 3: Handle(处理) │
|
|
20
|
+
* │ Command: commandService.handle() │
|
|
21
|
+
* │ AI: aiHandler (由 AI 模块注册) │
|
|
22
|
+
* └────────────────────────────────────────┘
|
|
23
|
+
*
|
|
24
|
+
* 注意:Context key 为 'dispatcher',避免与 HTTP 模块的 'router' 冲突。
|
|
25
|
+
*/
|
|
26
|
+
import { Message } from '../message.js';
|
|
27
|
+
import type { MessageMiddleware, RegisteredAdapter, MaybePromise } from '../types.js';
|
|
28
|
+
import type { Context } from '../plugin.js';
|
|
29
|
+
/**
|
|
30
|
+
* 路由判定结果
|
|
31
|
+
*/
|
|
32
|
+
export type RouteResult = {
|
|
33
|
+
type: 'command';
|
|
34
|
+
} | {
|
|
35
|
+
type: 'ai';
|
|
36
|
+
content: string;
|
|
37
|
+
} | {
|
|
38
|
+
type: 'skip';
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* AI 处理函数签名
|
|
42
|
+
* 由 AI 模块通过 dispatcher.setAIHandler() 注册
|
|
43
|
+
*/
|
|
44
|
+
export type AIHandler = (message: Message<any>, content: string) => MaybePromise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* 命令前缀判定函数
|
|
47
|
+
* 返回 true 表示该消息是精确命令调用
|
|
48
|
+
*/
|
|
49
|
+
export type CommandMatcher = (text: string, message: Message<any>) => boolean;
|
|
50
|
+
/**
|
|
51
|
+
* AI 触发判定函数
|
|
52
|
+
* 返回 { triggered, content } 表示是否应该触发 AI 以及提取的内容
|
|
53
|
+
*/
|
|
54
|
+
export type AITriggerMatcher = (message: Message<any>) => {
|
|
55
|
+
triggered: boolean;
|
|
56
|
+
content: string;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Guardrail 中间件
|
|
60
|
+
* 与 MessageMiddleware 签名一致,但语义上只用于鉴权/限流/安全/日志
|
|
61
|
+
* 返回 false 或抛异常表示拦截消息
|
|
62
|
+
*/
|
|
63
|
+
export type GuardrailMiddleware = MessageMiddleware<RegisteredAdapter>;
|
|
64
|
+
/**
|
|
65
|
+
* MessageDispatcher 服务接口
|
|
66
|
+
*/
|
|
67
|
+
export interface MessageDispatcherService {
|
|
68
|
+
/**
|
|
69
|
+
* 调度一条消息 — 这是唯一的入口
|
|
70
|
+
* Adapter 的 message.receive 事件应该调用此方法
|
|
71
|
+
*/
|
|
72
|
+
dispatch(message: Message<any>): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* 注册 Guardrail(护栏中间件)
|
|
75
|
+
* Guardrail 始终执行,用于鉴权、限流、安全过滤、日志等
|
|
76
|
+
* @returns 移除函数
|
|
77
|
+
*/
|
|
78
|
+
addGuardrail(guardrail: GuardrailMiddleware): () => void;
|
|
79
|
+
/**
|
|
80
|
+
* 设置命令匹配器
|
|
81
|
+
* 用于判定消息是否为精确命令调用
|
|
82
|
+
* 默认:检查消息是否以已注册命令的 pattern 开头
|
|
83
|
+
*/
|
|
84
|
+
setCommandMatcher(matcher: CommandMatcher): void;
|
|
85
|
+
/**
|
|
86
|
+
* 设置 AI 触发判定器
|
|
87
|
+
* 用于判定消息是否应该触发 AI 处理
|
|
88
|
+
* 由 AI 模块注册
|
|
89
|
+
*/
|
|
90
|
+
setAITriggerMatcher(matcher: AITriggerMatcher): void;
|
|
91
|
+
/**
|
|
92
|
+
* 注册 AI 处理函数
|
|
93
|
+
* 由 AI 模块注册,当消息路由到 AI 路径时调用
|
|
94
|
+
*/
|
|
95
|
+
setAIHandler(handler: AIHandler): void;
|
|
96
|
+
/**
|
|
97
|
+
* 获取当前是否已注册 AI 处理能力
|
|
98
|
+
*/
|
|
99
|
+
hasAIHandler(): boolean;
|
|
100
|
+
}
|
|
101
|
+
export interface DispatcherContextExtensions {
|
|
102
|
+
/** 注册 Guardrail(护栏中间件) */
|
|
103
|
+
addGuardrail(guardrail: GuardrailMiddleware): () => void;
|
|
104
|
+
}
|
|
105
|
+
declare module '../plugin.js' {
|
|
106
|
+
namespace Plugin {
|
|
107
|
+
interface Extensions extends DispatcherContextExtensions {
|
|
108
|
+
}
|
|
109
|
+
interface Contexts {
|
|
110
|
+
dispatcher: MessageDispatcherService;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 创建 MessageDispatcher Context
|
|
116
|
+
*/
|
|
117
|
+
export declare function createMessageDispatcher(): Context<'dispatcher', DispatcherContextExtensions>;
|
|
118
|
+
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/built/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAEjB,YAAY,EAGb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAM5C;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,OAAO,EAAE,MAAM,KACZ,YAAY,CAAC,IAAI,CAAC,CAAC;AAExB;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC;AAE9E;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAElG;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAMvE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAAC;IAEzD;;;;OAIG;IACH,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAEjD;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAErD;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAEvC;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC;CACzB;AAMD,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B;IAC1B,YAAY,CAAC,SAAS,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAAC;CAC1D;AAED,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,MAAM,CAAC;QACf,UAAU,UAAW,SAAQ,2BAA2B;SAAG;QAC3D,UAAU,QAAQ;YAChB,UAAU,EAAE,wBAAwB,CAAC;SACtC;KACF;CACF;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAAC,YAAY,EAAE,2BAA2B,CAAC,CAqL5F"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageDispatcher — 消息调度器
|
|
3
|
+
*
|
|
4
|
+
* 取代原先的"大杂烩中间件链",将消息处理分为三个清晰阶段:
|
|
5
|
+
*
|
|
6
|
+
* ┌────────────────────────────────────────┐
|
|
7
|
+
* │ Stage 1: Guardrail(护栏) │
|
|
8
|
+
* │ 鉴权、限流、安全过滤、日志记录 │
|
|
9
|
+
* │ 始终执行,不可被 AI 跳过 │
|
|
10
|
+
* └──────────────┬─────────────────────────┘
|
|
11
|
+
* ▼
|
|
12
|
+
* ┌────────────────────────────────────────┐
|
|
13
|
+
* │ Stage 2: Route(路径判定) │
|
|
14
|
+
* │ 精确命令 → Command 快速路径 │
|
|
15
|
+
* │ 其它消息 → AI Agent 路径 │
|
|
16
|
+
* └──────────────┬─────────────────────────┘
|
|
17
|
+
* ▼
|
|
18
|
+
* ┌────────────────────────────────────────┐
|
|
19
|
+
* │ Stage 3: Handle(处理) │
|
|
20
|
+
* │ Command: commandService.handle() │
|
|
21
|
+
* │ AI: aiHandler (由 AI 模块注册) │
|
|
22
|
+
* └────────────────────────────────────────┘
|
|
23
|
+
*
|
|
24
|
+
* 注意:Context key 为 'dispatcher',避免与 HTTP 模块的 'router' 冲突。
|
|
25
|
+
*/
|
|
26
|
+
import { getPlugin } from '../plugin.js';
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// 实现
|
|
29
|
+
// ============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* 创建 MessageDispatcher Context
|
|
32
|
+
*/
|
|
33
|
+
export function createMessageDispatcher() {
|
|
34
|
+
// 护栏中间件列表
|
|
35
|
+
const guardrails = [];
|
|
36
|
+
// AI 处理函数(由 AI 模块注册)
|
|
37
|
+
let aiHandler = null;
|
|
38
|
+
// AI 触发判定器(由 AI 模块注册)
|
|
39
|
+
let aiTriggerMatcher = null;
|
|
40
|
+
// 命令匹配器(默认由 command service 驱动)
|
|
41
|
+
let commandMatcher = null;
|
|
42
|
+
// 根插件引用(mounted 时设置)
|
|
43
|
+
let rootPlugin = null;
|
|
44
|
+
/**
|
|
45
|
+
* 执行 Guardrail 管道
|
|
46
|
+
* 返回 true 表示消息通过,false 表示被拦截
|
|
47
|
+
*/
|
|
48
|
+
async function runGuardrails(message) {
|
|
49
|
+
if (guardrails.length === 0)
|
|
50
|
+
return true;
|
|
51
|
+
let passed = true;
|
|
52
|
+
let index = 0;
|
|
53
|
+
const runNext = async () => {
|
|
54
|
+
if (index >= guardrails.length)
|
|
55
|
+
return;
|
|
56
|
+
const guardrail = guardrails[index++];
|
|
57
|
+
try {
|
|
58
|
+
await guardrail(message, runNext);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Guardrail 抛异常 → 拦截消息
|
|
62
|
+
passed = false;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
await runNext();
|
|
66
|
+
return passed;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 路由判定:这条消息该走哪条路径?
|
|
70
|
+
*/
|
|
71
|
+
function route(message) {
|
|
72
|
+
// 提取文本内容
|
|
73
|
+
const text = extractText(message);
|
|
74
|
+
// 1. 如果有自定义命令匹配器,优先使用
|
|
75
|
+
if (commandMatcher && commandMatcher(text, message)) {
|
|
76
|
+
return { type: 'command' };
|
|
77
|
+
}
|
|
78
|
+
// 2. 默认命令匹配:检查 commandService
|
|
79
|
+
if (rootPlugin) {
|
|
80
|
+
const commandService = rootPlugin.inject('command');
|
|
81
|
+
if (commandService?.items) {
|
|
82
|
+
for (const cmd of commandService.items) {
|
|
83
|
+
const pattern = cmd.pattern?.split(/\s/)[0];
|
|
84
|
+
if (pattern && text.startsWith(pattern)) {
|
|
85
|
+
return { type: 'command' };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// 3. AI 触发判定
|
|
91
|
+
if (aiTriggerMatcher) {
|
|
92
|
+
const { triggered, content } = aiTriggerMatcher(message);
|
|
93
|
+
if (triggered) {
|
|
94
|
+
return { type: 'ai', content };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// 4. 都不匹配 → 跳过
|
|
98
|
+
return { type: 'skip' };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 提取消息文本(简单实现,与 ai-trigger 中的 extractTextContent 对齐)
|
|
102
|
+
*/
|
|
103
|
+
function extractText(message) {
|
|
104
|
+
if (!message.$content)
|
|
105
|
+
return '';
|
|
106
|
+
return message.$content
|
|
107
|
+
.map((seg) => {
|
|
108
|
+
if (typeof seg === 'string')
|
|
109
|
+
return seg;
|
|
110
|
+
if (seg.type === 'text')
|
|
111
|
+
return seg.data?.text || '';
|
|
112
|
+
return '';
|
|
113
|
+
})
|
|
114
|
+
.join('')
|
|
115
|
+
.trim();
|
|
116
|
+
}
|
|
117
|
+
// ─── 服务实例 ───────────────────────────────────────────────────────────
|
|
118
|
+
const service = {
|
|
119
|
+
async dispatch(message) {
|
|
120
|
+
// Stage 1: Guardrail
|
|
121
|
+
const passed = await runGuardrails(message);
|
|
122
|
+
if (!passed)
|
|
123
|
+
return;
|
|
124
|
+
// Stage 2: Route
|
|
125
|
+
const result = route(message);
|
|
126
|
+
// Stage 3: Handle
|
|
127
|
+
switch (result.type) {
|
|
128
|
+
case 'command': {
|
|
129
|
+
// 命令快速路径 — 直接委托给 commandService
|
|
130
|
+
if (rootPlugin) {
|
|
131
|
+
const commandService = rootPlugin.inject('command');
|
|
132
|
+
if (commandService) {
|
|
133
|
+
const response = await commandService.handle(message, rootPlugin);
|
|
134
|
+
if (response) {
|
|
135
|
+
await message.$reply(response);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case 'ai': {
|
|
142
|
+
// AI Agent 路径
|
|
143
|
+
if (aiHandler) {
|
|
144
|
+
await aiHandler(message, result.content);
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case 'skip':
|
|
149
|
+
default:
|
|
150
|
+
// 不处理
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
// 兼容:仍然执行旧的中间件链(除了默认的命令中间件和 AI 触发中间件)
|
|
154
|
+
// 这样既有 Guardrail/Dispatcher 新逻辑,又不会丢失已有的自定义中间件
|
|
155
|
+
// Phase 1 阶段先保持兼容,后续逐步迁移
|
|
156
|
+
},
|
|
157
|
+
addGuardrail(guardrail) {
|
|
158
|
+
guardrails.push(guardrail);
|
|
159
|
+
return () => {
|
|
160
|
+
const index = guardrails.indexOf(guardrail);
|
|
161
|
+
if (index !== -1)
|
|
162
|
+
guardrails.splice(index, 1);
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
setCommandMatcher(matcher) {
|
|
166
|
+
commandMatcher = matcher;
|
|
167
|
+
},
|
|
168
|
+
setAITriggerMatcher(matcher) {
|
|
169
|
+
aiTriggerMatcher = matcher;
|
|
170
|
+
},
|
|
171
|
+
setAIHandler(handler) {
|
|
172
|
+
aiHandler = handler;
|
|
173
|
+
},
|
|
174
|
+
hasAIHandler() {
|
|
175
|
+
return aiHandler !== null;
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
return {
|
|
179
|
+
name: 'dispatcher',
|
|
180
|
+
description: '消息调度器 — 统一消息路由分流 (Command / AI)',
|
|
181
|
+
value: service,
|
|
182
|
+
mounted(plugin) {
|
|
183
|
+
rootPlugin = plugin.root;
|
|
184
|
+
return service;
|
|
185
|
+
},
|
|
186
|
+
extensions: {
|
|
187
|
+
addGuardrail(guardrail) {
|
|
188
|
+
const plugin = getPlugin();
|
|
189
|
+
const dispose = service.addGuardrail(guardrail);
|
|
190
|
+
plugin.onDispose(dispose);
|
|
191
|
+
return dispose;
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/built/dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,55 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* PermissionFeature
|
|
3
|
+
* 权限管理服务,继承自 Feature 抽象类
|
|
4
|
+
*/
|
|
5
|
+
import { Feature, FeatureJSON } from "../feature.js";
|
|
6
|
+
import type { MaybePromise, RegisteredAdapter, AdapterMessage } from "../types.js";
|
|
7
|
+
import { Message as MessageClass } from "../message.js";
|
|
2
8
|
export type PermissionItem<T extends RegisteredAdapter = RegisteredAdapter> = {
|
|
3
9
|
name: string | RegExp;
|
|
4
10
|
check: PermissionChecker<T>;
|
|
5
11
|
};
|
|
6
|
-
export type PermissionChecker<T extends RegisteredAdapter = RegisteredAdapter> = (name: string, message:
|
|
7
|
-
|
|
12
|
+
export type PermissionChecker<T extends RegisteredAdapter = RegisteredAdapter> = (name: string, message: MessageClass<AdapterMessage<T>>) => MaybePromise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* PermissionFeature 扩展方法类型
|
|
15
|
+
*/
|
|
16
|
+
export interface PermissionContextExtensions {
|
|
17
|
+
addPermission(permission: PermissionItem): () => void;
|
|
18
|
+
}
|
|
19
|
+
declare module "../plugin.js" {
|
|
20
|
+
namespace Plugin {
|
|
21
|
+
interface Extensions extends PermissionContextExtensions {
|
|
22
|
+
}
|
|
23
|
+
interface Contexts {
|
|
24
|
+
permission: PermissionFeature;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export declare class PermissionFeature extends Feature<PermissionItem> {
|
|
29
|
+
readonly name: "permission";
|
|
30
|
+
readonly icon = "Shield";
|
|
31
|
+
readonly desc = "\u6743\u9650";
|
|
8
32
|
constructor();
|
|
9
|
-
|
|
10
|
-
|
|
33
|
+
/**
|
|
34
|
+
* 检查权限
|
|
35
|
+
*/
|
|
36
|
+
check(name: string, message: MessageClass<AdapterMessage<RegisteredAdapter>>): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* 序列化为 JSON
|
|
39
|
+
*/
|
|
40
|
+
toJSON(pluginName?: string): FeatureJSON;
|
|
41
|
+
/**
|
|
42
|
+
* 提供给 Plugin.prototype 的扩展方法
|
|
43
|
+
*/
|
|
44
|
+
get extensions(): {
|
|
45
|
+
addPermission(permission: PermissionItem): () => void;
|
|
46
|
+
};
|
|
11
47
|
}
|
|
12
48
|
export declare namespace Permissions {
|
|
13
49
|
function define<T extends RegisteredAdapter = RegisteredAdapter>(name: string | RegExp, check: PermissionChecker<T>): PermissionItem<T>;
|
|
14
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* @deprecated Use PermissionFeature instead
|
|
53
|
+
*/
|
|
54
|
+
export declare const PermissionService: typeof PermissionFeature;
|
|
15
55
|
//# sourceMappingURL=permission.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/built/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/built/permission.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,IAAI;IAC5E,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,IAAI,CAC/E,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,KACrC,YAAY,CAAC,OAAO,CAAC,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,aAAa,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,IAAI,CAAC;CACvD;AAED,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,MAAM,CAAC;QACf,UAAU,UAAW,SAAQ,2BAA2B;SAAG;QAC3D,UAAU,QAAQ;YAChB,UAAU,EAAE,iBAAiB,CAAC;SAC/B;KACF;CACF;AAED,qBAAa,iBAAkB,SAAQ,OAAO,CAAC,cAAc,CAAC;IAC5D,QAAQ,CAAC,IAAI,EAAG,YAAY,CAAU;IACtC,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,IAAI,kBAAQ;;IAuDrB;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAQrG;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW;IAaxC;;OAEG;IACH,IAAI,UAAU;kCAGgB,cAAc;MAS3C;CACF;AAED,yBAAiB,WAAW,CAAC;IAC3B,SAAgB,MAAM,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,EACpE,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC1B,cAAc,CAAC,CAAC,CAAC,CAEnB;CACF;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,0BAAoB,CAAC"}
|
package/lib/built/permission.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* PermissionFeature
|
|
3
|
+
* 权限管理服务,继承自 Feature 抽象类
|
|
4
|
+
*/
|
|
5
|
+
import { Feature } from "../feature.js";
|
|
6
|
+
import { getPlugin } from "../plugin.js";
|
|
7
|
+
export class PermissionFeature extends Feature {
|
|
8
|
+
name = 'permission';
|
|
9
|
+
icon = 'Shield';
|
|
10
|
+
desc = '权限';
|
|
2
11
|
constructor() {
|
|
3
12
|
super();
|
|
13
|
+
// 注册默认权限检查器(使用 'built-in' 作为插件名)
|
|
4
14
|
this.add(Permissions.define(/^adapter\([^)]+\)$/, (name, message) => {
|
|
5
15
|
return message.$adapter === name.replace(/^adapter\(([^)]+)\)$/, '$1');
|
|
6
|
-
}));
|
|
16
|
+
}), '__built-in__');
|
|
7
17
|
this.add(Permissions.define(/^group\([^)]+\)$/, (name, message) => {
|
|
8
18
|
const match = name.match(/^group\(([^)]+)\)$/);
|
|
9
19
|
if (!match)
|
|
@@ -14,7 +24,7 @@ export class PermissionService extends Array {
|
|
|
14
24
|
if (id === '' || id === '*')
|
|
15
25
|
return true;
|
|
16
26
|
return message.$channel.id === id;
|
|
17
|
-
}));
|
|
27
|
+
}), '__built-in__');
|
|
18
28
|
this.add(Permissions.define(/^private\([^)]+\)$/, (name, message) => {
|
|
19
29
|
const match = name.match(/^private\(([^)]+)\)$/);
|
|
20
30
|
if (!match)
|
|
@@ -25,7 +35,7 @@ export class PermissionService extends Array {
|
|
|
25
35
|
if (id === '' || id === '*')
|
|
26
36
|
return true;
|
|
27
37
|
return message.$channel.id === id;
|
|
28
|
-
}));
|
|
38
|
+
}), '__built-in__');
|
|
29
39
|
this.add(Permissions.define(/^channel\([^)]+\)$/, (name, message) => {
|
|
30
40
|
const match = name.match(/^channel\(([^)]+)\)$/);
|
|
31
41
|
if (!match)
|
|
@@ -36,26 +46,57 @@ export class PermissionService extends Array {
|
|
|
36
46
|
if (id === '' || id === '*')
|
|
37
47
|
return true;
|
|
38
48
|
return message.$channel.id === id;
|
|
39
|
-
}));
|
|
49
|
+
}), '__built-in__');
|
|
40
50
|
this.add(Permissions.define(/^user\([^)]+\)$/, (name, message) => {
|
|
41
|
-
const match = name.match(/^
|
|
51
|
+
const match = name.match(/^user\(([^)]+)\)$/);
|
|
42
52
|
if (!match)
|
|
43
53
|
return false;
|
|
44
54
|
const id = match[1];
|
|
45
55
|
return message.$sender.id === id;
|
|
46
|
-
}));
|
|
47
|
-
}
|
|
48
|
-
add(permission) {
|
|
49
|
-
this.push(permission);
|
|
56
|
+
}), '__built-in__');
|
|
50
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* 检查权限
|
|
60
|
+
*/
|
|
51
61
|
async check(name, message) {
|
|
52
|
-
for (const permission of this) {
|
|
62
|
+
for (const permission of this.items) {
|
|
53
63
|
const passed = await permission.check(name, message);
|
|
54
64
|
if (passed)
|
|
55
65
|
return true;
|
|
56
66
|
}
|
|
57
67
|
return false;
|
|
58
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* 序列化为 JSON
|
|
71
|
+
*/
|
|
72
|
+
toJSON(pluginName) {
|
|
73
|
+
const list = pluginName ? this.getByPlugin(pluginName) : this.items;
|
|
74
|
+
return {
|
|
75
|
+
name: this.name,
|
|
76
|
+
icon: this.icon,
|
|
77
|
+
desc: this.desc,
|
|
78
|
+
count: list.length,
|
|
79
|
+
items: list.map(p => ({
|
|
80
|
+
name: p.name instanceof RegExp ? p.name.source : p.name,
|
|
81
|
+
})),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 提供给 Plugin.prototype 的扩展方法
|
|
86
|
+
*/
|
|
87
|
+
get extensions() {
|
|
88
|
+
const feature = this;
|
|
89
|
+
return {
|
|
90
|
+
addPermission(permission) {
|
|
91
|
+
const plugin = getPlugin();
|
|
92
|
+
const dispose = feature.add(permission, plugin.name);
|
|
93
|
+
const permName = permission.name instanceof RegExp ? permission.name.source : permission.name;
|
|
94
|
+
plugin.recordFeatureContribution(feature.name, permName);
|
|
95
|
+
plugin.onDispose(dispose);
|
|
96
|
+
return dispose;
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
59
100
|
}
|
|
60
101
|
export var Permissions;
|
|
61
102
|
(function (Permissions) {
|
|
@@ -64,4 +105,8 @@ export var Permissions;
|
|
|
64
105
|
}
|
|
65
106
|
Permissions.define = define;
|
|
66
107
|
})(Permissions || (Permissions = {}));
|
|
108
|
+
/**
|
|
109
|
+
* @deprecated Use PermissionFeature instead
|
|
110
|
+
*/
|
|
111
|
+
export const PermissionService = PermissionFeature;
|
|
67
112
|
//# sourceMappingURL=permission.js.map
|