Something went wrong. Try again.
A social knowledge tool for research trails, built on ATProto semble.so
research-tool social-network tools-for-thought atproto
Something went wrong. Try again.
10 kB · 330 lines
TypeScript
at development
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331import { QueryClient, CardClient, CollectionClient, UserClient, FeedClient,} from './clients';import { TokenManager } from '../services/TokenManager';import { createClientTokenManager, createServerTokenManager,} from '../services/auth';import type { // Request types AddUrlToLibraryRequest, AddCardToLibraryRequest, AddCardToCollectionRequest, UpdateNoteCardRequest, RemoveCardFromLibraryRequest, RemoveCardFromCollectionRequest, CreateCollectionRequest, UpdateCollectionRequest, DeleteCollectionRequest, LoginWithAppPasswordRequest, InitiateOAuthSignInRequest, CompleteOAuthSignInRequest, RefreshAccessTokenRequest, GenerateExtensionTokensRequest, GetMyUrlCardsParams, GetCollectionPageParams, GetCollectionPageByAtUriParams, GetMyCollectionsParams, GetGlobalFeedParams, // Response types AddUrlToLibraryResponse, AddCardToLibraryResponse, AddCardToCollectionResponse, UpdateNoteCardResponse, RemoveCardFromLibraryResponse, RemoveCardFromCollectionResponse, CreateCollectionResponse, UpdateCollectionResponse, DeleteCollectionResponse, LoginWithAppPasswordResponse, InitiateOAuthSignInResponse, CompleteOAuthSignInResponse, RefreshAccessTokenResponse, GenerateExtensionTokensResponse, GetUrlMetadataResponse, GetUrlCardViewResponse, GetLibrariesForCardResponse, GetCollectionPageResponse, GetGlobalFeedResponse, GetCollectionsResponse, GetCollectionsParams, GetUrlCardsParams, GetUrlCardsResponse, GetProfileResponse, GetProfileParams, GetUrlStatusForMyLibraryParams, GetUrlStatusForMyLibraryResponse, GetLibrariesForUrlParams, GetLibrariesForUrlResponse, GetNoteCardsForUrlParams, GetNoteCardsForUrlResponse, GetCollectionsForUrlParams, GetCollectionsForUrlResponse,} from './types';
// Main API Client class using compositionexport class ApiClient { private queryClient: QueryClient; private cardClient: CardClient; private collectionClient: CollectionClient; private userClient: UserClient; private feedClient: FeedClient;
constructor( private baseUrl: string, private tokenManager?: TokenManager, ) { this.queryClient = new QueryClient(baseUrl, tokenManager); this.cardClient = new CardClient(baseUrl, tokenManager); this.collectionClient = new CollectionClient(baseUrl, tokenManager); this.userClient = new UserClient(baseUrl, tokenManager); this.feedClient = new FeedClient(baseUrl, tokenManager); }
// Helper to check if client is authenticated get isAuthenticated(): boolean { return !!this.tokenManager; }
// Helper method to ensure authentication for protected operations private requireAuthentication(operation: string): void { if (!this.tokenManager) { throw new Error(`Authentication required for ${operation}`); } }
// Query operations - delegate to QueryClient async getUrlMetadata(url: string): Promise<GetUrlMetadataResponse> { return this.queryClient.getUrlMetadata(url); }
async getMyUrlCards( params?: GetMyUrlCardsParams, ): Promise<GetUrlCardsResponse> { this.requireAuthentication('getMyUrlCards'); return this.queryClient.getMyUrlCards(params); }
async getUrlCards(params: GetUrlCardsParams): Promise<GetUrlCardsResponse> { return this.queryClient.getUserUrlCards(params); }
async getUrlCardView(cardId: string): Promise<GetUrlCardViewResponse> { return this.queryClient.getUrlCardView(cardId); }
async getLibrariesForCard( cardId: string, ): Promise<GetLibrariesForCardResponse> { this.requireAuthentication('getLibrariesForCard'); return this.queryClient.getLibrariesForCard(cardId); }
async getMyProfile(): Promise<GetProfileResponse> { this.requireAuthentication('getMyProfile'); return this.queryClient.getMyProfile(); }
async getProfile(params: GetProfileParams): Promise<GetProfileResponse> { return this.queryClient.getUserProfile(params); }
async getCollectionPage( collectionId: string, params?: GetCollectionPageParams, ): Promise<GetCollectionPageResponse> { return this.queryClient.getCollectionPage(collectionId, params); }
async getCollectionPageByAtUri( params: GetCollectionPageByAtUriParams, ): Promise<GetCollectionPageResponse> { return this.queryClient.getCollectionPageByAtUri(params); }
async getMyCollections( params?: GetMyCollectionsParams, ): Promise<GetCollectionsResponse> { this.requireAuthentication('getMyCollections'); return this.queryClient.getMyCollections(params); }
async getCollections( params: GetCollectionsParams, ): Promise<GetCollectionsResponse> { return this.queryClient.getUserCollections(params); }
async getUrlStatusForMyLibrary( params: GetUrlStatusForMyLibraryParams, ): Promise<GetUrlStatusForMyLibraryResponse> { this.requireAuthentication('getUrlStatusForMyLibrary'); return this.queryClient.getUrlStatusForMyLibrary(params); }
async getLibrariesForUrl( params: GetLibrariesForUrlParams, ): Promise<GetLibrariesForUrlResponse> { return this.queryClient.getLibrariesForUrl(params); }
async getNoteCardsForUrl( params: GetNoteCardsForUrlParams, ): Promise<GetNoteCardsForUrlResponse> { return this.queryClient.getNoteCardsForUrl(params); }
async getCollectionsForUrl( params: GetCollectionsForUrlParams, ): Promise<GetCollectionsForUrlResponse> { return this.queryClient.getCollectionsForUrl(params); }
// Card operations - delegate to CardClient (all require authentication) async addUrlToLibrary( request: AddUrlToLibraryRequest, ): Promise<AddUrlToLibraryResponse> { this.requireAuthentication('addUrlToLibrary'); return this.cardClient.addUrlToLibrary(request); }
async addCardToLibrary( request: AddCardToLibraryRequest, ): Promise<AddCardToLibraryResponse> { this.requireAuthentication('addCardToLibrary'); return this.cardClient.addCardToLibrary(request); }
async addCardToCollection( request: AddCardToCollectionRequest, ): Promise<AddCardToCollectionResponse> { this.requireAuthentication('addCardToCollection'); return this.cardClient.addCardToCollection(request); }
async updateNoteCard( request: UpdateNoteCardRequest, ): Promise<UpdateNoteCardResponse> { this.requireAuthentication('updateNoteCard'); return this.cardClient.updateNoteCard(request); }
async removeCardFromLibrary( request: RemoveCardFromLibraryRequest, ): Promise<RemoveCardFromLibraryResponse> { this.requireAuthentication('removeCardFromLibrary'); return this.cardClient.removeCardFromLibrary(request); }
async removeCardFromCollection( request: RemoveCardFromCollectionRequest, ): Promise<RemoveCardFromCollectionResponse> { this.requireAuthentication('removeCardFromCollection'); return this.cardClient.removeCardFromCollection(request); }
// Collection operations - delegate to CollectionClient (all require authentication) async createCollection( request: CreateCollectionRequest, ): Promise<CreateCollectionResponse> { this.requireAuthentication('createCollection'); return this.collectionClient.createCollection(request); }
async updateCollection( request: UpdateCollectionRequest, ): Promise<UpdateCollectionResponse> { this.requireAuthentication('updateCollection'); return this.collectionClient.updateCollection(request); }
async deleteCollection( request: DeleteCollectionRequest, ): Promise<DeleteCollectionResponse> { this.requireAuthentication('deleteCollection'); return this.collectionClient.deleteCollection(request); }
// User operations - delegate to UserClient async loginWithAppPassword( request: LoginWithAppPasswordRequest, ): Promise<LoginWithAppPasswordResponse> { return this.userClient.loginWithAppPassword(request); }
async initiateOAuthSignIn( request?: InitiateOAuthSignInRequest, ): Promise<InitiateOAuthSignInResponse> { return this.userClient.initiateOAuthSignIn(request); }
async completeOAuthSignIn( request: CompleteOAuthSignInRequest, ): Promise<CompleteOAuthSignInResponse> { return this.userClient.completeOAuthSignIn(request); }
async refreshAccessToken( request: RefreshAccessTokenRequest, ): Promise<RefreshAccessTokenResponse> { this.requireAuthentication('refreshAccessToken'); return this.userClient.refreshAccessToken(request); }
async generateExtensionTokens( request?: GenerateExtensionTokensRequest, ): Promise<GenerateExtensionTokensResponse> { this.requireAuthentication('generateExtensionTokens'); return this.userClient.generateExtensionTokens(request); }
async logout(): Promise<{ success: boolean; message: string }> { this.requireAuthentication('logout'); return this.userClient.logout(); }
// Feed operations - delegate to FeedClient async getGlobalFeed( params?: GetGlobalFeedParams, ): Promise<GetGlobalFeedResponse> { return this.feedClient.getGlobalFeed(params); }}
// Re-export types for convenienceexport * from './types';
// Factory functions for different client typesexport const createAuthenticatedApiClient = () => { return new ApiClient( process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3000', createClientTokenManager(), );};
export const createUnauthenticatedApiClient = () => { return new ApiClient( process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3000', undefined, );};
// Factory function for server-side API clientexport const createServerApiClient = async () => { const tokenManager = await createServerTokenManager(); return new ApiClient( process.env.API_BASE_URL || 'http://localhost:3000', tokenManager, );};
// Default authenticated client instance for client-side usage (backward compatibility)export const apiClient = createAuthenticatedApiClient();
// Default unauthenticated client instance for public operationsexport const publicApiClient = createUnauthenticatedApiClient();