remove.ts
1import type {} from "@atcute/atproto";
2import type {} from "@atcute/bluesky";
3import { Client, CredentialManager, ok } from "@atcute/client";
4
5/* ------------------------------------------------------------------ */
6/* 1. Log in */
7/* ------------------------------------------------------------------ */
8const manager = new CredentialManager({ service: "https://bsky.social" });
9await manager.login({
10 identifier: "handle.invalid", // ← your handle or email
11 password: "xD", // ← app-password recommended
12});
13const rpc = new Client({ handler: manager });
14
15/* ------------------------------------------------------------------ */
16/* 2. Remove lowercase `alt` from every social.grain.photo record */
17/* ------------------------------------------------------------------ */
18const collection = "social.grain.photo";
19const repo = "did:plc:tas6hj2xjrqben5653v5kohk";
20
21let cursor: string | undefined;
22do {
23 const res = await ok(
24 rpc.get("com.atproto.repo.listRecords", {
25 params: { repo, collection, cursor, limit: 100 },
26 })
27 );
28
29 for (const rec of res.records) {
30 const uri = rec.uri as string;
31 const record = rec.value as any;
32
33 if (!("alt" in record)) continue; // ← lowercase check
34
35 const { alt, ...cleaned } = record; // ← lowercase delete
36
37 await ok(
38 rpc.post("com.atproto.repo.putRecord", {
39 input: {
40 collection,
41 repo,
42 rkey: uri.split("/").pop()!,
43 record: cleaned,
44 },
45 })
46 );
47
48 console.log(`✔ removed \`alt\` from ${uri}`);
49 }
50
51 cursor = res.cursor;
52} while (cursor);
53
54console.log("All done 🎉");