✨ feat(vscode): 支持讨论评论引用与 macOS 系统级新评论桌面提醒
This commit is contained in:
1 parent
540c212bad
commit
a2c3c1f919
13 files changed
+638
-302
No files matched your search
@@ -0,0 +1,177 @@
|
||||
export interface PrWebhookEvent {
|
||||
kind: 'pr'
|
||||
issueNumber: number | undefined
|
||||
action: string
|
||||
pr: string
|
||||
branch: string
|
||||
htmlUrl: string
|
||||
title: string
|
||||
body: string
|
||||
raw: unknown
|
||||
}
|
||||
|
||||
export interface IssueWebhookEvent {
|
||||
kind: 'issue'
|
||||
action: string
|
||||
issueNumber: number
|
||||
title: string
|
||||
body: string
|
||||
htmlUrl: string
|
||||
raw: unknown
|
||||
}
|
||||
|
||||
export interface IssueCommentWebhookEvent {
|
||||
kind: 'issue_comment'
|
||||
action: string
|
||||
issueNumber: number
|
||||
prNumber: number | undefined
|
||||
commentBody: string
|
||||
commentAuthor: string
|
||||
commentHtmlUrl: string
|
||||
raw: unknown
|
||||
}
|
||||
|
||||
export interface PushWebhookEvent {
|
||||
kind: 'push'
|
||||
branch: string
|
||||
raw: unknown
|
||||
}
|
||||
|
||||
export type WebhookEvent = PrWebhookEvent | IssueWebhookEvent | IssueCommentWebhookEvent | PushWebhookEvent
|
||||
|
||||
export function parseEvent(
|
||||
eventHeader: string,
|
||||
issueNumber: number | undefined,
|
||||
raw: unknown,
|
||||
): WebhookEvent | null {
|
||||
if (!raw || typeof raw !== 'object')
|
||||
return null
|
||||
const obj = raw as {
|
||||
action?: unknown
|
||||
pull_request?: unknown
|
||||
issue?: unknown
|
||||
comment?: unknown
|
||||
ref?: unknown
|
||||
sender?: unknown
|
||||
}
|
||||
|
||||
if (eventHeader === 'push') {
|
||||
// gitea push 事件无 `action`,顶层带 `ref: "refs/heads/<branch>"`。
|
||||
if (typeof obj.ref !== 'string')
|
||||
return null
|
||||
const branch = obj.ref.replace(/^refs\/heads\//, '')
|
||||
if (!branch)
|
||||
return null
|
||||
return { kind: 'push', branch, raw }
|
||||
}
|
||||
|
||||
if (typeof obj.action !== 'string')
|
||||
return null
|
||||
|
||||
if (eventHeader === 'issue_comment') {
|
||||
const issue = obj.issue
|
||||
const comment = obj.comment
|
||||
if (!issue || typeof issue !== 'object')
|
||||
return null
|
||||
if (!comment || typeof comment !== 'object')
|
||||
return null
|
||||
const issueObj = issue as {
|
||||
number?: unknown
|
||||
pull_request?: unknown
|
||||
}
|
||||
const commentObj = comment as {
|
||||
body?: unknown
|
||||
html_url?: unknown
|
||||
user?: unknown
|
||||
}
|
||||
const num = typeof issueObj.number === 'number' ? issueObj.number : Number(issueObj.number)
|
||||
if (!Number.isFinite(num))
|
||||
return null
|
||||
// gitea sets issue.pull_request (non-null object) when the issue is a PR.
|
||||
const prNumber = issueObj.pull_request && typeof issueObj.pull_request === 'object'
|
||||
? num
|
||||
: undefined
|
||||
const commentBody = typeof commentObj.body === 'string' ? commentObj.body : ''
|
||||
const commentHtmlUrl = typeof commentObj.html_url === 'string' ? commentObj.html_url : ''
|
||||
const commentUser = commentObj.user as { login?: unknown, username?: unknown } | undefined
|
||||
const sender = obj.sender as { login?: unknown, username?: unknown } | undefined
|
||||
const commentAuthor = (typeof commentUser?.login === 'string' && commentUser.login)
|
||||
|| (typeof commentUser?.username === 'string' && commentUser.username)
|
||||
|| (typeof sender?.login === 'string' && sender.login)
|
||||
|| (typeof sender?.username === 'string' && sender.username)
|
||||
|| ''
|
||||
return {
|
||||
kind: 'issue_comment',
|
||||
action: obj.action,
|
||||
issueNumber: num,
|
||||
prNumber,
|
||||
commentAuthor,
|
||||
commentBody,
|
||||
commentHtmlUrl,
|
||||
raw,
|
||||
}
|
||||
}
|
||||
|
||||
if (eventHeader === 'issues') {
|
||||
const issue = obj.issue
|
||||
if (!issue || typeof issue !== 'object')
|
||||
return null
|
||||
const issueObj = issue as {
|
||||
number?: unknown
|
||||
html_url?: unknown
|
||||
title?: unknown
|
||||
body?: unknown
|
||||
}
|
||||
const num = typeof issueObj.number === 'number' ? issueObj.number : Number(issueObj.number)
|
||||
if (!Number.isFinite(num))
|
||||
return null
|
||||
const htmlUrl = typeof issueObj.html_url === 'string' ? issueObj.html_url : ''
|
||||
const title = typeof issueObj.title === 'string' ? issueObj.title : ''
|
||||
const body = typeof issueObj.body === 'string' ? issueObj.body : ''
|
||||
return {
|
||||
kind: 'issue',
|
||||
action: obj.action,
|
||||
issueNumber: num,
|
||||
title,
|
||||
body,
|
||||
htmlUrl,
|
||||
raw,
|
||||
}
|
||||
}
|
||||
|
||||
// Default path: pull_request payload (preserves legacy behaviour for any
|
||||
// event header value, since gitea historically may not set the header).
|
||||
const pr = obj.pull_request
|
||||
if (!pr || typeof pr !== 'object')
|
||||
return null
|
||||
const prObj = pr as {
|
||||
number?: unknown
|
||||
html_url?: unknown
|
||||
head?: unknown
|
||||
title?: unknown
|
||||
body?: unknown
|
||||
}
|
||||
const num = typeof prObj.number === 'number' ? prObj.number : Number(prObj.number)
|
||||
if (!Number.isFinite(num))
|
||||
return null
|
||||
const htmlUrl = typeof prObj.html_url === 'string' ? prObj.html_url : ''
|
||||
const head = prObj.head as { ref?: unknown } | undefined
|
||||
const branch = head && typeof head.ref === 'string' ? head.ref : ''
|
||||
const title = typeof prObj.title === 'string' ? prObj.title : ''
|
||||
const body = typeof prObj.body === 'string' ? prObj.body : ''
|
||||
|
||||
if (!branch || !htmlUrl)
|
||||
return null
|
||||
|
||||
return {
|
||||
kind: 'pr',
|
||||
issueNumber,
|
||||
action: obj.action,
|
||||
pr: String(num),
|
||||
branch,
|
||||
htmlUrl,
|
||||
title,
|
||||
body,
|
||||
raw,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user