A social knowledge tool for researchers built on ATProto
1import {
2 QueryClient,
3 CardClient,
4 CollectionClient,
5 UserClient,
6 FeedClient,
7} from './clients';
8import type {
9 // Request types
10 AddUrlToLibraryRequest,
11 AddCardToLibraryRequest,
12 AddCardToCollectionRequest,
13 UpdateNoteCardRequest,
14 UpdateUrlCardAssociationsRequest,
15 RemoveCardFromLibraryRequest,
16 RemoveCardFromCollectionRequest,
17 CreateCollectionRequest,
18 UpdateCollectionRequest,
19 DeleteCollectionRequest,
20 LoginWithAppPasswordRequest,
21 InitiateOAuthSignInRequest,
22 CompleteOAuthSignInRequest,
23 RefreshAccessTokenRequest,
24 GenerateExtensionTokensRequest,
25 GetMyUrlCardsParams,
26 GetCollectionPageParams,
27 GetCollectionPageByAtUriParams,
28 GetMyCollectionsParams,
29 GetGlobalFeedParams,
30 // Response types
31 AddUrlToLibraryResponse,
32 AddCardToLibraryResponse,
33 AddCardToCollectionResponse,
34 UpdateNoteCardResponse,
35 UpdateUrlCardAssociationsResponse,
36 RemoveCardFromLibraryResponse,
37 RemoveCardFromCollectionResponse,
38 CreateCollectionResponse,
39 UpdateCollectionResponse,
40 DeleteCollectionResponse,
41 LoginWithAppPasswordResponse,
42 InitiateOAuthSignInResponse,
43 CompleteOAuthSignInResponse,
44 RefreshAccessTokenResponse,
45 GenerateExtensionTokensResponse,
46 GetUrlMetadataResponse,
47 GetUrlCardViewResponse,
48 GetLibrariesForCardResponse,
49 GetCollectionPageResponse,
50 GetGlobalFeedResponse,
51 GetCollectionsResponse,
52 GetCollectionsParams,
53 GetUrlCardsParams,
54 GetUrlCardsResponse,
55 GetProfileResponse,
56 GetProfileParams,
57 GetUrlStatusForMyLibraryParams,
58 GetUrlStatusForMyLibraryResponse,
59 GetLibrariesForUrlParams,
60 GetLibrariesForUrlResponse,
61 GetNoteCardsForUrlParams,
62 GetNoteCardsForUrlResponse,
63 GetCollectionsForUrlParams,
64 GetCollectionsForUrlResponse,
65 GetSimilarUrlsForUrlParams,
66 GetSimilarUrlsForUrlResponse,
67} from '@semble/types';
68
69// Main API Client class using composition
70export class ApiClient {
71 private queryClient: QueryClient;
72 private cardClient: CardClient;
73 private collectionClient: CollectionClient;
74 private userClient: UserClient;
75 private feedClient: FeedClient;
76
77 constructor(private baseUrl: string) {
78 this.queryClient = new QueryClient(baseUrl);
79 this.cardClient = new CardClient(baseUrl);
80 this.collectionClient = new CollectionClient(baseUrl);
81 this.userClient = new UserClient(baseUrl);
82 this.feedClient = new FeedClient(baseUrl);
83 }
84
85 // Query operations - delegate to QueryClient
86 async getUrlMetadata(url: string): Promise<GetUrlMetadataResponse> {
87 return this.queryClient.getUrlMetadata(url);
88 }
89
90 async getMyUrlCards(
91 params?: GetMyUrlCardsParams,
92 ): Promise<GetUrlCardsResponse> {
93 return this.queryClient.getMyUrlCards(params);
94 }
95
96 async getUrlCards(params: GetUrlCardsParams): Promise<GetUrlCardsResponse> {
97 return this.queryClient.getUserUrlCards(params);
98 }
99
100 async getUrlCardView(cardId: string): Promise<GetUrlCardViewResponse> {
101 return this.queryClient.getUrlCardView(cardId);
102 }
103
104 async getLibrariesForCard(
105 cardId: string,
106 ): Promise<GetLibrariesForCardResponse> {
107 return this.queryClient.getLibrariesForCard(cardId);
108 }
109
110 async getMyProfile(): Promise<GetProfileResponse> {
111 return this.queryClient.getMyProfile();
112 }
113
114 async getProfile(params: GetProfileParams): Promise<GetProfileResponse> {
115 return this.queryClient.getUserProfile(params);
116 }
117
118 async getCollectionPage(
119 collectionId: string,
120 params?: GetCollectionPageParams,
121 ): Promise<GetCollectionPageResponse> {
122 return this.queryClient.getCollectionPage(collectionId, params);
123 }
124
125 async getCollectionPageByAtUri(
126 params: GetCollectionPageByAtUriParams,
127 ): Promise<GetCollectionPageResponse> {
128 return this.queryClient.getCollectionPageByAtUri(params);
129 }
130
131 async getMyCollections(
132 params?: GetMyCollectionsParams,
133 ): Promise<GetCollectionsResponse> {
134 return this.queryClient.getMyCollections(params);
135 }
136
137 async getCollections(
138 params: GetCollectionsParams,
139 ): Promise<GetCollectionsResponse> {
140 return this.queryClient.getUserCollections(params);
141 }
142
143 async getUrlStatusForMyLibrary(
144 params: GetUrlStatusForMyLibraryParams,
145 ): Promise<GetUrlStatusForMyLibraryResponse> {
146 return this.queryClient.getUrlStatusForMyLibrary(params);
147 }
148
149 async getLibrariesForUrl(
150 params: GetLibrariesForUrlParams,
151 ): Promise<GetLibrariesForUrlResponse> {
152 return this.queryClient.getLibrariesForUrl(params);
153 }
154
155 async getNoteCardsForUrl(
156 params: GetNoteCardsForUrlParams,
157 ): Promise<GetNoteCardsForUrlResponse> {
158 return this.queryClient.getNoteCardsForUrl(params);
159 }
160
161 async getCollectionsForUrl(
162 params: GetCollectionsForUrlParams,
163 ): Promise<GetCollectionsForUrlResponse> {
164 return this.queryClient.getCollectionsForUrl(params);
165 }
166
167 async getSimilarUrlsForUrl(
168 params: GetSimilarUrlsForUrlParams,
169 ): Promise<GetSimilarUrlsForUrlResponse> {
170 return this.queryClient.getSimilarUrlsForUrl(params);
171 }
172
173 // Card operations - delegate to CardClient
174 async addUrlToLibrary(
175 request: AddUrlToLibraryRequest,
176 ): Promise<AddUrlToLibraryResponse> {
177 return this.cardClient.addUrlToLibrary(request);
178 }
179
180 async addCardToLibrary(
181 request: AddCardToLibraryRequest,
182 ): Promise<AddCardToLibraryResponse> {
183 return this.cardClient.addCardToLibrary(request);
184 }
185
186 async addCardToCollection(
187 request: AddCardToCollectionRequest,
188 ): Promise<AddCardToCollectionResponse> {
189 return this.cardClient.addCardToCollection(request);
190 }
191
192 async updateNoteCard(
193 request: UpdateNoteCardRequest,
194 ): Promise<UpdateNoteCardResponse> {
195 return this.cardClient.updateNoteCard(request);
196 }
197
198 async updateUrlCardAssociations(
199 request: UpdateUrlCardAssociationsRequest,
200 ): Promise<UpdateUrlCardAssociationsResponse> {
201 return this.cardClient.updateUrlCardAssociations(request);
202 }
203
204 async removeCardFromLibrary(
205 request: RemoveCardFromLibraryRequest,
206 ): Promise<RemoveCardFromLibraryResponse> {
207 return this.cardClient.removeCardFromLibrary(request);
208 }
209
210 async removeCardFromCollection(
211 request: RemoveCardFromCollectionRequest,
212 ): Promise<RemoveCardFromCollectionResponse> {
213 return this.cardClient.removeCardFromCollection(request);
214 }
215
216 // Collection operations - delegate to CollectionClient
217 async createCollection(
218 request: CreateCollectionRequest,
219 ): Promise<CreateCollectionResponse> {
220 return this.collectionClient.createCollection(request);
221 }
222
223 async updateCollection(
224 request: UpdateCollectionRequest,
225 ): Promise<UpdateCollectionResponse> {
226 return this.collectionClient.updateCollection(request);
227 }
228
229 async deleteCollection(
230 request: DeleteCollectionRequest,
231 ): Promise<DeleteCollectionResponse> {
232 return this.collectionClient.deleteCollection(request);
233 }
234
235 // User operations - delegate to UserClient
236 async loginWithAppPassword(
237 request: LoginWithAppPasswordRequest,
238 ): Promise<LoginWithAppPasswordResponse> {
239 return this.userClient.loginWithAppPassword(request);
240 }
241
242 async initiateOAuthSignIn(
243 request?: InitiateOAuthSignInRequest,
244 ): Promise<InitiateOAuthSignInResponse> {
245 return this.userClient.initiateOAuthSignIn(request);
246 }
247
248 async completeOAuthSignIn(
249 request: CompleteOAuthSignInRequest,
250 ): Promise<CompleteOAuthSignInResponse> {
251 return this.userClient.completeOAuthSignIn(request);
252 }
253
254 async refreshAccessToken(
255 request: RefreshAccessTokenRequest,
256 ): Promise<RefreshAccessTokenResponse> {
257 return this.userClient.refreshAccessToken(request);
258 }
259
260 async generateExtensionTokens(
261 request?: GenerateExtensionTokensRequest,
262 ): Promise<GenerateExtensionTokensResponse> {
263 return this.userClient.generateExtensionTokens(request);
264 }
265
266 async logout(): Promise<{ success: boolean; message: string }> {
267 return this.userClient.logout();
268 }
269
270 // Feed operations - delegate to FeedClient
271 async getGlobalFeed(
272 params?: GetGlobalFeedParams,
273 ): Promise<GetGlobalFeedResponse> {
274 return this.feedClient.getGlobalFeed(params);
275 }
276}
277
278// Re-export types for convenience
279export * from '@semble/types';
280
281// Factory functions for different client types
282export const createApiClient = () => {
283 return new ApiClient(
284 process.env.NEXT_PUBLIC_API_BASE_URL || 'http://127.0.0.1:3000',
285 );
286};
287
288export const createServerApiClient = () => {
289 return new ApiClient(
290 process.env.NEXT_PUBLIC_API_BASE_URL || 'http://127.0.0.1:3000',
291 );
292};
293
294// Default client instance for backward compatibility
295export const apiClient = createApiClient();