import { ok } from "@atcute/client"; import { mainSchema as putRecordSchema } from "@atcute/atproto/types/repo/putRecord"; import { mainSchema as deleteRecordSchema } from "@atcute/atproto/types/repo/deleteRecord"; import type { Nsid, RecordKey } from "@atcute/lexicons/syntax"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; import { createClient } from "$lib/auth/agent"; import type { BobbinContext, XrpcRequestInit } from "./client"; import { jsonGet } from "./_request"; import type { RecordList, RecordView } from "./records"; import type * as ShTangledRepoIssue from "./lexicons/types/sh/tangled/repo/issue"; import type * as ShTangledRepoIssueState from "./lexicons/types/sh/tangled/repo/issue/state"; export type IssueRecord = ShTangledRepoIssue.Main; export type IssueStateRecord = ShTangledRepoIssueState.Main; const ISSUE_COLLECTION = "sh.tangled.repo.issue" as Nsid; export const putIssue = async ( agent: OAuthUserAgent, rkey: string, record: IssueRecord ): Promise> => { const rpc = createClient(agent); const { uri, cid } = await ok( rpc.call(putRecordSchema, { input: { repo: agent.sub, collection: ISSUE_COLLECTION, rkey: rkey as RecordKey, record } }) ); return { uri, cid, value: record }; }; export const deleteIssue = async (agent: OAuthUserAgent, rkey: string): Promise => { const rpc = createClient(agent); await ok( rpc.call(deleteRecordSchema, { input: { repo: agent.sub, collection: ISSUE_COLLECTION, rkey: rkey as RecordKey } }) ); }; export const getIssue = (ctx: BobbinContext, issue: string, init?: XrpcRequestInit) => jsonGet>(ctx, "sh.tangled.repo.getIssue", { issue }, init); export const getIssues = (ctx: BobbinContext, issues: readonly string[], init?: XrpcRequestInit) => jsonGet>(ctx, "sh.tangled.repo.getIssues", { issues }, init); export type IssueState = "open" | "closed"; // a listIssues row: the embedded issue record plus bobbin-derived state/counts. export interface IssueListItem { cid?: string; commentCount: number; state: string; stateUpdatedAt?: string; uri: string; value: IssueRecord; } export interface IssueListPage { cursor?: string | null; items: IssueListItem[]; } export interface ListIssuesFilter { state?: IssueState; author?: string; limit?: number; cursor?: string; order?: "asc" | "desc"; } export const listIssues = ( ctx: BobbinContext, subject: string, filter: ListIssuesFilter = {}, init?: XrpcRequestInit ) => jsonGet(ctx, "sh.tangled.repo.listIssues", { subject, ...filter }, init); export interface IssueStateList { cursor?: string | null; items: RecordView[]; } export const listIssueStates = ( ctx: BobbinContext, subject: string, filter: { limit?: number; cursor?: string; order?: "asc" | "desc" } = {}, init?: XrpcRequestInit ) => jsonGet(ctx, "sh.tangled.repo.issue.listStates", { subject, ...filter }, init);