This repository has no description
1import { Result, ok, err } from '../../../../shared/core/Result';
2import {
3 IAtUriResolutionService,
4 AtUriResourceType,
5 AtUriResolutionResult,
6} from '../../domain/services/IAtUriResolutionService';
7import { CollectionId } from '../../domain/value-objects/CollectionId';
8import { CardId } from '../../domain/value-objects/CardId';
9import { FollowTargetType } from '../../../user/domain/value-objects/FollowTargetType';
10import { InMemoryCollectionRepository } from './InMemoryCollectionRepository';
11import { InMemoryCardRepository } from './InMemoryCardRepository';
12
13export class InMemoryAtUriResolutionService implements IAtUriResolutionService {
14 constructor(
15 private collectionRepository: InMemoryCollectionRepository,
16 private cardRepository: InMemoryCardRepository,
17 ) {}
18
19 async resolveAtUri(
20 atUri: string,
21 ): Promise<Result<AtUriResolutionResult | null>> {
22 try {
23 // Check cards first
24 const allCards = this.cardRepository.getAllCards();
25 for (const card of allCards) {
26 if (card.publishedRecordId?.uri === atUri) {
27 return ok({
28 type: AtUriResourceType.CARD,
29 id: card.cardId,
30 });
31 }
32 }
33
34 // Check collections
35 const allCollections = this.collectionRepository.getAllCollections();
36 for (const collection of allCollections) {
37 if (collection.publishedRecordId?.uri === atUri) {
38 return ok({
39 type: AtUriResourceType.COLLECTION,
40 id: collection.collectionId,
41 });
42 }
43
44 // Check collection links (cards within collections)
45 for (const cardLink of collection.cardLinks) {
46 if (cardLink.publishedRecordId?.uri === atUri) {
47 return ok({
48 type: AtUriResourceType.COLLECTION_LINK,
49 id: {
50 collectionId: collection.collectionId,
51 cardId: cardLink.cardId,
52 },
53 });
54 }
55 }
56 }
57
58 return ok(null);
59 } catch (error) {
60 return err(error as Error);
61 }
62 }
63
64 async resolveCollectionId(
65 atUri: string,
66 ): Promise<Result<CollectionId | null>> {
67 const result = await this.resolveAtUri(atUri);
68
69 if (result.isErr()) {
70 return err(result.error);
71 }
72
73 if (!result.value || result.value.type !== AtUriResourceType.COLLECTION) {
74 return ok(null);
75 }
76
77 return ok(result.value.id as CollectionId);
78 }
79
80 async resolveCardId(atUri: string): Promise<Result<CardId | null>> {
81 const result = await this.resolveAtUri(atUri);
82
83 if (result.isErr()) {
84 return err(result.error);
85 }
86
87 if (!result.value || result.value.type !== AtUriResourceType.CARD) {
88 return ok(null);
89 }
90
91 return ok(result.value.id as CardId);
92 }
93
94 async resolveCollectionLinkId(
95 atUri: string,
96 ): Promise<Result<{ collectionId: CollectionId; cardId: CardId } | null>> {
97 const result = await this.resolveAtUri(atUri);
98
99 if (result.isErr()) {
100 return err(result.error);
101 }
102
103 if (
104 !result.value ||
105 result.value.type !== AtUriResourceType.COLLECTION_LINK
106 ) {
107 return ok(null);
108 }
109
110 return ok(
111 result.value.id as { collectionId: CollectionId; cardId: CardId },
112 );
113 }
114
115 async resolveFollowId(atUri: string): Promise<
116 Result<{
117 followerDid: string;
118 targetId: string;
119 targetType: FollowTargetType;
120 } | null>
121 > {
122 // For testing purposes, return null (follow not found)
123 // In a real implementation, this would search through follow records
124 return ok(null);
125 }
126}