koishi-plugin-github-webhook-pusher 0.0.7 → 0.0.8

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.
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /**
3
+ * 命令模块入口
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerUtilCommands = exports.registerSubscriptionCommands = exports.registerTrustCommands = void 0;
7
+ var trust_1 = require("./trust");
8
+ Object.defineProperty(exports, "registerTrustCommands", { enumerable: true, get: function () { return trust_1.registerTrustCommands; } });
9
+ var subscription_1 = require("./subscription");
10
+ Object.defineProperty(exports, "registerSubscriptionCommands", { enumerable: true, get: function () { return subscription_1.registerSubscriptionCommands; } });
11
+ var utils_1 = require("./utils");
12
+ Object.defineProperty(exports, "registerUtilCommands", { enumerable: true, get: function () { return utils_1.registerUtilCommands; } });
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ /**
3
+ * 订阅管理命令
4
+ * 需求: 3.1-3.7
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.registerSubscriptionCommands = registerSubscriptionCommands;
8
+ const types_1 = require("../types");
9
+ const trust_1 = require("../repository/trust");
10
+ const subscription_1 = require("../repository/subscription");
11
+ /** 所有支持的事件类型 */
12
+ const ALL_EVENT_TYPES = [
13
+ 'issues',
14
+ 'issue_comment',
15
+ 'pull_request',
16
+ 'pull_request_review',
17
+ 'pull_request_review_comment',
18
+ 'release',
19
+ 'push',
20
+ 'star',
21
+ 'fork',
22
+ 'create',
23
+ 'delete',
24
+ 'workflow_run',
25
+ ];
26
+ /**
27
+ * 从会话中提取会话标识
28
+ */
29
+ function getSessionIdentifier(session) {
30
+ return {
31
+ platform: session.platform,
32
+ channelId: session.channelId,
33
+ guildId: session.guildId,
34
+ userId: session.userId,
35
+ };
36
+ }
37
+ /**
38
+ * 解析事件变更参数
39
+ * 格式: +issues -star +release
40
+ * @param changes 变更参数数组
41
+ * @param currentEvents 当前事件列表
42
+ * @returns 新的事件列表
43
+ */
44
+ function parseEventChanges(changes, currentEvents) {
45
+ const events = new Set(currentEvents);
46
+ for (const change of changes) {
47
+ if (!change)
48
+ continue;
49
+ const prefix = change[0];
50
+ const eventName = change.slice(1);
51
+ // 验证事件类型
52
+ if (!ALL_EVENT_TYPES.includes(eventName)) {
53
+ continue;
54
+ }
55
+ if (prefix === '+') {
56
+ events.add(eventName);
57
+ }
58
+ else if (prefix === '-') {
59
+ events.delete(eventName);
60
+ }
61
+ }
62
+ return Array.from(events);
63
+ }
64
+ /**
65
+ * 注册订阅管理命令
66
+ * @param ctx Koishi 上下文
67
+ * @param config 插件配置
68
+ */
69
+ function registerSubscriptionCommands(ctx, config) {
70
+ ctx.command('gh', 'GitHub Webhook 指令');
71
+ // gh.sub <repo> - 订阅仓库
72
+ ctx.command('gh.sub <repo:string>', '订阅 GitHub 仓库事件')
73
+ .usage('gh.sub owner/repo')
74
+ .example('gh.sub koishijs/koishi')
75
+ .action(async ({ session }, repo) => {
76
+ if (!session)
77
+ return '❌ 无法获取会话信息';
78
+ if (!repo) {
79
+ return '❌ 请指定仓库名,格式: owner/repo';
80
+ }
81
+ // 检查仓库是否在信任列表中
82
+ const trusted = await (0, trust_1.isInTrustList)(ctx, repo);
83
+ if (!trusted) {
84
+ return '❌ 该仓库不在信任列表中';
85
+ }
86
+ const sessionId = getSessionIdentifier(session);
87
+ const subscription = await (0, subscription_1.createSubscription)(ctx, sessionId, repo, config.defaultEvents);
88
+ if (subscription) {
89
+ const eventList = subscription.events.join(', ');
90
+ return `✅ 已订阅仓库: ${repo}\n📋 订阅事件: ${eventList}`;
91
+ }
92
+ return '❌ 订阅失败';
93
+ });
94
+ // gh.unsub <repo> - 取消订阅
95
+ ctx.command('gh.unsub <repo:string>', '取消订阅 GitHub 仓库')
96
+ .usage('gh.unsub owner/repo')
97
+ .example('gh.unsub koishijs/koishi')
98
+ .action(async ({ session }, repo) => {
99
+ if (!session)
100
+ return '❌ 无法获取会话信息';
101
+ if (!repo) {
102
+ return '❌ 请指定仓库名';
103
+ }
104
+ const sessionId = getSessionIdentifier(session);
105
+ const success = await (0, subscription_1.removeSubscription)(ctx, sessionId, repo);
106
+ if (success) {
107
+ return `✅ 已取消订阅: ${repo}`;
108
+ }
109
+ return `❌ 未找到仓库 ${repo} 的订阅`;
110
+ });
111
+ // gh.list - 列出当前会话的所有订阅
112
+ ctx.command('gh.list', '列出当前会话的所有订阅')
113
+ .usage('gh.list')
114
+ .action(async ({ session }) => {
115
+ if (!session)
116
+ return '❌ 无法获取会话信息';
117
+ const sessionId = getSessionIdentifier(session);
118
+ const subscriptions = await (0, subscription_1.listSubscriptions)(ctx, sessionId);
119
+ if (subscriptions.length === 0) {
120
+ return '📋 当前会话没有订阅任何仓库';
121
+ }
122
+ const lines = ['📋 订阅列表:'];
123
+ for (const sub of subscriptions) {
124
+ const status = sub.enabled ? '✅' : '⏸️';
125
+ const events = sub.events.join(', ');
126
+ lines.push(`${status} ${sub.repo}`);
127
+ lines.push(` 事件: ${events}`);
128
+ }
129
+ return lines.join('\n');
130
+ });
131
+ // gh.events <repo> - 查看订阅事件
132
+ ctx.command('gh.events [repo:string]', '查看订阅的事件类型')
133
+ .usage('gh.events [owner/repo]')
134
+ .example('gh.events koishijs/koishi')
135
+ .action(async ({ session }, repo) => {
136
+ if (!session)
137
+ return '❌ 无法获取会话信息';
138
+ if (!repo) {
139
+ // 显示所有可用事件类型
140
+ const lines = ['📋 可用事件类型:'];
141
+ for (const [type, info] of Object.entries(types_1.EVENT_DISPLAY_MAP)) {
142
+ lines.push(`${info.emoji} ${type} - ${info.name}`);
143
+ }
144
+ return lines.join('\n');
145
+ }
146
+ const sessionId = getSessionIdentifier(session);
147
+ const subscription = await (0, subscription_1.getSubscription)(ctx, sessionId, repo);
148
+ if (!subscription) {
149
+ return `❌ 未找到仓库 ${repo} 的订阅`;
150
+ }
151
+ const events = subscription.events.join(', ');
152
+ return `📋 ${repo} 订阅的事件:\n${events}`;
153
+ });
154
+ ctx.command('gh.on <repo:string> [...events:string]', '快捷启用订阅事件')
155
+ .usage('gh.on owner/repo issues pull_request')
156
+ .example('gh.on koishijs/koishi issues pull_request')
157
+ .action(async ({ session }, repo, ...events) => {
158
+ if (!session)
159
+ return '❌ 无法获取会话信息';
160
+ if (!repo) {
161
+ return '❌ 请指定仓库名';
162
+ }
163
+ if (!events || events.length === 0) {
164
+ const eventList = ALL_EVENT_TYPES.map(e => {
165
+ const info = types_1.EVENT_DISPLAY_MAP[e];
166
+ return `${info.emoji} ${e}`;
167
+ }).join(', ');
168
+ return `❌ 请指定事件类型\n可用类型: ${eventList}`;
169
+ }
170
+ const sessionId = getSessionIdentifier(session);
171
+ const subscription = await (0, subscription_1.getSubscription)(ctx, sessionId, repo);
172
+ if (!subscription) {
173
+ return `❌ 未找到仓库 ${repo} 的订阅`;
174
+ }
175
+ const changes = events.map(event => `+${event}`);
176
+ const newEvents = parseEventChanges(changes, subscription.events);
177
+ const success = await (0, subscription_1.updateEvents)(ctx, sessionId, repo, newEvents);
178
+ if (success) {
179
+ const eventList = newEvents.join(', ');
180
+ return `✅ 已启用 ${repo} 的订阅事件:\n${eventList}`;
181
+ }
182
+ return '❌ 更新失败';
183
+ });
184
+ ctx.command('gh.off <repo:string> [...events:string]', '快捷禁用订阅事件')
185
+ .usage('gh.off owner/repo issues pull_request')
186
+ .example('gh.off koishijs/koishi issues pull_request')
187
+ .action(async ({ session }, repo, ...events) => {
188
+ if (!session)
189
+ return '❌ 无法获取会话信息';
190
+ if (!repo) {
191
+ return '❌ 请指定仓库名';
192
+ }
193
+ if (!events || events.length === 0) {
194
+ const eventList = ALL_EVENT_TYPES.map(e => {
195
+ const info = types_1.EVENT_DISPLAY_MAP[e];
196
+ return `${info.emoji} ${e}`;
197
+ }).join(', ');
198
+ return `❌ 请指定事件类型\n可用类型: ${eventList}`;
199
+ }
200
+ const sessionId = getSessionIdentifier(session);
201
+ const subscription = await (0, subscription_1.getSubscription)(ctx, sessionId, repo);
202
+ if (!subscription) {
203
+ return `❌ 未找到仓库 ${repo} 的订阅`;
204
+ }
205
+ const changes = events.map(event => `-${event}`);
206
+ const newEvents = parseEventChanges(changes, subscription.events);
207
+ const success = await (0, subscription_1.updateEvents)(ctx, sessionId, repo, newEvents);
208
+ if (success) {
209
+ const eventList = newEvents.join(', ');
210
+ return `✅ 已禁用 ${repo} 的订阅事件:\n${eventList}`;
211
+ }
212
+ return '❌ 更新失败';
213
+ });
214
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /**
3
+ * 信任仓库管理命令
4
+ * 需求: 2.1-2.5, 8.3
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.registerTrustCommands = registerTrustCommands;
8
+ const trust_1 = require("../repository/trust");
9
+ /** 管理员权限等级 */
10
+ const ADMIN_AUTHORITY = 3;
11
+ /**
12
+ * 注册信任仓库管理命令
13
+ * @param ctx Koishi 上下文
14
+ */
15
+ function registerTrustCommands(ctx) {
16
+ // 创建 gh.trust 命令组
17
+ const trust = ctx.command('gh.trust', '管理信任的 GitHub 仓库')
18
+ .usage('gh.trust <add|remove|list|enable|disable> [repo]');
19
+ // gh.trust.add <repo> - 添加信任仓库
20
+ trust.subcommand('.add <repo:string>', '添加信任仓库')
21
+ .usage('gh.trust.add owner/repo')
22
+ .example('gh.trust.add koishijs/koishi')
23
+ .action(async ({ session }, repo) => {
24
+ // 权限检查
25
+ const user = session?.user;
26
+ if ((user?.authority ?? 0) < ADMIN_AUTHORITY) {
27
+ return '❌ 权限不足,需要管理员权限';
28
+ }
29
+ if (!repo) {
30
+ return '❌ 请指定仓库名,格式: owner/repo';
31
+ }
32
+ // 格式验证
33
+ if (!(0, trust_1.isValidRepoFormat)(repo)) {
34
+ return '❌ 仓库格式错误,请使用 owner/repo 格式';
35
+ }
36
+ const result = await (0, trust_1.addTrustedRepo)(ctx, repo);
37
+ if (result) {
38
+ return `✅ 已添加信任仓库: ${repo}`;
39
+ }
40
+ return '❌ 添加失败';
41
+ });
42
+ // gh.trust.remove <repo> - 移除信任仓库
43
+ trust.subcommand('.remove <repo:string>', '移除信任仓库')
44
+ .usage('gh.trust.remove owner/repo')
45
+ .example('gh.trust.remove koishijs/koishi')
46
+ .action(async ({ session }, repo) => {
47
+ // 权限检查
48
+ const user = session?.user;
49
+ if ((user?.authority ?? 0) < ADMIN_AUTHORITY) {
50
+ return '❌ 权限不足,需要管理员权限';
51
+ }
52
+ if (!repo) {
53
+ return '❌ 请指定仓库名';
54
+ }
55
+ const success = await (0, trust_1.removeTrustedRepo)(ctx, repo);
56
+ if (success) {
57
+ return `✅ 已移除信任仓库: ${repo}`;
58
+ }
59
+ return `❌ 仓库 ${repo} 不在信任列表中`;
60
+ });
61
+ // gh.trust.list - 列出所有信任仓库
62
+ trust.subcommand('.list', '列出所有信任仓库')
63
+ .usage('gh.trust.list')
64
+ .action(async ({ session }) => {
65
+ // 权限检查
66
+ const user = session?.user;
67
+ if ((user?.authority ?? 0) < ADMIN_AUTHORITY) {
68
+ return '❌ 权限不足,需要管理员权限';
69
+ }
70
+ const repos = await (0, trust_1.listTrustedRepos)(ctx);
71
+ if (repos.length === 0) {
72
+ return '📋 信任仓库列表为空';
73
+ }
74
+ const lines = ['📋 信任仓库列表:'];
75
+ for (const repo of repos) {
76
+ const status = repo.enabled ? '✅' : '⏸️';
77
+ lines.push(`${status} ${repo.repo}`);
78
+ }
79
+ return lines.join('\n');
80
+ });
81
+ // gh.trust.enable <repo> - 启用信任仓库
82
+ trust.subcommand('.enable <repo:string>', '启用信任仓库')
83
+ .usage('gh.trust.enable owner/repo')
84
+ .example('gh.trust.enable koishijs/koishi')
85
+ .action(async ({ session }, repo) => {
86
+ // 权限检查
87
+ const user = session?.user;
88
+ if ((user?.authority ?? 0) < ADMIN_AUTHORITY) {
89
+ return '❌ 权限不足,需要管理员权限';
90
+ }
91
+ if (!repo) {
92
+ return '❌ 请指定仓库名';
93
+ }
94
+ const success = await (0, trust_1.enableRepo)(ctx, repo);
95
+ if (success) {
96
+ return `✅ 已启用仓库: ${repo}`;
97
+ }
98
+ return `❌ 仓库 ${repo} 不在信任列表中`;
99
+ });
100
+ // gh.trust.disable <repo> - 禁用信任仓库
101
+ trust.subcommand('.disable <repo:string>', '禁用信任仓库')
102
+ .usage('gh.trust.disable owner/repo')
103
+ .example('gh.trust.disable koishijs/koishi')
104
+ .action(async ({ session }, repo) => {
105
+ // 权限检查
106
+ const user = session?.user;
107
+ if ((user?.authority ?? 0) < ADMIN_AUTHORITY) {
108
+ return '❌ 权限不足,需要管理员权限';
109
+ }
110
+ if (!repo) {
111
+ return '❌ 请指定仓库名';
112
+ }
113
+ const success = await (0, trust_1.disableRepo)(ctx, repo);
114
+ if (success) {
115
+ return `⏸️ 已禁用仓库: ${repo}`;
116
+ }
117
+ return `❌ 仓库 ${repo} 不在信任列表中`;
118
+ });
119
+ }
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ /**
3
+ * 工具命令
4
+ * 需求: 8.1, 8.2
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.registerUtilCommands = registerUtilCommands;
8
+ const types_1 = require("../types");
9
+ const trust_1 = require("../repository/trust");
10
+ const message_1 = require("../message");
11
+ /** 插件名称(避免循环依赖) */
12
+ const PLUGIN_NAME = 'github-webhook-pusher';
13
+ /** 管理员权限等级 */
14
+ const ADMIN_AUTHORITY = 3;
15
+ /** 所有支持的事件类型 */
16
+ const ALL_EVENT_TYPES = [
17
+ 'issues',
18
+ 'issue_comment',
19
+ 'pull_request',
20
+ 'pull_request_review',
21
+ 'pull_request_review_comment',
22
+ 'release',
23
+ 'push',
24
+ 'star',
25
+ 'fork',
26
+ 'create',
27
+ 'delete',
28
+ 'workflow_run',
29
+ ];
30
+ /**
31
+ * 生成测试事件数据
32
+ */
33
+ function generateTestEvent(repo, eventType) {
34
+ const baseEvent = {
35
+ type: eventType,
36
+ displayType: (0, types_1.getDisplayType)(eventType),
37
+ repo,
38
+ actor: 'test-user',
39
+ url: `https://github.com/${repo}`,
40
+ };
41
+ switch (eventType) {
42
+ case 'issues':
43
+ return {
44
+ ...baseEvent,
45
+ action: 'opened',
46
+ title: '测试 Issue 标题',
47
+ number: 123,
48
+ };
49
+ case 'issue_comment':
50
+ return {
51
+ ...baseEvent,
52
+ action: 'created',
53
+ title: '测试 Issue 标题',
54
+ number: 123,
55
+ };
56
+ case 'release':
57
+ return {
58
+ ...baseEvent,
59
+ action: 'published',
60
+ title: 'v1.0.0',
61
+ tagName: 'v1.0.0',
62
+ };
63
+ case 'push':
64
+ return {
65
+ ...baseEvent,
66
+ ref: 'main',
67
+ commits: [
68
+ { sha: 'abc1234', message: '测试提交 1', author: 'test-user', url: '' },
69
+ { sha: 'def5678', message: '测试提交 2', author: 'test-user', url: '' },
70
+ ],
71
+ totalCommits: 2,
72
+ };
73
+ case 'pull_request':
74
+ return {
75
+ ...baseEvent,
76
+ action: 'opened',
77
+ title: '测试 PR 标题',
78
+ number: 456,
79
+ };
80
+ case 'pull_request_review':
81
+ return {
82
+ ...baseEvent,
83
+ action: 'approved',
84
+ title: '测试 PR 标题',
85
+ number: 456,
86
+ };
87
+ case 'pull_request_review_comment':
88
+ return {
89
+ ...baseEvent,
90
+ action: 'created',
91
+ title: '测试 PR 标题',
92
+ number: 456,
93
+ };
94
+ case 'star':
95
+ return {
96
+ ...baseEvent,
97
+ action: 'created',
98
+ starCount: 1234,
99
+ };
100
+ case 'fork':
101
+ return {
102
+ ...baseEvent,
103
+ action: 'forked',
104
+ title: `${repo}-fork`,
105
+ };
106
+ case 'create':
107
+ return {
108
+ ...baseEvent,
109
+ action: 'created',
110
+ ref: 'branch:feature/test',
111
+ };
112
+ case 'delete':
113
+ return {
114
+ ...baseEvent,
115
+ action: 'deleted',
116
+ ref: 'branch:feature/old',
117
+ };
118
+ case 'workflow_run':
119
+ return {
120
+ ...baseEvent,
121
+ action: 'completed/success',
122
+ title: 'CI',
123
+ };
124
+ default:
125
+ return baseEvent;
126
+ }
127
+ }
128
+ /**
129
+ * 注册工具命令
130
+ * @param ctx Koishi 上下文
131
+ * @param config 插件配置
132
+ */
133
+ function registerUtilCommands(ctx, config) {
134
+ // gh.ping - 返回插件状态信息
135
+ ctx.command('gh.ping', '查看插件状态')
136
+ .usage('gh.ping')
137
+ .action(async () => {
138
+ const repos = await (0, trust_1.listTrustedRepos)(ctx);
139
+ const enabledCount = repos.filter(r => r.enabled).length;
140
+ const lines = [
141
+ '🏓 GitHub Webhook 推送插件',
142
+ `📦 插件名称: ${PLUGIN_NAME}`,
143
+ `🔗 Webhook 路径: ${config.path}`,
144
+ `📋 信任仓库: ${repos.length} 个 (${enabledCount} 个已启用)`,
145
+ `🔧 调试模式: ${config.debug ? '开启' : '关闭'}`,
146
+ ];
147
+ return lines.join('\n');
148
+ });
149
+ // gh.test <repo> <event> - 生成并推送测试消息(管理员)
150
+ ctx.command('gh.test <repo:string> <event:string>', '生成测试消息')
151
+ .usage('gh.test owner/repo event')
152
+ .example('gh.test koishijs/koishi issues')
153
+ .example('gh.test koishijs/koishi push')
154
+ .action(async ({ session }, repo, event) => {
155
+ // 权限检查
156
+ const user = session?.user;
157
+ if ((user?.authority ?? 0) < ADMIN_AUTHORITY) {
158
+ return '❌ 权限不足,需要管理员权限';
159
+ }
160
+ if (!repo) {
161
+ return '❌ 请指定仓库名,格式: owner/repo';
162
+ }
163
+ if (!event) {
164
+ const eventList = ALL_EVENT_TYPES.map(e => {
165
+ const info = types_1.EVENT_DISPLAY_MAP[e];
166
+ return `${info.emoji} ${e}`;
167
+ }).join(', ');
168
+ return `❌ 请指定事件类型\n可用类型: ${eventList}`;
169
+ }
170
+ // 验证事件类型
171
+ if (!ALL_EVENT_TYPES.includes(event)) {
172
+ const eventList = ALL_EVENT_TYPES.join(', ');
173
+ return `❌ 不支持的事件类型: ${event}\n可用类型: ${eventList}`;
174
+ }
175
+ // 生成测试事件
176
+ const testEvent = generateTestEvent(repo, event);
177
+ const message = (0, message_1.buildMessage)(testEvent);
178
+ // 发送测试消息到当前会话
179
+ await session?.send(message);
180
+ return; // 消息已发送,不需要额外返回
181
+ });
182
+ }
package/lib/config.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Config = void 0;
4
+ const koishi_1 = require("koishi");
5
+ /** 支持的事件类型列表 */
6
+ const EVENT_TYPES = [
7
+ 'issues',
8
+ 'issue_comment',
9
+ 'pull_request',
10
+ 'pull_request_review',
11
+ 'pull_request_review_comment',
12
+ 'release',
13
+ 'push',
14
+ 'star',
15
+ 'fork',
16
+ 'create',
17
+ 'delete',
18
+ 'workflow_run',
19
+ ];
20
+ exports.Config = koishi_1.Schema.object({
21
+ path: koishi_1.Schema.string().default('/github/webhook').description('Webhook 接收路径'),
22
+ secret: koishi_1.Schema.string().required().description('GitHub Webhook Secret'),
23
+ baseUrl: koishi_1.Schema.string().description('显示用基础 URL'),
24
+ defaultEvents: koishi_1.Schema.array(koishi_1.Schema.union(EVENT_TYPES.map(e => koishi_1.Schema.const(e))))
25
+ .default(['issues', 'release', 'push'])
26
+ .description('默认订阅事件'),
27
+ debug: koishi_1.Schema.boolean().default(false).description('调试模式'),
28
+ allowUntrusted: koishi_1.Schema.boolean().default(false).description('允许非信任仓库'),
29
+ concurrency: koishi_1.Schema.number().default(5).description('推送并发数'),
30
+ });
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extendDatabase = extendDatabase;
4
+ function extendDatabase(ctx) {
5
+ ctx.model.extend('github_trusted_repos', {
6
+ id: { type: 'unsigned', length: 10 },
7
+ repo: { type: 'string', length: 255 },
8
+ enabled: 'boolean',
9
+ createdAt: 'timestamp',
10
+ updatedAt: 'timestamp',
11
+ }, {
12
+ primary: 'id',
13
+ autoInc: true,
14
+ unique: ['repo'],
15
+ });
16
+ ctx.model.extend('github_subscriptions', {
17
+ id: { type: 'unsigned', length: 10 },
18
+ platform: 'string',
19
+ channelId: 'string',
20
+ guildId: 'string',
21
+ userId: 'string',
22
+ repo: 'string',
23
+ events: 'json',
24
+ enabled: 'boolean',
25
+ createdAt: 'timestamp',
26
+ updatedAt: 'timestamp',
27
+ }, {
28
+ primary: 'id',
29
+ autoInc: true,
30
+ });
31
+ ctx.model.extend('github_deliveries', {
32
+ deliveryId: 'string',
33
+ repo: 'string',
34
+ event: 'string',
35
+ receivedAt: 'timestamp',
36
+ }, {
37
+ primary: 'deliveryId',
38
+ });
39
+ }
package/lib/index.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * Koishi GitHub Webhook 推送插件入口
4
+ * 需求: 1.1, 7.1-7.7
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Config = exports.inject = exports.name = void 0;
8
+ exports.apply = apply;
9
+ const koishi_1 = require("koishi");
10
+ const config_1 = require("./config");
11
+ Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
12
+ const database_1 = require("./database");
13
+ const webhook_1 = require("./webhook");
14
+ const commands_1 = require("./commands");
15
+ /** 插件名称 */
16
+ exports.name = 'github-webhook-pusher';
17
+ /** 声明服务依赖 - 需要 server 服务提供 router 和 database 服务 */
18
+ exports.inject = ['server', 'database'];
19
+ /** 插件日志 */
20
+ const logger = new koishi_1.Logger('github-webhook-pusher');
21
+ /**
22
+ * 插件入口函数
23
+ * @param ctx Koishi 上下文
24
+ * @param config 插件配置
25
+ */
26
+ function apply(ctx, config) {
27
+ // 需求 7.1-7.7: 使用配置项
28
+ logger.info(`正在加载 GitHub Webhook 插件...`);
29
+ // 初始化数据库
30
+ // 需求 6.1, 6.2, 6.3: 创建数据库表
31
+ (0, database_1.extendDatabase)(ctx);
32
+ logger.debug('数据库模型已注册');
33
+ // 需求 1.1: 注册 Webhook 处理器
34
+ (0, webhook_1.registerWebhook)(ctx, config);
35
+ logger.debug(`Webhook 处理器已注册: ${config.path}`);
36
+ // 注册所有命令
37
+ // 需求 2.1-2.5: 信任仓库管理命令
38
+ (0, commands_1.registerTrustCommands)(ctx);
39
+ logger.debug('信任仓库管理命令已注册');
40
+ // 需求 3.1-3.7: 订阅管理命令
41
+ (0, commands_1.registerSubscriptionCommands)(ctx, config);
42
+ logger.debug('订阅管理命令已注册');
43
+ // 需求 8.1, 8.2: 工具命令
44
+ (0, commands_1.registerUtilCommands)(ctx, config);
45
+ logger.debug('工具命令已注册');
46
+ // 插件启动日志
47
+ logger.info(`GitHub Webhook 插件已加载`);
48
+ logger.info(`Webhook 路径: ${config.path}`);
49
+ logger.info(`默认订阅事件: ${config.defaultEvents.join(', ')}`);
50
+ if (config.debug) {
51
+ logger.info('调试模式已启用');
52
+ }
53
+ }