@dsh-plugin/dsh-synapse 0.1.0-dev.41044228975 → 0.1.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/LICENSE +661 -661
- package/README.md +0 -14
- package/package.json +1 -1
- package/vendor/gugle-chat-bot/LICENSE +661 -661
- package/vendor/gugle-chat-bot/package.json +57 -57
- package/vendor/gugle-chat-bot/src/allow-rule.yml +9345 -9345
- package/vendor/gugle-chat-bot/src/api.json +4284 -4284
- package/vendor/gugle-chat-bot/src/command/index.ts +141 -141
- package/vendor/gugle-chat-bot/src/config/features.ts +547 -547
- package/vendor/gugle-chat-bot/src/config/index.ts +184 -184
- package/vendor/gugle-chat-bot/src/config/manager.ts +356 -356
- package/vendor/gugle-chat-bot/src/constants/index.ts +13 -13
- package/vendor/gugle-chat-bot/src/custom.ts +548 -548
- package/vendor/gugle-chat-bot/src/event/index.ts +118 -118
- package/vendor/gugle-chat-bot/src/features/admin/index.ts +414 -414
- package/vendor/gugle-chat-bot/src/features/bili/image/impl/video.ts +39 -39
- package/vendor/gugle-chat-bot/src/features/bili/image/index.ts +37 -37
- package/vendor/gugle-chat-bot/src/features/bili/index.ts +65 -65
- package/vendor/gugle-chat-bot/src/features/bili/template/style/video.css +97 -97
- package/vendor/gugle-chat-bot/src/features/bili/template/video.html +56 -56
- package/vendor/gugle-chat-bot/src/features/discord-bridge/index.ts +1128 -1128
- package/vendor/gugle-chat-bot/src/features/discord-bridge/markdown.ts +105 -105
- package/vendor/gugle-chat-bot/src/features/discord-bridge/slash.ts +355 -355
- package/vendor/gugle-chat-bot/src/features/discord-bridge/source.ts +96 -96
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/message.html +14 -14
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/style/message.css +144 -144
- package/vendor/gugle-chat-bot/src/features/github/api.ts +93 -93
- package/vendor/gugle-chat-bot/src/features/github/binding.ts +161 -161
- package/vendor/gugle-chat-bot/src/features/github/image/impl/issue.ts +132 -132
- package/vendor/gugle-chat-bot/src/features/github/image/impl/pr.ts +144 -144
- package/vendor/gugle-chat-bot/src/features/github/image/impl/release.ts +160 -160
- package/vendor/gugle-chat-bot/src/features/github/image/index.ts +310 -310
- package/vendor/gugle-chat-bot/src/features/github/index.ts +302 -302
- package/vendor/gugle-chat-bot/src/features/github/template/issue.html +118 -118
- package/vendor/gugle-chat-bot/src/features/github/template/pull_request.html +125 -125
- package/vendor/gugle-chat-bot/src/features/github/template/release.html +53 -53
- package/vendor/gugle-chat-bot/src/features/github/template/style/issue.css +468 -468
- package/vendor/gugle-chat-bot/src/features/github/template/style/pull_request.css +468 -468
- package/vendor/gugle-chat-bot/src/features/github/template/style/release.css +412 -412
- package/vendor/gugle-chat-bot/src/features/hermes/client.ts +184 -184
- package/vendor/gugle-chat-bot/src/features/hermes/config.ts +210 -210
- package/vendor/gugle-chat-bot/src/features/hermes/context.ts +67 -67
- package/vendor/gugle-chat-bot/src/features/hermes/history.ts +86 -86
- package/vendor/gugle-chat-bot/src/features/hermes/index.ts +1533 -1533
- package/vendor/gugle-chat-bot/src/features/hermes/message.ts +319 -319
- package/vendor/gugle-chat-bot/src/features/hermes/reaction.ts +181 -181
- package/vendor/gugle-chat-bot/src/features/hermes/render.ts +118 -118
- package/vendor/gugle-chat-bot/src/features/hermes/reply-units.ts +331 -331
- package/vendor/gugle-chat-bot/src/features/hermes/skills.ts +406 -406
- package/vendor/gugle-chat-bot/src/features/hermes/template/approval.html +30 -30
- package/vendor/gugle-chat-bot/src/features/hermes/template/progress.html +21 -21
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/approval.css +81 -81
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/progress.css +120 -120
- package/vendor/gugle-chat-bot/src/features/hermes/trigger.ts +86 -86
- package/vendor/gugle-chat-bot/src/features/hermes/types.ts +327 -327
- package/vendor/gugle-chat-bot/src/features/management/index.ts +156 -156
- package/vendor/gugle-chat-bot/src/features/minecraft/index.ts +127 -127
- package/vendor/gugle-chat-bot/src/features/modrinth/index.ts +71 -71
- package/vendor/gugle-chat-bot/src/features/parentheses/index.ts +117 -117
- package/vendor/gugle-chat-bot/src/features/peak-valley-timer/index.ts +451 -451
- package/vendor/gugle-chat-bot/src/features/poke/index.ts +24 -24
- package/vendor/gugle-chat-bot/src/features/version-tracker/index.ts +77 -77
- package/vendor/gugle-chat-bot/src/features/welcome/index.ts +57 -57
- package/vendor/gugle-chat-bot/src/github-ip.json +5814 -5814
- package/vendor/gugle-chat-bot/src/image/index.ts +278 -278
- package/vendor/gugle-chat-bot/src/index.ts +695 -695
- package/vendor/gugle-chat-bot/src/logger/index.ts +54 -54
- package/vendor/gugle-chat-bot/src/result.json +359 -359
- package/vendor/gugle-chat-bot/src/type/bili.d.ts +825 -825
- package/vendor/gugle-chat-bot/src/type/event.d.ts +146 -146
- package/vendor/gugle-chat-bot/src/type/github.d.ts +446 -446
- package/vendor/gugle-chat-bot/src/type/index.d.ts +254 -254
- package/vendor/gugle-chat-bot/tsconfig.json +46 -46
- package/scripts/dump-npm-latest.mjs +0 -30
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
import { Issue, IssueEvent, OpenedIssueEvent, ReopenedIssueEvent, User } from '@/type/github';
|
|
2
|
-
import { Logger } from 'winston';
|
|
3
|
-
import { Template, tryGenerateImage } from '@/image';
|
|
4
|
-
import dayjs from 'dayjs';
|
|
5
|
-
import { renderIssueBody } from '@/features/github/image';
|
|
6
|
-
|
|
7
|
-
function getRepositoryParts(repositoryUrl?: string, htmlUrl?: string): { owner: string; name: string } {
|
|
8
|
-
const url = repositoryUrl || htmlUrl;
|
|
9
|
-
if (!url) return { owner: 'GitHub', name: '' };
|
|
10
|
-
const parts = url.split('/').filter(Boolean);
|
|
11
|
-
const githubIndex = parts.indexOf('github.com');
|
|
12
|
-
const repositoryParts = githubIndex >= 0 ? parts.slice(githubIndex + 1, githubIndex + 3) : parts.slice(-2);
|
|
13
|
-
return repositoryParts.length === 2
|
|
14
|
-
? { owner: repositoryParts[0]!, name: repositoryParts[1]! }
|
|
15
|
-
: { owner: 'GitHub', name: '' };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function getIssueState(issue: Issue): string {
|
|
19
|
-
if (issue.state == 'open') {
|
|
20
|
-
return `
|
|
21
|
-
<div class="state_label" style="color:white; background-color: #347d39; box-shadow-color: #347d39;">
|
|
22
|
-
<div style="display: flex; align-items: center;">
|
|
23
|
-
<svg focusable="false" aria-label="Issue"
|
|
24
|
-
class="octicon octicon-issue-opened prc-StateLabel-Icon-YICrR" role="img" viewBox="0 0 16 16"
|
|
25
|
-
width="16" height="16" fill="currentColor" display="inline-block"
|
|
26
|
-
overflow="visible" style="margin-right:4px; vertical-align:text-bottom">
|
|
27
|
-
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"/>
|
|
28
|
-
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"/>
|
|
29
|
-
</svg>
|
|
30
|
-
Open
|
|
31
|
-
</div>
|
|
32
|
-
</div>\n
|
|
33
|
-
`;
|
|
34
|
-
} else {
|
|
35
|
-
if (issue.state_reason == 'completed') {
|
|
36
|
-
return `
|
|
37
|
-
<div class="state_label" style="color:white; background-color: #8256d0; box-shadow-color: #8256d0;">
|
|
38
|
-
<div style="display: flex; align-items: center;">
|
|
39
|
-
<svg focusable="false" aria-label="Issue" class="octicon octicon-issue-closed prc-StateLabel-Icon-YICrR"
|
|
40
|
-
role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block"
|
|
41
|
-
overflow="visible" style="margin-right:4px; vertical-align:text-bottom">
|
|
42
|
-
<path d="M11.28 6.78a.75.75 0 0 0-1.06-1.06L7.25 8.69 5.78 7.22a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.06 0l3.5-3.5Z"/>
|
|
43
|
-
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-1.5 0a6.5 6.5 0 1 0-13 0 6.5 6.5 0 0 0 13 0Z"></path>
|
|
44
|
-
</svg>
|
|
45
|
-
Closed
|
|
46
|
-
</div>
|
|
47
|
-
</div>\n
|
|
48
|
-
`;
|
|
49
|
-
} else {
|
|
50
|
-
return `
|
|
51
|
-
<div class="state_label" style="color:white; background-color: #656c76; box-shadow-color: #656c76;">
|
|
52
|
-
<div style="display: flex; align-items: center;">
|
|
53
|
-
<svg focusable="false" aria-label="Issue, not planned" class="octicon octicon-skip prc-StateLabel-Icon-YICrR"
|
|
54
|
-
role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block"
|
|
55
|
-
overflow="visible" style="margin-right:4px; vertical-align: text-bottom;">
|
|
56
|
-
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13
|
|
57
|
-
0Zm9.78-2.22-5.5 5.5a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l5.5-5.5a.751.751 0 0 1
|
|
58
|
-
1.042.018.751.751 0 0 1 .018 1.042Z"/>
|
|
59
|
-
</svg>
|
|
60
|
-
Closed
|
|
61
|
-
</div>
|
|
62
|
-
</div>\n
|
|
63
|
-
`;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function issuesHandler(issue: Issue, logger?: Logger, operation?: string, sender?: User, extra?: string) {
|
|
69
|
-
let labelsHtml = '';
|
|
70
|
-
for (let label of issue.labels) {
|
|
71
|
-
labelsHtml += `<div class="sidebar-label" style="color:#${label.color}ff; background-color: #${label.color}55; border:2px solid #${label.color}99">${label.name}</div>\n`;
|
|
72
|
-
}
|
|
73
|
-
let headerExtra: string | undefined = undefined;
|
|
74
|
-
if (sender) {
|
|
75
|
-
headerExtra = `<div class="message">用户<div class="user">${sender.login}</div>${operation}了 </div>`;
|
|
76
|
-
}
|
|
77
|
-
return new Promise<string>((resolve, reject) => {
|
|
78
|
-
const repository = getRepositoryParts(issue.repository_url, issue.html_url);
|
|
79
|
-
const repoFullName = `${repository.owner}/${repository.name}`;
|
|
80
|
-
renderIssueBody(issue.body, repoFullName, logger)
|
|
81
|
-
.then(bodyHtml => {
|
|
82
|
-
const template = Template.load('issue', 'src/features/github/template')
|
|
83
|
-
.arg('header extra', headerExtra || '')
|
|
84
|
-
.arg('repository owner', repository.owner)
|
|
85
|
-
.arg('repository name', repository.name)
|
|
86
|
-
.arg('issue number', issue.number)
|
|
87
|
-
.arg('state label', getIssueState(issue))
|
|
88
|
-
.arg('issue title', issue.title)
|
|
89
|
-
.arg('issue author', issue.user.login)
|
|
90
|
-
.arg('issue body', bodyHtml)
|
|
91
|
-
.arg('issue created at', dayjs(issue.created_at).format('YYYY-MM-DD HH:mm:ss'))
|
|
92
|
-
.arg('issue labels', labelsHtml || 'No labels')
|
|
93
|
-
.arg('extra', extra || '');
|
|
94
|
-
const templateFile = template.file();
|
|
95
|
-
template
|
|
96
|
-
.handler()
|
|
97
|
-
.then(issue => {
|
|
98
|
-
logger?.debug(`Start process issue message...`);
|
|
99
|
-
tryGenerateImage(resolve, reject, issue, 820, templateFile);
|
|
100
|
-
})
|
|
101
|
-
.catch(reject);
|
|
102
|
-
})
|
|
103
|
-
.catch(reject);
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function issuesClosed(issue: IssueEvent, logger?: Logger): Promise<string> {
|
|
108
|
-
let extra: string | undefined;
|
|
109
|
-
if (issue.issue.state_reason) {
|
|
110
|
-
extra = "<div class='h1'>关闭原因:</div>\n";
|
|
111
|
-
}
|
|
112
|
-
if (issue.issue.state_reason == 'completed') {
|
|
113
|
-
extra += "<div class='body'>已完成</div>\n";
|
|
114
|
-
} else if (issue.issue.state_reason == 'not_planned') {
|
|
115
|
-
extra += "<div class='body'>未计划</div>\n";
|
|
116
|
-
} else if (issue.issue.state_reason == 'duplicate') {
|
|
117
|
-
extra += "<div class='body'>重复</div>\n";
|
|
118
|
-
} else {
|
|
119
|
-
extra += `<div class='body'>${issue.issue.state_reason}</div>\n`;
|
|
120
|
-
}
|
|
121
|
-
return issuesHandler(issue.issue, logger, '关闭', issue.sender, extra);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function issuesOpened(issue: OpenedIssueEvent | ReopenedIssueEvent, logger?: Logger): Promise<string> {
|
|
125
|
-
let operation: string;
|
|
126
|
-
if (issue.action == 'reopened') {
|
|
127
|
-
operation = '重新打开';
|
|
128
|
-
} else {
|
|
129
|
-
operation = '提交';
|
|
130
|
-
}
|
|
131
|
-
return issuesHandler(issue.issue, logger, operation, issue.sender);
|
|
132
|
-
}
|
|
1
|
+
import { Issue, IssueEvent, OpenedIssueEvent, ReopenedIssueEvent, User } from '@/type/github';
|
|
2
|
+
import { Logger } from 'winston';
|
|
3
|
+
import { Template, tryGenerateImage } from '@/image';
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
import { renderIssueBody } from '@/features/github/image';
|
|
6
|
+
|
|
7
|
+
function getRepositoryParts(repositoryUrl?: string, htmlUrl?: string): { owner: string; name: string } {
|
|
8
|
+
const url = repositoryUrl || htmlUrl;
|
|
9
|
+
if (!url) return { owner: 'GitHub', name: '' };
|
|
10
|
+
const parts = url.split('/').filter(Boolean);
|
|
11
|
+
const githubIndex = parts.indexOf('github.com');
|
|
12
|
+
const repositoryParts = githubIndex >= 0 ? parts.slice(githubIndex + 1, githubIndex + 3) : parts.slice(-2);
|
|
13
|
+
return repositoryParts.length === 2
|
|
14
|
+
? { owner: repositoryParts[0]!, name: repositoryParts[1]! }
|
|
15
|
+
: { owner: 'GitHub', name: '' };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getIssueState(issue: Issue): string {
|
|
19
|
+
if (issue.state == 'open') {
|
|
20
|
+
return `
|
|
21
|
+
<div class="state_label" style="color:white; background-color: #347d39; box-shadow-color: #347d39;">
|
|
22
|
+
<div style="display: flex; align-items: center;">
|
|
23
|
+
<svg focusable="false" aria-label="Issue"
|
|
24
|
+
class="octicon octicon-issue-opened prc-StateLabel-Icon-YICrR" role="img" viewBox="0 0 16 16"
|
|
25
|
+
width="16" height="16" fill="currentColor" display="inline-block"
|
|
26
|
+
overflow="visible" style="margin-right:4px; vertical-align:text-bottom">
|
|
27
|
+
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"/>
|
|
28
|
+
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"/>
|
|
29
|
+
</svg>
|
|
30
|
+
Open
|
|
31
|
+
</div>
|
|
32
|
+
</div>\n
|
|
33
|
+
`;
|
|
34
|
+
} else {
|
|
35
|
+
if (issue.state_reason == 'completed') {
|
|
36
|
+
return `
|
|
37
|
+
<div class="state_label" style="color:white; background-color: #8256d0; box-shadow-color: #8256d0;">
|
|
38
|
+
<div style="display: flex; align-items: center;">
|
|
39
|
+
<svg focusable="false" aria-label="Issue" class="octicon octicon-issue-closed prc-StateLabel-Icon-YICrR"
|
|
40
|
+
role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block"
|
|
41
|
+
overflow="visible" style="margin-right:4px; vertical-align:text-bottom">
|
|
42
|
+
<path d="M11.28 6.78a.75.75 0 0 0-1.06-1.06L7.25 8.69 5.78 7.22a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.06 0l3.5-3.5Z"/>
|
|
43
|
+
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-1.5 0a6.5 6.5 0 1 0-13 0 6.5 6.5 0 0 0 13 0Z"></path>
|
|
44
|
+
</svg>
|
|
45
|
+
Closed
|
|
46
|
+
</div>
|
|
47
|
+
</div>\n
|
|
48
|
+
`;
|
|
49
|
+
} else {
|
|
50
|
+
return `
|
|
51
|
+
<div class="state_label" style="color:white; background-color: #656c76; box-shadow-color: #656c76;">
|
|
52
|
+
<div style="display: flex; align-items: center;">
|
|
53
|
+
<svg focusable="false" aria-label="Issue, not planned" class="octicon octicon-skip prc-StateLabel-Icon-YICrR"
|
|
54
|
+
role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block"
|
|
55
|
+
overflow="visible" style="margin-right:4px; vertical-align: text-bottom;">
|
|
56
|
+
<path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13
|
|
57
|
+
0Zm9.78-2.22-5.5 5.5a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l5.5-5.5a.751.751 0 0 1
|
|
58
|
+
1.042.018.751.751 0 0 1 .018 1.042Z"/>
|
|
59
|
+
</svg>
|
|
60
|
+
Closed
|
|
61
|
+
</div>
|
|
62
|
+
</div>\n
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function issuesHandler(issue: Issue, logger?: Logger, operation?: string, sender?: User, extra?: string) {
|
|
69
|
+
let labelsHtml = '';
|
|
70
|
+
for (let label of issue.labels) {
|
|
71
|
+
labelsHtml += `<div class="sidebar-label" style="color:#${label.color}ff; background-color: #${label.color}55; border:2px solid #${label.color}99">${label.name}</div>\n`;
|
|
72
|
+
}
|
|
73
|
+
let headerExtra: string | undefined = undefined;
|
|
74
|
+
if (sender) {
|
|
75
|
+
headerExtra = `<div class="message">用户<div class="user">${sender.login}</div>${operation}了 </div>`;
|
|
76
|
+
}
|
|
77
|
+
return new Promise<string>((resolve, reject) => {
|
|
78
|
+
const repository = getRepositoryParts(issue.repository_url, issue.html_url);
|
|
79
|
+
const repoFullName = `${repository.owner}/${repository.name}`;
|
|
80
|
+
renderIssueBody(issue.body, repoFullName, logger)
|
|
81
|
+
.then(bodyHtml => {
|
|
82
|
+
const template = Template.load('issue', 'src/features/github/template')
|
|
83
|
+
.arg('header extra', headerExtra || '')
|
|
84
|
+
.arg('repository owner', repository.owner)
|
|
85
|
+
.arg('repository name', repository.name)
|
|
86
|
+
.arg('issue number', issue.number)
|
|
87
|
+
.arg('state label', getIssueState(issue))
|
|
88
|
+
.arg('issue title', issue.title)
|
|
89
|
+
.arg('issue author', issue.user.login)
|
|
90
|
+
.arg('issue body', bodyHtml)
|
|
91
|
+
.arg('issue created at', dayjs(issue.created_at).format('YYYY-MM-DD HH:mm:ss'))
|
|
92
|
+
.arg('issue labels', labelsHtml || 'No labels')
|
|
93
|
+
.arg('extra', extra || '');
|
|
94
|
+
const templateFile = template.file();
|
|
95
|
+
template
|
|
96
|
+
.handler()
|
|
97
|
+
.then(issue => {
|
|
98
|
+
logger?.debug(`Start process issue message...`);
|
|
99
|
+
tryGenerateImage(resolve, reject, issue, 820, templateFile);
|
|
100
|
+
})
|
|
101
|
+
.catch(reject);
|
|
102
|
+
})
|
|
103
|
+
.catch(reject);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function issuesClosed(issue: IssueEvent, logger?: Logger): Promise<string> {
|
|
108
|
+
let extra: string | undefined;
|
|
109
|
+
if (issue.issue.state_reason) {
|
|
110
|
+
extra = "<div class='h1'>关闭原因:</div>\n";
|
|
111
|
+
}
|
|
112
|
+
if (issue.issue.state_reason == 'completed') {
|
|
113
|
+
extra += "<div class='body'>已完成</div>\n";
|
|
114
|
+
} else if (issue.issue.state_reason == 'not_planned') {
|
|
115
|
+
extra += "<div class='body'>未计划</div>\n";
|
|
116
|
+
} else if (issue.issue.state_reason == 'duplicate') {
|
|
117
|
+
extra += "<div class='body'>重复</div>\n";
|
|
118
|
+
} else {
|
|
119
|
+
extra += `<div class='body'>${issue.issue.state_reason}</div>\n`;
|
|
120
|
+
}
|
|
121
|
+
return issuesHandler(issue.issue, logger, '关闭', issue.sender, extra);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function issuesOpened(issue: OpenedIssueEvent | ReopenedIssueEvent, logger?: Logger): Promise<string> {
|
|
125
|
+
let operation: string;
|
|
126
|
+
if (issue.action == 'reopened') {
|
|
127
|
+
operation = '重新打开';
|
|
128
|
+
} else {
|
|
129
|
+
operation = '提交';
|
|
130
|
+
}
|
|
131
|
+
return issuesHandler(issue.issue, logger, operation, issue.sender);
|
|
132
|
+
}
|
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
import { OpenedPullRequestEvent, PullRequest, PullRequestEvent, ReopenedPullRequestEvent, User } from '@/type/github';
|
|
2
|
-
import { Logger } from 'winston';
|
|
3
|
-
import { Template, tryGenerateImage } from '@/image';
|
|
4
|
-
import { renderIssueBody } from '@/features/github/image';
|
|
5
|
-
import dayjs from 'dayjs';
|
|
6
|
-
|
|
7
|
-
function getRepositoryParts(repositoryUrl?: string, htmlUrl?: string): { owner: string; name: string } {
|
|
8
|
-
const url = repositoryUrl || htmlUrl;
|
|
9
|
-
if (!url) return { owner: 'GitHub', name: '' };
|
|
10
|
-
const parts = url.split('/').filter(Boolean);
|
|
11
|
-
const githubIndex = parts.indexOf('github.com');
|
|
12
|
-
const repositoryParts = githubIndex >= 0 ? parts.slice(githubIndex + 1, githubIndex + 3) : parts.slice(-2);
|
|
13
|
-
return repositoryParts.length === 2
|
|
14
|
-
? { owner: repositoryParts[0]!, name: repositoryParts[1]! }
|
|
15
|
-
: { owner: 'GitHub', name: '' };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function getPullRequestState(pr: PullRequest): string {
|
|
19
|
-
if (pr.state == 'open') {
|
|
20
|
-
if (pr.draft) {
|
|
21
|
-
return `
|
|
22
|
-
<div class="state_label" style="color:white; background-color: #656c76; box-shadow-color: #656c76;">
|
|
23
|
-
<div style="display: flex; align-items: center;">
|
|
24
|
-
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
25
|
-
<path d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251
|
|
26
|
-
0 0 1 3.25 1Zm9.5 14a2.25 2.25 0 1 1 0-4.5 2.25 2.25 0 0 1 0 4.5ZM2.5 3.25a.75.75 0 1 0 1.5 0
|
|
27
|
-
.75.75 0 0 0-1.5 0ZM3.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm9.5 0a.75.75 0 1 0 0 1.5.75.75
|
|
28
|
-
0 0 0 0-1.5ZM14 7.5a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm0-4.25a1.25 1.25 0 1 1-2.5 0
|
|
29
|
-
1.25 1.25 0 0 1 2.5 0Z"/>
|
|
30
|
-
</svg>
|
|
31
|
-
Draft
|
|
32
|
-
</div>
|
|
33
|
-
</div>\n
|
|
34
|
-
`;
|
|
35
|
-
} else {
|
|
36
|
-
return `
|
|
37
|
-
<div class="state_label" style="color:white; background-color: #347d39; box-shadow-color: #347d39;">
|
|
38
|
-
<div style="display: flex; align-items: center;">
|
|
39
|
-
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
40
|
-
<path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25
|
|
41
|
-
0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251
|
|
42
|
-
2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1
|
|
43
|
-
0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0
|
|
44
|
-
0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"/>
|
|
45
|
-
</svg>
|
|
46
|
-
Open
|
|
47
|
-
</div>
|
|
48
|
-
</div>\n
|
|
49
|
-
`;
|
|
50
|
-
}
|
|
51
|
-
} else {
|
|
52
|
-
if (pr.merged) {
|
|
53
|
-
return `
|
|
54
|
-
<div class="state_label" style="color:white; background-color: #8256d0; box-shadow-color: #8256d0;">
|
|
55
|
-
<div style="display: flex; align-items: center;">
|
|
56
|
-
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
57
|
-
<path d="M5.45 5.154A4.25 4.25 0 0 0 9.25 7.5h1.378a2.251 2.251 0 1 1 0 1.5H9.25A5.734 5.734
|
|
58
|
-
0 0 1 5 7.123v3.505a2.25 2.25 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.95-.218ZM4.25 13.5a.75.75
|
|
59
|
-
0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm8.5-4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5ZM5 3.25a.75.75
|
|
60
|
-
0 1 0 0 .005V3.25Z"/>
|
|
61
|
-
</svg>
|
|
62
|
-
Merged
|
|
63
|
-
</div>
|
|
64
|
-
</div>\n
|
|
65
|
-
`;
|
|
66
|
-
} else {
|
|
67
|
-
return `
|
|
68
|
-
<div class="state_label" style="color:white; background-color: #c93c37; box-shadow-color: #c93c37;">
|
|
69
|
-
<div style="display: flex; align-items: center;">
|
|
70
|
-
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
71
|
-
<path d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251
|
|
72
|
-
0 0 1 3.25 1Zm9.5 5.5a.75.75 0 0 1 .75.75v3.378a2.251 2.251 0 1 1-1.5 0V7.25a.75.75
|
|
73
|
-
0 0 1 .75-.75Zm-2.03-5.273a.75.75 0 0 1 1.06 0l.97.97.97-.97a.748.748 0 0 1 1.265.332.75.75
|
|
74
|
-
0 0 1-.205.729l-.97.97.97.97a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-.97-.97-.97.97a.749.749
|
|
75
|
-
0 0 1-1.275-.326.749.749 0 0 1 .215-.734l.97-.97-.97-.97a.75.75 0 0 1 0-1.06ZM2.5 3.25a.75.75
|
|
76
|
-
0 1 0 1.5 0 .75.75 0 0 0-1.5 0ZM3.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm9.5 0a.75.75 0 1
|
|
77
|
-
0 0 1.5.75.75 0 0 0 0-1.5Z"/>
|
|
78
|
-
</svg>
|
|
79
|
-
Closed
|
|
80
|
-
</div>
|
|
81
|
-
</div>\n
|
|
82
|
-
`;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function prHandler(pr: PullRequest, logger?: Logger, operation?: string, sender?: User, extra?: string) {
|
|
88
|
-
let labelsHtml = '';
|
|
89
|
-
for (let label of pr.labels) {
|
|
90
|
-
labelsHtml += `<div class="sidebar-label" style="color:#${label.color}ff; background-color: #${label.color}55; border:2px solid #${label.color}99">${label.name}</div>\n`;
|
|
91
|
-
}
|
|
92
|
-
let headerExtra: string | undefined = undefined;
|
|
93
|
-
if (sender) {
|
|
94
|
-
headerExtra = `<div class="message">用户<div class="user">${sender.login}</div>${operation}了 </div>`;
|
|
95
|
-
}
|
|
96
|
-
return new Promise<string>((resolve, reject) => {
|
|
97
|
-
const repository = getRepositoryParts(pr.repository_url, pr.html_url);
|
|
98
|
-
const repoFullName = `${repository.owner}/${repository.name}`;
|
|
99
|
-
renderIssueBody(pr.body, repoFullName, logger)
|
|
100
|
-
.then(bodyHtml => {
|
|
101
|
-
const template = Template.load('pull_request', 'src/features/github/template')
|
|
102
|
-
.arg('header extra', headerExtra || '')
|
|
103
|
-
.arg('repository owner', repository.owner)
|
|
104
|
-
.arg('repository name', repository.name)
|
|
105
|
-
.arg('pr number', pr.number)
|
|
106
|
-
.arg('pr title', pr.title)
|
|
107
|
-
.arg('pr body', bodyHtml)
|
|
108
|
-
.arg('pr labels', labelsHtml || 'No labels')
|
|
109
|
-
.arg('pr author', pr.user.login)
|
|
110
|
-
.arg('pr created at', dayjs(pr.created_at).format('YYYY-MM-DD HH:mm:ss'))
|
|
111
|
-
.arg('state label', getPullRequestState(pr))
|
|
112
|
-
.arg('extra', extra || '');
|
|
113
|
-
const templateFile = template.file();
|
|
114
|
-
template
|
|
115
|
-
.handler()
|
|
116
|
-
.then(pr => {
|
|
117
|
-
logger?.debug(`Start process pull request message...`);
|
|
118
|
-
tryGenerateImage(resolve, reject, pr, 820, templateFile);
|
|
119
|
-
})
|
|
120
|
-
.catch(reject);
|
|
121
|
-
})
|
|
122
|
-
.catch(reject);
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function prClosed(pr: PullRequestEvent, logger?: Logger): Promise<string> {
|
|
127
|
-
let operation: string;
|
|
128
|
-
if (pr.pull_request.merged) {
|
|
129
|
-
operation = '合并';
|
|
130
|
-
} else {
|
|
131
|
-
operation = '关闭';
|
|
132
|
-
}
|
|
133
|
-
return prHandler(pr.pull_request, logger, operation, pr.sender);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function prOpened(pr: OpenedPullRequestEvent | ReopenedPullRequestEvent, logger?: Logger): Promise<string> {
|
|
137
|
-
let operation: string;
|
|
138
|
-
if (pr.action == 'reopened') {
|
|
139
|
-
operation = '重新打开';
|
|
140
|
-
} else {
|
|
141
|
-
operation = '提交';
|
|
142
|
-
}
|
|
143
|
-
return prHandler(pr.pull_request, logger, operation, pr.sender);
|
|
144
|
-
}
|
|
1
|
+
import { OpenedPullRequestEvent, PullRequest, PullRequestEvent, ReopenedPullRequestEvent, User } from '@/type/github';
|
|
2
|
+
import { Logger } from 'winston';
|
|
3
|
+
import { Template, tryGenerateImage } from '@/image';
|
|
4
|
+
import { renderIssueBody } from '@/features/github/image';
|
|
5
|
+
import dayjs from 'dayjs';
|
|
6
|
+
|
|
7
|
+
function getRepositoryParts(repositoryUrl?: string, htmlUrl?: string): { owner: string; name: string } {
|
|
8
|
+
const url = repositoryUrl || htmlUrl;
|
|
9
|
+
if (!url) return { owner: 'GitHub', name: '' };
|
|
10
|
+
const parts = url.split('/').filter(Boolean);
|
|
11
|
+
const githubIndex = parts.indexOf('github.com');
|
|
12
|
+
const repositoryParts = githubIndex >= 0 ? parts.slice(githubIndex + 1, githubIndex + 3) : parts.slice(-2);
|
|
13
|
+
return repositoryParts.length === 2
|
|
14
|
+
? { owner: repositoryParts[0]!, name: repositoryParts[1]! }
|
|
15
|
+
: { owner: 'GitHub', name: '' };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getPullRequestState(pr: PullRequest): string {
|
|
19
|
+
if (pr.state == 'open') {
|
|
20
|
+
if (pr.draft) {
|
|
21
|
+
return `
|
|
22
|
+
<div class="state_label" style="color:white; background-color: #656c76; box-shadow-color: #656c76;">
|
|
23
|
+
<div style="display: flex; align-items: center;">
|
|
24
|
+
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
25
|
+
<path d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251
|
|
26
|
+
0 0 1 3.25 1Zm9.5 14a2.25 2.25 0 1 1 0-4.5 2.25 2.25 0 0 1 0 4.5ZM2.5 3.25a.75.75 0 1 0 1.5 0
|
|
27
|
+
.75.75 0 0 0-1.5 0ZM3.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm9.5 0a.75.75 0 1 0 0 1.5.75.75
|
|
28
|
+
0 0 0 0-1.5ZM14 7.5a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm0-4.25a1.25 1.25 0 1 1-2.5 0
|
|
29
|
+
1.25 1.25 0 0 1 2.5 0Z"/>
|
|
30
|
+
</svg>
|
|
31
|
+
Draft
|
|
32
|
+
</div>
|
|
33
|
+
</div>\n
|
|
34
|
+
`;
|
|
35
|
+
} else {
|
|
36
|
+
return `
|
|
37
|
+
<div class="state_label" style="color:white; background-color: #347d39; box-shadow-color: #347d39;">
|
|
38
|
+
<div style="display: flex; align-items: center;">
|
|
39
|
+
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
40
|
+
<path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25
|
|
41
|
+
0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251
|
|
42
|
+
2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1
|
|
43
|
+
0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0
|
|
44
|
+
0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"/>
|
|
45
|
+
</svg>
|
|
46
|
+
Open
|
|
47
|
+
</div>
|
|
48
|
+
</div>\n
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
if (pr.merged) {
|
|
53
|
+
return `
|
|
54
|
+
<div class="state_label" style="color:white; background-color: #8256d0; box-shadow-color: #8256d0;">
|
|
55
|
+
<div style="display: flex; align-items: center;">
|
|
56
|
+
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
57
|
+
<path d="M5.45 5.154A4.25 4.25 0 0 0 9.25 7.5h1.378a2.251 2.251 0 1 1 0 1.5H9.25A5.734 5.734
|
|
58
|
+
0 0 1 5 7.123v3.505a2.25 2.25 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.95-.218ZM4.25 13.5a.75.75
|
|
59
|
+
0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm8.5-4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5ZM5 3.25a.75.75
|
|
60
|
+
0 1 0 0 .005V3.25Z"/>
|
|
61
|
+
</svg>
|
|
62
|
+
Merged
|
|
63
|
+
</div>
|
|
64
|
+
</div>\n
|
|
65
|
+
`;
|
|
66
|
+
} else {
|
|
67
|
+
return `
|
|
68
|
+
<div class="state_label" style="color:white; background-color: #c93c37; box-shadow-color: #c93c37;">
|
|
69
|
+
<div style="display: flex; align-items: center;">
|
|
70
|
+
<svg class="octicon" focusable="false" height="16" fill="currentColor" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true">
|
|
71
|
+
<path d="M3.25 1A2.25 2.25 0 0 1 4 5.372v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.251 2.251
|
|
72
|
+
0 0 1 3.25 1Zm9.5 5.5a.75.75 0 0 1 .75.75v3.378a2.251 2.251 0 1 1-1.5 0V7.25a.75.75
|
|
73
|
+
0 0 1 .75-.75Zm-2.03-5.273a.75.75 0 0 1 1.06 0l.97.97.97-.97a.748.748 0 0 1 1.265.332.75.75
|
|
74
|
+
0 0 1-.205.729l-.97.97.97.97a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-.97-.97-.97.97a.749.749
|
|
75
|
+
0 0 1-1.275-.326.749.749 0 0 1 .215-.734l.97-.97-.97-.97a.75.75 0 0 1 0-1.06ZM2.5 3.25a.75.75
|
|
76
|
+
0 1 0 1.5 0 .75.75 0 0 0-1.5 0ZM3.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm9.5 0a.75.75 0 1
|
|
77
|
+
0 0 1.5.75.75 0 0 0 0-1.5Z"/>
|
|
78
|
+
</svg>
|
|
79
|
+
Closed
|
|
80
|
+
</div>
|
|
81
|
+
</div>\n
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function prHandler(pr: PullRequest, logger?: Logger, operation?: string, sender?: User, extra?: string) {
|
|
88
|
+
let labelsHtml = '';
|
|
89
|
+
for (let label of pr.labels) {
|
|
90
|
+
labelsHtml += `<div class="sidebar-label" style="color:#${label.color}ff; background-color: #${label.color}55; border:2px solid #${label.color}99">${label.name}</div>\n`;
|
|
91
|
+
}
|
|
92
|
+
let headerExtra: string | undefined = undefined;
|
|
93
|
+
if (sender) {
|
|
94
|
+
headerExtra = `<div class="message">用户<div class="user">${sender.login}</div>${operation}了 </div>`;
|
|
95
|
+
}
|
|
96
|
+
return new Promise<string>((resolve, reject) => {
|
|
97
|
+
const repository = getRepositoryParts(pr.repository_url, pr.html_url);
|
|
98
|
+
const repoFullName = `${repository.owner}/${repository.name}`;
|
|
99
|
+
renderIssueBody(pr.body, repoFullName, logger)
|
|
100
|
+
.then(bodyHtml => {
|
|
101
|
+
const template = Template.load('pull_request', 'src/features/github/template')
|
|
102
|
+
.arg('header extra', headerExtra || '')
|
|
103
|
+
.arg('repository owner', repository.owner)
|
|
104
|
+
.arg('repository name', repository.name)
|
|
105
|
+
.arg('pr number', pr.number)
|
|
106
|
+
.arg('pr title', pr.title)
|
|
107
|
+
.arg('pr body', bodyHtml)
|
|
108
|
+
.arg('pr labels', labelsHtml || 'No labels')
|
|
109
|
+
.arg('pr author', pr.user.login)
|
|
110
|
+
.arg('pr created at', dayjs(pr.created_at).format('YYYY-MM-DD HH:mm:ss'))
|
|
111
|
+
.arg('state label', getPullRequestState(pr))
|
|
112
|
+
.arg('extra', extra || '');
|
|
113
|
+
const templateFile = template.file();
|
|
114
|
+
template
|
|
115
|
+
.handler()
|
|
116
|
+
.then(pr => {
|
|
117
|
+
logger?.debug(`Start process pull request message...`);
|
|
118
|
+
tryGenerateImage(resolve, reject, pr, 820, templateFile);
|
|
119
|
+
})
|
|
120
|
+
.catch(reject);
|
|
121
|
+
})
|
|
122
|
+
.catch(reject);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function prClosed(pr: PullRequestEvent, logger?: Logger): Promise<string> {
|
|
127
|
+
let operation: string;
|
|
128
|
+
if (pr.pull_request.merged) {
|
|
129
|
+
operation = '合并';
|
|
130
|
+
} else {
|
|
131
|
+
operation = '关闭';
|
|
132
|
+
}
|
|
133
|
+
return prHandler(pr.pull_request, logger, operation, pr.sender);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function prOpened(pr: OpenedPullRequestEvent | ReopenedPullRequestEvent, logger?: Logger): Promise<string> {
|
|
137
|
+
let operation: string;
|
|
138
|
+
if (pr.action == 'reopened') {
|
|
139
|
+
operation = '重新打开';
|
|
140
|
+
} else {
|
|
141
|
+
operation = '提交';
|
|
142
|
+
}
|
|
143
|
+
return prHandler(pr.pull_request, logger, operation, pr.sender);
|
|
144
|
+
}
|