forked from
rocksky.app/rocksky
A decentralized music tracking and discovery platform built on AT Protocol 馃幍
1import type { Agent } from "@atproto/api";
2import chalk from "chalk";
3import { ctx } from "context";
4import { createAgent } from "lib/agent";
5import * as FeedGenerator from "lexicon/types/app/rocksky/feed/generator";
6import tables from "schema";
7import type { InsertFeed } from "schema/feeds";
8import { eq } from "drizzle-orm";
9
10const args = process.argv.slice(2);
11
12if (args.length === 0) {
13 console.error("Please provide user author identifier (handle or DID).");
14 console.log(`Usage: ${chalk.cyan("npm run seed:feed -- <handle|did>")}`);
15 process.exit(1);
16}
17
18async function getFeeds(agent: Agent, limit: number = 100) {
19 const res = await agent.com.atproto.repo.listRecords({
20 repo: agent.assertDid,
21 collection: "app.rocksky.feed.generator",
22 limit,
23 });
24 return res.data.records.map((record) => ({
25 ...record,
26 value: FeedGenerator.isRecord(record.value) ? record.value : null,
27 }));
28}
29
30let userDid = args[0];
31
32if (!userDid.startsWith("did:plc:")) {
33 userDid = await ctx.baseIdResolver.handle.resolve(userDid);
34}
35
36const agent = await createAgent(ctx.oauthClient, userDid);
37
38const [user] = await ctx.db
39 .select()
40 .from(tables.users)
41 .where(eq(tables.users.did, agent.assertDid))
42 .execute();
43
44const feeds = await getFeeds(agent);
45
46for (const feed of feeds) {
47 if (!feed.value) continue;
48
49 await ctx.db
50 .insert(tables.feeds)
51 .values({
52 displayName: feed.value.displayName,
53 description: feed.value.description,
54 did: feed.value.did,
55 userId: user.id,
56 uri: feed.uri,
57 } satisfies InsertFeed)
58 .onConflictDoNothing()
59 .execute();
60 console.log(
61 `Feed ${chalk.cyanBright(feed.value.displayName)} seeded successfully.`,
62 );
63}
64
65process.exit(0);