import { BskyAgent } from "@atproto/api"; import { getPreferenceValues } from "@raycast/api"; import { SembleCard, SembleCollection, SembleCollectionLink, CardWithCollection } from "./types"; interface Preferences { identifier: string; password: string; pdsHost?: string; } export class SembleClient { private agent: BskyAgent; private preferences: Preferences; private userDid: string | null = null; constructor() { this.preferences = getPreferenceValues(); const pdsHost = this.preferences.pdsHost || "bsky.social"; this.agent = new BskyAgent({ service: `https://${pdsHost}`, }); } async authenticate(): Promise { try { const response = await this.agent.login({ identifier: this.preferences.identifier, password: this.preferences.password, }); this.userDid = response.data.did; } catch (error) { throw new Error(`Authentication failed: ${error instanceof Error ? error.message : "Unknown error"}`); } } async getCards(): Promise { if (!this.userDid) { await this.authenticate(); } try { const response = await this.agent.com.atproto.repo.listRecords({ repo: this.userDid!, collection: "network.cosmik.card", limit: 100, }); return response.data.records as unknown as SembleCard[]; } catch (error) { throw new Error(`Failed to fetch cards: ${error instanceof Error ? error.message : "Unknown error"}`); } } async getCollections(): Promise { if (!this.userDid) { await this.authenticate(); } try { const response = await this.agent.com.atproto.repo.listRecords({ repo: this.userDid!, collection: "network.cosmik.collection", limit: 100, }); return response.data.records as unknown as SembleCollection[]; } catch (error) { throw new Error(`Failed to fetch collections: ${error instanceof Error ? error.message : "Unknown error"}`); } } async getCollectionLinks(): Promise { if (!this.userDid) { await this.authenticate(); } try { const response = await this.agent.com.atproto.repo.listRecords({ repo: this.userDid!, collection: "network.cosmik.collectionLink", limit: 100, }); return response.data.records as unknown as SembleCollectionLink[]; } catch (error) { throw new Error( `Failed to fetch collection links: ${error instanceof Error ? error.message : "Unknown error"}` ); } } async getCardsWithCollections(): Promise { const [cards, collections, collectionLinks] = await Promise.all([ this.getCards(), this.getCollections(), this.getCollectionLinks(), ]); // Create a map of collection URIs to collection objects const collectionsMap = new Map(); collections.forEach((col) => { collectionsMap.set(col.uri, col); }); // Create a map of card URIs to their collections const cardCollectionsMap = new Map(); collectionLinks.forEach((link) => { const cardUri = link.value.card.uri; const collectionUri = link.value.collection.uri; const collection = collectionsMap.get(collectionUri); if (collection) { if (!cardCollectionsMap.has(cardUri)) { cardCollectionsMap.set(cardUri, []); } cardCollectionsMap.get(cardUri)!.push(collection); } }); // Combine cards with their collections return cards.map((card) => ({ card, collections: cardCollectionsMap.get(card.uri) || [], })); } getUserIdentifier(): string { return this.preferences.identifier; } getUserDid(): string | null { return this.userDid; } }