import type { Datetime, Nsid, ResourceUri } from "@atcute/lexicons/syntax"; import { now as tidNow } from "@atcute/tid"; import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; import type { BobbinContext, XrpcRequestInit } from "$lib/api/client"; import type * as ShTangledLabelDefinition from "$lib/api/lexicons/types/sh/tangled/label/definition"; import { collect } from "$lib/api/pagination"; import { createRecord, deleteRecord, type WrittenRecord } from "$lib/api/write"; import { rkeyFromUri } from "$lib/api/uri"; export type LabelDefinition = ShTangledLabelDefinition.Main; const LABEL_DEFINITION_COLLECTION = "sh.tangled.label.definition" as Nsid; const ISSUE_SCOPE = "sh.tangled.repo.issue" as Nsid; const PULL_SCOPE = "sh.tangled.repo.pull" as Nsid; export const DEFAULT_LABEL_OWNER = "did:plc:wshs7t2adsemcrrd4snkeqli"; export const DEFAULT_LABELS = [ `at://${DEFAULT_LABEL_OWNER}/sh.tangled.label.definition/wontfix`, `at://${DEFAULT_LABEL_OWNER}/sh.tangled.label.definition/good-first-issue`, `at://${DEFAULT_LABEL_OWNER}/sh.tangled.label.definition/duplicate`, `at://${DEFAULT_LABEL_OWNER}/sh.tangled.label.definition/documentation`, `at://${DEFAULT_LABEL_OWNER}/sh.tangled.label.definition/assignee` ] as ResourceUri[]; export interface LabelView { uri: string; value: LabelDefinition; } export const listLabelDefinitions = async ( ctx: BobbinContext, subject: string, init?: XrpcRequestInit ): Promise => { const items = await collect( ctx, "sh.tangled.label.listDefinitions", { subject, limit: 100 }, { ...init, maxPages: 5 } ); return items.map((item) => ({ uri: item.uri, value: item.value as LabelDefinition })); }; export const isBasicLabel = (label: LabelDefinition): boolean => label.valueType.type === "null"; export interface CustomLabelInput { name: string; color: string; issues: boolean; pulls: boolean; keyValue: boolean; } export const createLabelDefinition = ( agent: OAuthUserAgent, input: CustomLabelInput ): Promise => createRecord( agent, LABEL_DEFINITION_COLLECTION, { $type: "sh.tangled.label.definition", name: input.name, color: input.color, scope: [...(input.issues ? [ISSUE_SCOPE] : []), ...(input.pulls ? [PULL_SCOPE] : [])], valueType: input.keyValue ? { type: "string", format: "any" } : { type: "null", format: "any" }, createdAt: new Date().toISOString() as Datetime }, tidNow() ); export const deleteLabelDefinition = (agent: OAuthUserAgent, uri: string): Promise => deleteRecord(agent, LABEL_DEFINITION_COLLECTION, rkeyFromUri(uri));