this repo has no description
1import "@atcute/bluesky/lexicons";
2import {
3 AppBskyLabelerService,
4 ComAtprotoLabelDefs,
5 ComAtprotoRepoCreateRecord,
6} from "@atcute/client/lexicons";
7import { loginAgent, LoginCredentials } from "./util.js";
8
9/**
10 * Declare the labels this labeler will apply. Necessary for users to be able to configure what they see.
11 * @param credentials The credentials of the labeler account.
12 * @param labelDefinitions The label definitions to declare. You can learn about the definition format [here](https://docs.bsky.app/docs/advanced-guides/moderation#custom-label-values).
13 * @param overwriteExisting Whether to overwrite the existing label definitions if they already exist.
14 */
15export async function declareLabeler(
16 credentials: LoginCredentials,
17 labelDefinitions: Array<ComAtprotoLabelDefs.LabelValueDefinition>,
18 overwriteExisting?: boolean,
19): Promise<void> {
20 const { agent, session } = await loginAgent(credentials);
21 const labelValues = labelDefinitions.map(({ identifier }) => identifier);
22
23 const existing = await getLabelerLabelDefinitions(credentials);
24 if (existing?.length && !overwriteExisting) {
25 if (overwriteExisting === false) return;
26 else if (overwriteExisting === undefined) {
27 throw new Error(
28 "Label definitions already exist. Use `overwriteExisting: true` to update them, or `overwriteExisting: false` to silence this error.",
29 );
30 }
31 }
32
33 const data = {
34 collection: "app.bsky.labeler.service",
35 rkey: "self",
36 repo: session.did,
37 record: {
38 $type: "app.bsky.labeler.service",
39 policies: { labelValues, labelValueDefinitions: labelDefinitions },
40 createdAt: new Date().toISOString(),
41 } satisfies AppBskyLabelerService.Record,
42 validate: true,
43 } satisfies ComAtprotoRepoCreateRecord.Input;
44
45 // We check if existing is truthy because an empty array means the record exists, but contains no definitions.
46 if (existing) {
47 await agent.call("com.atproto.repo.putRecord", { data });
48 } else {
49 await agent.call("com.atproto.repo.createRecord", { data });
50 }
51}
52
53/**
54 * Get the label definitions currently declared by the labeler.
55 * @param credentials The credentials of the labeler account.
56 * @returns The label definitions.
57 */
58export async function getLabelerLabelDefinitions(
59 credentials: LoginCredentials,
60): Promise<Array<ComAtprotoLabelDefs.LabelValueDefinition> | null> {
61 const { agent, session } = await loginAgent(credentials);
62 const { data: { value: declaration } } = await agent.get("com.atproto.repo.getRecord", {
63 params: { collection: "app.bsky.labeler.service", rkey: "self", repo: session.did },
64 }).catch(() => ({ data: { value: {} } }));
65 // @ts-expect-error — declaration is unknown
66 return declaration?.policies?.labelValueDefinitions ?? null;
67}
68
69/**
70 * Set the label definitions for this labeler account.
71 * @param credentials The credentials of the labeler account.
72 * @param labelDefinitions The label definitions to set.
73 */
74export async function setLabelerLabelDefinitions(
75 credentials: LoginCredentials,
76 labelDefinitions: Array<ComAtprotoLabelDefs.LabelValueDefinition>,
77) {
78 return declareLabeler(credentials, labelDefinitions, true);
79}
80
81/**
82 * Delete the labeler declaration for this account, removing all label definitions.
83 * @param credentials The credentials of the labeler account.
84 */
85export async function deleteLabelerDeclaration(credentials: LoginCredentials): Promise<void> {
86 const { agent, session } = await loginAgent(credentials);
87 await agent.call("com.atproto.repo.deleteRecord", {
88 data: { collection: "app.bsky.labeler.service", rkey: "self", repo: session.did },
89 });
90}