Gitee
by normal-coder
Verified
- operations
import { z } from "zod";
import { giteeRequest, validateOwnerName, validateRepositoryName, validateBranchName, getGiteeApiBaseUrl } from "../common/utils.js";
import { GiteePullRequestSchema } from "../common/types.js";
// Schema definitions
export const CreatePullRequestSchema = z.object({
// 仓库所属空间地址 (企业、组织或个人的地址 path)
owner: z.string().describe("Repository owner path (enterprise, organization, or personal path)"),
// 仓库路径 (path)
repo: z.string().describe("Repository path"),
// Pull Request 标题
title: z.string().describe("Pull Request title"),
// 源分支的名称
head: z.string().describe("Source branch name"),
// 目标分支的名称
base: z.string().describe("Target branch name"),
// Pull Request 内容
body: z.string().optional().describe("Pull Request content"),
// 里程碑序号
milestone_number: z.number().optional().describe("Milestone number"),
// 标签
labels: z.array(z.string()).optional().describe("Labels"),
// 相关的 Issue,格式为 #xxx
issue: z.string().optional().describe("Related issue, format: #xxx"),
// 审查人员
assignees: z.array(z.string()).optional().describe("Reviewers"),
// 测试人员
testers: z.array(z.string()).optional().describe("Testers"),
// 合并后是否删除源分支
prune_source_branch: z.boolean().optional().describe("Whether to delete the source branch after merging"),
});
export const ListPullRequestsSchema = z.object({
// 仓库所属空间地址 (企业、组织或个人的地址 path)
owner: z.string().describe("Repository owner path (enterprise, organization, or personal path)"),
// 仓库路径 (path)
repo: z.string().describe("Repository path"),
// Pull Request 状态
state: z.enum(["open", "closed", "merged", "all"]).default("open").optional().describe("Pull Request state"),
// 排序字段
sort: z.enum(["created", "updated", "popularity", "long-running"]).default("created").optional().describe("Sort field"),
// 排序方向
direction: z.enum(["asc", "desc"]).default("desc").optional().describe("Sort direction"),
// 里程碑 ID
milestone: z.number().optional().describe("Milestone ID"),
// 标签,多个标签以逗号分隔
labels: z.string().optional().describe("Labels, multiple labels separated by commas"),
// 当前的页码
page: z.number().int().default(1).optional().describe("Page number"),
// 每页的数量,最大为 100
per_page: z.number().int().min(1).max(100).optional().describe("Number of items per page, maximum 100"),
});
export const GetPullRequestSchema = z.object({
// 仓库所属空间地址 (企业、组织或个人的地址 path)
owner: z.string().describe("Repository owner path (enterprise, organization, or personal path)"),
// 仓库路径 (path)
repo: z.string().describe("Repository path"),
// Pull Request 编号
pull_number: z.number().describe("Pull Request number"),
});
export const UpdatePullRequestSchema = z.object({
// 仓库所属空间地址 (企业、组织或个人的地址 path)
owner: z.string().describe("Repository owner path (enterprise, organization, or personal path)"),
// 仓库路径 (path)
repo: z.string().describe("Repository path"),
// Pull Request 编号
pull_number: z.number().describe("Pull Request number"),
// Pull Request 标题
title: z.string().optional().describe("Pull Request title"),
// Pull Request 内容
body: z.string().optional().describe("Pull Request content"),
// Pull Request 状态
state: z.enum(["open", "closed"]).optional().describe("Pull Request state"),
// 里程碑序号
milestone_number: z.number().optional().describe("Milestone number"),
// 标签
labels: z.array(z.string()).optional().describe("Labels"),
// 审查人员
assignees: z.array(z.string()).optional().describe("Reviewers"),
// 测试人员
testers: z.array(z.string()).optional().describe("Testers"),
});
export const MergePullRequestSchema = z.object({
// 仓库所属空间地址 (企业、组织或个人的地址 path)
owner: z.string().describe("Repository owner path (enterprise, organization, or personal path)"),
// 仓库路径 (path)
repo: z.string().describe("Repository path"),
// Pull Request 编号
pull_number: z.number().describe("Pull Request number"),
// 合并方式
merge_method: z.enum(["merge", "squash", "rebase"]).default("merge").optional().describe("Merge method"),
// 合并后是否删除源分支
prune_source_branch: z.boolean().optional().describe("Whether to delete the source branch after merging"),
});
// Type exports
export type CreatePullRequestOptions = z.infer<typeof CreatePullRequestSchema>;
export type ListPullRequestsOptions = z.infer<typeof ListPullRequestsSchema>;
export type GetPullRequestOptions = z.infer<typeof GetPullRequestSchema>;
export type UpdatePullRequestOptions = z.infer<typeof UpdatePullRequestSchema>;
export type MergePullRequestOptions = z.infer<typeof MergePullRequestSchema>;
// Function implementations
export async function createPullRequest(options: CreatePullRequestOptions) {
const { owner, repo, ...rest } = options;
const validatedOwner = validateOwnerName(owner);
const validatedRepo = validateRepositoryName(repo);
const validatedHead = validateBranchName(rest.head);
const validatedBase = validateBranchName(rest.base);
const url = `/repos/${validatedOwner}/${validatedRepo}/pulls`;
const body = {
...rest,
head: validatedHead,
base: validatedBase,
};
const response = await giteeRequest(url, "POST", body);
return GiteePullRequestSchema.parse(response);
}
export async function listPullRequests(
owner: string,
repo: string,
options: Omit<ListPullRequestsOptions, "owner" | "repo">
) {
owner = validateOwnerName(owner);
repo = validateRepositoryName(repo);
const url = new URL(`${getGiteeApiBaseUrl()}/repos/${owner}/${repo}/pulls`);
// Add query parameters
Object.entries(options).forEach(([key, value]) => {
if (value !== undefined) {
url.searchParams.append(key, value.toString());
}
});
const response = await giteeRequest(url.toString(), "GET");
return z.array(GiteePullRequestSchema).parse(response);
}
export async function getPullRequest(
owner: string,
repo: string,
pullNumber: number
) {
owner = validateOwnerName(owner);
repo = validateRepositoryName(repo);
const url = `/repos/${owner}/${repo}/pulls/${pullNumber}`;
const response = await giteeRequest(url, "GET");
return GiteePullRequestSchema.parse(response);
}
export async function updatePullRequest(
owner: string,
repo: string,
pullNumber: number,
options: Omit<UpdatePullRequestOptions, "owner" | "repo" | "pull_number">
) {
owner = validateOwnerName(owner);
repo = validateRepositoryName(repo);
const url = `/repos/${owner}/${repo}/pulls/${pullNumber}`;
const response = await giteeRequest(url, "PATCH", options);
return GiteePullRequestSchema.parse(response);
}
export async function mergePullRequest(
owner: string,
repo: string,
pullNumber: number,
options: Omit<MergePullRequestOptions, "owner" | "repo" | "pull_number">
) {
owner = validateOwnerName(owner);
repo = validateRepositoryName(repo);
const url = `/repos/${owner}/${repo}/pulls/${pullNumber}/merge`;
const response = await giteeRequest(url, "PUT", options);
return response;
}