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