diff --git a/src/github/operations/issues.ts b/src/github/operations/issues.ts index aec154f0..4681d26c 100644 --- a/src/github/operations/issues.ts +++ b/src/github/operations/issues.ts @@ -1,41 +1,43 @@ import { z } from "zod"; import { githubRequest, buildUrl } from "../common/utils.js"; -import { - GitHubIssueSchema, - GitHubLabelSchema, - GitHubIssueAssigneeSchema, - GitHubMilestoneSchema, -} from "../common/types.js"; -// Schema definitions +export const GetIssueSchema = z.object({ + owner: z.string(), + repo: z.string(), + issue_number: z.number(), +}); + +export const IssueCommentSchema = z.object({ + owner: z.string(), + repo: z.string(), + issue_number: z.number(), + body: z.string(), +}); + export const CreateIssueOptionsSchema = z.object({ - title: z.string().describe("Issue title"), - body: z.string().optional().describe("Issue body/description"), - assignees: z.array(z.string()).optional().describe("Array of usernames to assign"), - milestone: z.number().optional().describe("Milestone number to assign"), - labels: z.array(z.string()).optional().describe("Array of label names"), + title: z.string(), + body: z.string().optional(), + assignees: z.array(z.string()).optional(), + milestone: z.number().optional(), + labels: z.array(z.string()).optional(), }); export const CreateIssueSchema = z.object({ - owner: z.string().describe("Repository owner (username or organization)"), - repo: z.string().describe("Repository name"), - title: z.string().describe("Issue title"), - body: z.string().optional().describe("Issue body/description"), - assignees: z.array(z.string()).optional().describe("Array of usernames to assign"), - labels: z.array(z.string()).optional().describe("Array of label names"), - milestone: z.number().optional().describe("Milestone number to assign"), + owner: z.string(), + repo: z.string(), + ...CreateIssueOptionsSchema.shape, }); export const ListIssuesOptionsSchema = z.object({ owner: z.string(), repo: z.string(), - state: z.enum(['open', 'closed', 'all']).optional(), + direction: z.enum(["asc", "desc"]).optional(), labels: z.array(z.string()).optional(), - sort: z.enum(['created', 'updated', 'comments']).optional(), - direction: z.enum(['asc', 'desc']).optional(), - since: z.string().optional(), // ISO 8601 timestamp page: z.number().optional(), - per_page: z.number().optional() + per_page: z.number().optional(), + since: z.string().optional(), + sort: z.enum(["created", "updated", "comments"]).optional(), + state: z.enum(["open", "closed", "all"]).optional(), }); export const UpdateIssueOptionsSchema = z.object({ @@ -44,108 +46,63 @@ export const UpdateIssueOptionsSchema = z.object({ issue_number: z.number(), title: z.string().optional(), body: z.string().optional(), - state: z.enum(['open', 'closed']).optional(), - labels: z.array(z.string()).optional(), assignees: z.array(z.string()).optional(), - milestone: z.number().optional() + milestone: z.number().optional(), + labels: z.array(z.string()).optional(), + state: z.enum(["open", "closed"]).optional(), }); -export const IssueCommentSchema = z.object({ - owner: z.string(), - repo: z.string(), - issue_number: z.number(), - body: z.string() -}); +export async function getIssue(owner: string, repo: string, issue_number: number) { + return githubRequest(`https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}`); +} -export const GetIssueSchema = z.object({ - owner: z.string().describe("Repository owner (username or organization)"), - repo: z.string().describe("Repository name"), - issue_number: z.number().describe("Issue number") -}); +export async function addIssueComment( + owner: string, + repo: string, + issue_number: number, + body: string +) { + return githubRequest(`https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}/comments`, { + method: "POST", + body: { body }, + }); +} -// Type exports -export type CreateIssueOptions = z.infer; -export type ListIssuesOptions = z.infer; -export type UpdateIssueOptions = z.infer; - -// Function implementations export async function createIssue( owner: string, repo: string, - options: CreateIssueOptions + options: z.infer ) { - const response = await githubRequest( + return githubRequest( `https://api.github.com/repos/${owner}/${repo}/issues`, { method: "POST", body: options, } ); - - return GitHubIssueSchema.parse(response); } export async function listIssues( owner: string, repo: string, - options: Omit + options: Omit, "owner" | "repo"> ) { - const url = buildUrl(`https://api.github.com/repos/${owner}/${repo}/issues`, options); - const response = await githubRequest(url); - return z.array(GitHubIssueSchema).parse(response); + return githubRequest( + buildUrl(`https://api.github.com/repos/${owner}/${repo}/issues`, options) + ); } export async function updateIssue( owner: string, repo: string, - issueNumber: number, - options: Omit + issue_number: number, + options: Omit, "owner" | "repo" | "issue_number"> ) { - const response = await githubRequest( - `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}`, + return githubRequest( + `https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}`, { method: "PATCH", - body: options + body: options, } ); - - return GitHubIssueSchema.parse(response); -} - -export async function addIssueComment( - owner: string, - repo: string, - issueNumber: number, - body: string -) { - const response = await githubRequest( - `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}/comments`, - { - method: "POST", - body: { body } - } - ); - - return z.object({ - id: z.number(), - node_id: z.string(), - url: z.string(), - html_url: z.string(), - body: z.string(), - user: GitHubIssueAssigneeSchema, - created_at: z.string(), - updated_at: z.string(), - }).parse(response); -} - -export async function getIssue( - owner: string, - repo: string, - issueNumber: number -) { - const response = await githubRequest( - `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}` - ); - - return GitHubIssueSchema.parse(response); -} +} \ No newline at end of file