550 lines
17 KiB
TypeScript
550 lines
17 KiB
TypeScript
/* eslint-disable max-lines -- Why: GitHub runtime RPC keeps related repo, project, and mutation schemas beside their handlers so the method contract stays reviewable in one place. */
|
|
import { z } from 'zod'
|
|
import { defineMethod, type RpcMethod } from '../core'
|
|
import { OptionalFiniteNumber, OptionalString, requiredString } from '../schemas'
|
|
|
|
const RepoSelector = z.object({
|
|
repo: requiredString('Missing repo selector')
|
|
})
|
|
|
|
const WorkItemsList = RepoSelector.extend({
|
|
limit: OptionalFiniteNumber,
|
|
query: OptionalString,
|
|
before: OptionalString
|
|
})
|
|
|
|
const WorkItem = RepoSelector.extend({
|
|
number: z.number().int().positive(),
|
|
type: z.enum(['issue', 'pr']).optional()
|
|
})
|
|
|
|
const WorkItemByOwnerRepo = RepoSelector.extend({
|
|
owner: requiredString('Missing owner'),
|
|
ownerRepo: requiredString('Missing repo'),
|
|
number: z.number().int().positive(),
|
|
type: z.enum(['issue', 'pr'])
|
|
})
|
|
|
|
const WorkItemDetails = WorkItem
|
|
|
|
const WorkItemsCount = RepoSelector.extend({
|
|
query: OptionalString
|
|
})
|
|
|
|
const RateLimit = z.object({
|
|
force: z.boolean().optional()
|
|
})
|
|
|
|
const SlugRepo = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
repo: requiredString('Missing repo')
|
|
})
|
|
|
|
const SlugAssignableUsers = SlugRepo.extend({
|
|
seedLogins: z.array(z.string()).optional()
|
|
})
|
|
|
|
const PrForBranch = RepoSelector.extend({
|
|
branch: requiredString('Missing branch'),
|
|
linkedPRNumber: z.number().int().positive().nullable().optional(),
|
|
fallbackPRNumber: z.number().int().positive().nullable().optional()
|
|
})
|
|
|
|
const Issue = RepoSelector.extend({
|
|
number: z.number().int().positive()
|
|
})
|
|
|
|
const PullRequest = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
noCache: z.boolean().optional(),
|
|
prRepo: SlugRepo.nullable().optional()
|
|
})
|
|
|
|
const PullRequestChecks = PullRequest.extend({
|
|
headSha: OptionalString
|
|
})
|
|
|
|
const PullRequestCheckDetails = RepoSelector.extend({
|
|
checkRunId: z.number().int().positive().optional(),
|
|
workflowRunId: z.number().int().positive().optional(),
|
|
checkName: OptionalString,
|
|
url: OptionalString.nullable().optional(),
|
|
prRepo: SlugRepo.nullable().optional()
|
|
})
|
|
|
|
const RerunPullRequestChecks = PullRequest.extend({
|
|
headSha: OptionalString,
|
|
failedOnly: z.boolean().optional()
|
|
})
|
|
|
|
const PullRequestFileContents = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
path: requiredString('Missing file path'),
|
|
oldPath: OptionalString,
|
|
status: z.enum(['added', 'removed', 'modified', 'renamed', 'copied', 'changed', 'unchanged']),
|
|
headSha: requiredString('Missing head SHA'),
|
|
baseSha: requiredString('Missing base SHA')
|
|
})
|
|
|
|
const PullRequestFileViewed = RepoSelector.extend({
|
|
pullRequestId: requiredString('Missing pull request ID'),
|
|
path: requiredString('Missing file path'),
|
|
viewed: z.boolean()
|
|
})
|
|
|
|
const ReviewThread = RepoSelector.extend({
|
|
threadId: requiredString('Missing thread ID'),
|
|
resolve: z.boolean()
|
|
})
|
|
|
|
const UpdatePrTitle = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
title: requiredString('Missing title'),
|
|
prRepo: SlugRepo.nullable().optional()
|
|
})
|
|
|
|
const MergePr = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
method: z.enum(['merge', 'squash', 'rebase']).optional(),
|
|
prRepo: SlugRepo.nullable().optional()
|
|
})
|
|
|
|
const UpdatePrState = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
updates: z.object({
|
|
state: z.enum(['open', 'closed'])
|
|
})
|
|
})
|
|
|
|
const RequestPrReviewers = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
reviewers: z.array(z.string()).min(1)
|
|
})
|
|
|
|
const RemovePrReviewers = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
reviewers: z.array(z.string()).min(1)
|
|
})
|
|
|
|
const CreateIssue = RepoSelector.extend({
|
|
title: requiredString('Missing title'),
|
|
body: z.string()
|
|
})
|
|
|
|
const IssueUpdate = z.object({
|
|
state: z.enum(['open', 'closed']).optional(),
|
|
title: OptionalString,
|
|
body: OptionalString,
|
|
addLabels: z.array(z.string()).optional(),
|
|
removeLabels: z.array(z.string()).optional(),
|
|
addAssignees: z.array(z.string()).optional(),
|
|
removeAssignees: z.array(z.string()).optional()
|
|
})
|
|
|
|
const UpdateIssue = RepoSelector.extend({
|
|
number: z.number().int().positive(),
|
|
updates: IssueUpdate
|
|
})
|
|
|
|
const IssueComment = RepoSelector.extend({
|
|
number: z.number().int().positive(),
|
|
body: requiredString('Comment body required'),
|
|
type: z.enum(['issue', 'pr']).optional()
|
|
})
|
|
|
|
const PRReviewComment = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
commitId: requiredString('Missing PR head SHA'),
|
|
path: requiredString('File path required'),
|
|
line: z.number().int().positive(),
|
|
startLine: z.number().int().positive().optional(),
|
|
body: requiredString('Comment body required')
|
|
})
|
|
|
|
const PRReviewCommentReply = RepoSelector.extend({
|
|
prNumber: z.number().int().positive(),
|
|
commentId: z.number().int().positive(),
|
|
body: requiredString('Comment body required'),
|
|
threadId: OptionalString,
|
|
path: OptionalString,
|
|
line: z.number().int().positive().optional()
|
|
})
|
|
|
|
const ProjectOwnerType = z.enum(['organization', 'user'])
|
|
|
|
const ProjectViewTable = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
ownerType: ProjectOwnerType,
|
|
projectNumber: z.number().int().positive(),
|
|
viewId: OptionalString,
|
|
viewNumber: z.number().int().positive().optional(),
|
|
viewName: OptionalString,
|
|
queryOverride: OptionalString
|
|
})
|
|
|
|
const ProjectWorkItemDetailsBySlug = SlugRepo.extend({
|
|
number: z.number().int().positive(),
|
|
type: z.enum(['issue', 'pr'])
|
|
})
|
|
|
|
const ProjectRef = z.object({
|
|
input: requiredString('Missing project reference')
|
|
})
|
|
|
|
const ProjectViews = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
ownerType: ProjectOwnerType,
|
|
projectNumber: z.number().int().positive()
|
|
})
|
|
|
|
const ProjectItemField = z.object({
|
|
projectId: requiredString('Missing project ID'),
|
|
itemId: requiredString('Missing item ID'),
|
|
fieldId: requiredString('Missing field ID'),
|
|
value: z.any()
|
|
})
|
|
|
|
const ClearProjectItemField = z.object({
|
|
projectId: requiredString('Missing project ID'),
|
|
itemId: requiredString('Missing item ID'),
|
|
fieldId: requiredString('Missing field ID')
|
|
})
|
|
|
|
const SlugIssueUpdate = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
repo: requiredString('Missing repo'),
|
|
number: z.number().int().positive(),
|
|
updates: IssueUpdate
|
|
})
|
|
|
|
const SlugPullRequestUpdate = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
repo: requiredString('Missing repo'),
|
|
number: z.number().int().positive(),
|
|
updates: z.object({
|
|
state: z.enum(['open', 'closed']).optional(),
|
|
title: OptionalString,
|
|
body: OptionalString
|
|
})
|
|
})
|
|
|
|
const SlugIssueTypeUpdate = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
repo: requiredString('Missing repo'),
|
|
number: z.number().int().positive(),
|
|
issueTypeId: z.string().nullable()
|
|
})
|
|
|
|
const SlugIssueComment = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
repo: requiredString('Missing repo'),
|
|
number: z.number().int().positive(),
|
|
body: requiredString('Comment body required')
|
|
})
|
|
|
|
const SlugIssueCommentEdit = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
repo: requiredString('Missing repo'),
|
|
commentId: z.number().int().positive(),
|
|
body: requiredString('Comment body required')
|
|
})
|
|
|
|
const SlugIssueCommentDelete = z.object({
|
|
owner: requiredString('Missing owner'),
|
|
repo: requiredString('Missing repo'),
|
|
commentId: z.number().int().positive()
|
|
})
|
|
|
|
export const GITHUB_METHODS: RpcMethod[] = [
|
|
defineMethod({
|
|
name: 'github.repoSlug',
|
|
params: RepoSelector,
|
|
handler: async (params, { runtime }) => runtime.getRepoSlug(params.repo)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.rateLimit',
|
|
params: RateLimit,
|
|
handler: async (params, { runtime }) => runtime.getGitHubRateLimit(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.listWorkItems',
|
|
params: WorkItemsList,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.listRepoWorkItems(params.repo, params.limit, params.query, params.before)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.countWorkItems',
|
|
params: WorkItemsCount,
|
|
handler: async (params, { runtime }) => runtime.countRepoWorkItems(params.repo, params.query)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.listLabels',
|
|
params: RepoSelector,
|
|
handler: async (params, { runtime }) => runtime.listRepoLabels(params.repo)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.listAssignableUsers',
|
|
params: RepoSelector,
|
|
handler: async (params, { runtime }) => runtime.listRepoAssignableUsers(params.repo)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.workItem',
|
|
params: WorkItem,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoWorkItem(params.repo, params.number, params.type)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.workItemByOwnerRepo',
|
|
params: WorkItemByOwnerRepo,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoWorkItemByOwnerRepo(
|
|
params.repo,
|
|
{ owner: params.owner, repo: params.ownerRepo },
|
|
params.number,
|
|
params.type
|
|
)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.workItemDetails',
|
|
params: WorkItemDetails,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoWorkItemDetails(params.repo, params.number, params.type)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.prForBranch',
|
|
params: PrForBranch,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoPRForBranch(
|
|
params.repo,
|
|
params.branch,
|
|
params.linkedPRNumber,
|
|
params.fallbackPRNumber
|
|
)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.issue',
|
|
params: Issue,
|
|
handler: async (params, { runtime }) => runtime.getRepoIssue(params.repo, params.number)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.prChecks',
|
|
params: PullRequestChecks,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoPRChecks(params.repo, params.prNumber, params.headSha, params.prRepo ?? null, {
|
|
noCache: params.noCache
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.prCheckDetails',
|
|
params: PullRequestCheckDetails,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoPRCheckDetails(params.repo, {
|
|
checkRunId: params.checkRunId,
|
|
workflowRunId: params.workflowRunId,
|
|
checkName: params.checkName,
|
|
url: params.url,
|
|
prRepo: params.prRepo ?? null
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.rerunPRChecks',
|
|
params: RerunPullRequestChecks,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.rerunRepoPRChecks(params.repo, params.prNumber, {
|
|
headSha: params.headSha,
|
|
failedOnly: params.failedOnly
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.prComments',
|
|
params: PullRequest,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoPRComments(params.repo, params.prNumber, params.prRepo ?? null, {
|
|
noCache: params.noCache
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.prFileContents',
|
|
params: PullRequestFileContents,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.getRepoPRFileContents(params.repo, {
|
|
prNumber: params.prNumber,
|
|
path: params.path,
|
|
oldPath: params.oldPath,
|
|
status: params.status,
|
|
headSha: params.headSha,
|
|
baseSha: params.baseSha
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.resolveReviewThread',
|
|
params: ReviewThread,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.resolveRepoReviewThread(params.repo, params.threadId, params.resolve)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.setPRFileViewed',
|
|
params: PullRequestFileViewed,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.setRepoPRFileViewed(params.repo, {
|
|
pullRequestId: params.pullRequestId,
|
|
path: params.path,
|
|
viewed: params.viewed
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.updatePRTitle',
|
|
params: UpdatePrTitle,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.updateRepoPRTitle(params.repo, params.prNumber, params.title, params.prRepo ?? null)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.mergePR',
|
|
params: MergePr,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.mergeRepoPR(params.repo, params.prNumber, params.method, params.prRepo ?? null)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.updatePRState',
|
|
params: UpdatePrState,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.updateRepoPRState(params.repo, params.prNumber, params.updates)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.requestPRReviewers',
|
|
params: RequestPrReviewers,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.requestRepoPRReviewers(params.repo, params.prNumber, params.reviewers)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.removePRReviewers',
|
|
params: RemovePrReviewers,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.removeRepoPRReviewers(params.repo, params.prNumber, params.reviewers)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.createIssue',
|
|
params: CreateIssue,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.createRepoIssue(params.repo, params.title, params.body)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.updateIssue',
|
|
params: UpdateIssue,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.updateRepoIssue(params.repo, params.number, params.updates)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.addIssueComment',
|
|
params: IssueComment,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.addRepoIssueComment(params.repo, params.number, params.body)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.addPRReviewComment',
|
|
params: PRReviewComment,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.addRepoPRReviewComment(params.repo, {
|
|
prNumber: params.prNumber,
|
|
commitId: params.commitId,
|
|
path: params.path,
|
|
line: params.line,
|
|
startLine: params.startLine,
|
|
body: params.body
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.addPRReviewCommentReply',
|
|
params: PRReviewCommentReply,
|
|
handler: async (params, { runtime }) =>
|
|
runtime.addRepoPRReviewCommentReply(params.repo, {
|
|
prNumber: params.prNumber,
|
|
commentId: params.commentId,
|
|
body: params.body,
|
|
threadId: params.threadId,
|
|
path: params.path,
|
|
line: params.line
|
|
})
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.listAccessible',
|
|
params: z.object({}),
|
|
handler: async (_params, { runtime }) => runtime.listGitHubProjects()
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.listLabelsBySlug',
|
|
params: SlugRepo,
|
|
handler: async (params, { runtime }) => runtime.listGitHubLabelsBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.listAssignableUsersBySlug',
|
|
params: SlugAssignableUsers,
|
|
handler: async (params, { runtime }) => runtime.listGitHubAssignableUsersBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.listIssueTypesBySlug',
|
|
params: SlugRepo,
|
|
handler: async (params, { runtime }) => runtime.listGitHubIssueTypesBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.resolveRef',
|
|
params: ProjectRef,
|
|
handler: async (params, { runtime }) => runtime.resolveGitHubProjectRef(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.listViews',
|
|
params: ProjectViews,
|
|
handler: async (params, { runtime }) => runtime.listGitHubProjectViews(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.viewTable',
|
|
params: ProjectViewTable,
|
|
handler: async (params, { runtime }) => runtime.getGitHubProjectViewTable(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.workItemDetailsBySlug',
|
|
params: ProjectWorkItemDetailsBySlug,
|
|
handler: async (params, { runtime }) => runtime.getGitHubProjectWorkItemDetailsBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.updateItemField',
|
|
params: ProjectItemField,
|
|
handler: async (params, { runtime }) => runtime.updateGitHubProjectItemField(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.clearItemField',
|
|
params: ClearProjectItemField,
|
|
handler: async (params, { runtime }) => runtime.clearGitHubProjectItemField(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.updateIssueBySlug',
|
|
params: SlugIssueUpdate,
|
|
handler: async (params, { runtime }) => runtime.updateGitHubIssueBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.updatePullRequestBySlug',
|
|
params: SlugPullRequestUpdate,
|
|
handler: async (params, { runtime }) => runtime.updateGitHubPullRequestBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.updateIssueTypeBySlug',
|
|
params: SlugIssueTypeUpdate,
|
|
handler: async (params, { runtime }) => runtime.updateGitHubIssueTypeBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.addIssueCommentBySlug',
|
|
params: SlugIssueComment,
|
|
handler: async (params, { runtime }) => runtime.addGitHubIssueCommentBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.updateIssueCommentBySlug',
|
|
params: SlugIssueCommentEdit,
|
|
handler: async (params, { runtime }) => runtime.updateGitHubIssueCommentBySlug(params)
|
|
}),
|
|
defineMethod({
|
|
name: 'github.project.deleteIssueCommentBySlug',
|
|
params: SlugIssueCommentDelete,
|
|
handler: async (params, { runtime }) => runtime.deleteGitHubIssueCommentBySlug(params)
|
|
})
|
|
]
|