Something went wrong. Try again.
CLI for Linear via GraphQL API
Something went wrong. Try again.
4.8 kB · 232 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233import { graphql } from "../api.ts";import { formatDate, printTable, requireToken, truncate, useJson,} from "./shared.ts";
export interface ListCommentsOptions { issue: string; json?: boolean;}
export async function listComments( options: ListCommentsOptions,): Promise<void> { const token = await requireToken(); const json = await useJson(options.json);
const query = ` query IssueComments($id: String!) { issue(id: $id) { comments { nodes { id body user { name } createdAt updatedAt } } } } `;
const data = await graphql<{ issue: { comments: { nodes: Array<{ id: string; body: string; user: { name: string } | null; createdAt: string; updatedAt: string; }>; }; }; }>(token, query, { id: options.issue });
const comments = data.issue.comments.nodes;
if (json) { console.log(JSON.stringify(comments, null, 2)); return; }
if (comments.length === 0) { console.log("No comments found."); return; }
const headers = ["ID", "AUTHOR", "BODY", "CREATED"]; const rows = comments.map((c) => [ c.id, c.user?.name ?? "-", truncate(c.body, 80), formatDate(c.createdAt), ]); printTable(headers, rows);}
export interface CreateCommentOptions { issue: string; body: string; json?: boolean;}
export async function createComment( options: CreateCommentOptions,): Promise<void> { const token = await requireToken(); const json = await useJson(options.json);
const issueQuery = ` query Issue($id: String!) { issue(id: $id) { id } } `;
const issueData = await graphql<{ issue: { id: string }; }>(token, issueQuery, { id: options.issue });
const issueId = issueData.issue.id;
const mutation = ` mutation CommentCreate($input: CommentCreateInput!) { commentCreate(input: $input) { success comment { id body user { name } createdAt url } } } `;
const data = await graphql<{ commentCreate: { success: boolean; comment: { id: string; body: string; user: { name: string } | null; createdAt: string; url: string; }; }; }>(token, mutation, { input: { issueId, body: options.body } });
if (!data.commentCreate.success) { console.error("Error: Failed to create comment."); process.exit(1); }
const comment = data.commentCreate.comment;
if (json) { console.log(JSON.stringify(comment, null, 2)); return; }
console.log(`Created comment ${comment.id}`); console.log(`Author: ${comment.user?.name ?? "-"}`); console.log(`URL: ${comment.url}`);}
export interface UpdateCommentOptions { id: string; body: string; json?: boolean;}
export async function updateComment( options: UpdateCommentOptions,): Promise<void> { const token = await requireToken(); const json = await useJson(options.json);
const mutation = ` mutation CommentUpdate($id: String!, $input: CommentUpdateInput!) { commentUpdate(id: $id, input: $input) { success comment { id body updatedAt } } } `;
const data = await graphql<{ commentUpdate: { success: boolean; comment: { id: string; body: string; updatedAt: string; }; }; }>(token, mutation, { id: options.id, input: { body: options.body } });
if (!data.commentUpdate.success) { console.error("Error: Failed to update comment."); process.exit(1); }
const comment = data.commentUpdate.comment;
if (json) { console.log(JSON.stringify(comment, null, 2)); return; }
console.log(`Updated comment ${comment.id}`); console.log(`Updated: ${formatDate(comment.updatedAt)}`);}
export interface DeleteCommentOptions { id: string; json?: boolean;}
export async function deleteComment( options: DeleteCommentOptions,): Promise<void> { const token = await requireToken(); const json = await useJson(options.json);
const mutation = ` mutation CommentDelete($id: String!) { commentDelete(id: $id) { success } } `;
const data = await graphql<{ commentDelete: { success: boolean; }; }>(token, mutation, { id: options.id });
if (!data.commentDelete.success) { console.error("Error: Failed to delete comment."); process.exit(1); }
if (json) { console.log(JSON.stringify({ id: options.id, deleted: true }, null, 2)); return; }
console.log(`Deleted comment ${options.id}`);}