fix: use buildUrl utility in issues module

This commit is contained in:
Peter M. Elias 2024-12-28 03:34:59 -08:00
commit dac0b7cc34

View file

@ -1,41 +1,43 @@
import { z } from "zod"; import { z } from "zod";
import { githubRequest, buildUrl } from "../common/utils.js"; 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({ export const CreateIssueOptionsSchema = z.object({
title: z.string().describe("Issue title"), title: z.string(),
body: z.string().optional().describe("Issue body/description"), body: z.string().optional(),
assignees: z.array(z.string()).optional().describe("Array of usernames to assign"), assignees: z.array(z.string()).optional(),
milestone: z.number().optional().describe("Milestone number to assign"), milestone: z.number().optional(),
labels: z.array(z.string()).optional().describe("Array of label names"), labels: z.array(z.string()).optional(),
}); });
export const CreateIssueSchema = z.object({ export const CreateIssueSchema = z.object({
owner: z.string().describe("Repository owner (username or organization)"), owner: z.string(),
repo: z.string().describe("Repository name"), repo: z.string(),
title: z.string().describe("Issue title"), ...CreateIssueOptionsSchema.shape,
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"),
}); });
export const ListIssuesOptionsSchema = z.object({ export const ListIssuesOptionsSchema = z.object({
owner: z.string(), owner: z.string(),
repo: z.string(), repo: z.string(),
state: z.enum(['open', 'closed', 'all']).optional(), direction: z.enum(["asc", "desc"]).optional(),
labels: z.array(z.string()).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(), 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({ export const UpdateIssueOptionsSchema = z.object({
@ -44,108 +46,63 @@ export const UpdateIssueOptionsSchema = z.object({
issue_number: z.number(), issue_number: z.number(),
title: z.string().optional(), title: z.string().optional(),
body: 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(), 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({ export async function getIssue(owner: string, repo: string, issue_number: number) {
owner: z.string(), return githubRequest(`https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}`);
repo: z.string(), }
issue_number: z.number(),
body: z.string()
});
export const GetIssueSchema = z.object({ export async function addIssueComment(
owner: z.string().describe("Repository owner (username or organization)"), owner: string,
repo: z.string().describe("Repository name"), repo: string,
issue_number: z.number().describe("Issue number") 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<typeof CreateIssueOptionsSchema>;
export type ListIssuesOptions = z.infer<typeof ListIssuesOptionsSchema>;
export type UpdateIssueOptions = z.infer<typeof UpdateIssueOptionsSchema>;
// Function implementations
export async function createIssue( export async function createIssue(
owner: string, owner: string,
repo: string, repo: string,
options: CreateIssueOptions options: z.infer<typeof CreateIssueOptionsSchema>
) { ) {
const response = await githubRequest( return githubRequest(
`https://api.github.com/repos/${owner}/${repo}/issues`, `https://api.github.com/repos/${owner}/${repo}/issues`,
{ {
method: "POST", method: "POST",
body: options, body: options,
} }
); );
return GitHubIssueSchema.parse(response);
} }
export async function listIssues( export async function listIssues(
owner: string, owner: string,
repo: string, repo: string,
options: Omit<ListIssuesOptions, 'owner' | 'repo'> options: Omit<z.infer<typeof ListIssuesOptionsSchema>, "owner" | "repo">
) { ) {
const url = buildUrl(`https://api.github.com/repos/${owner}/${repo}/issues`, options); return githubRequest(
const response = await githubRequest(url); buildUrl(`https://api.github.com/repos/${owner}/${repo}/issues`, options)
return z.array(GitHubIssueSchema).parse(response); );
} }
export async function updateIssue( export async function updateIssue(
owner: string, owner: string,
repo: string, repo: string,
issueNumber: number, issue_number: number,
options: Omit<UpdateIssueOptions, 'owner' | 'repo' | 'issue_number'> options: Omit<z.infer<typeof UpdateIssueOptionsSchema>, "owner" | "repo" | "issue_number">
) { ) {
const response = await githubRequest( return githubRequest(
`https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}`, `https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}`,
{ {
method: "PATCH", 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);
} }