/** * Integration Example: Using @lilith/http-client with @lilith/http-auth-interceptor * * This example demonstrates how to compose the HTTP client with authentication interceptor. */ import { createApiClient } from '@lilith/http-client'; import { createAuthInterceptor } from '@lilith/http-auth-interceptor'; import type { JwtTokenSource } from '@lilith/http-auth-interceptor'; /** * Example 1: Basic Setup with localStorage */ export function example1_basicSetup() { // Step 1: Create HTTP client (transport only) const client = createApiClient({ baseURL: 'https://api.example.com', timeout: 10000, }); // Step 2: Add authentication interceptor createAuthInterceptor(client, { getToken() { return localStorage.getItem('auth_token'); }, async refreshToken() { const refresh = localStorage.getItem('refresh_token'); if (!refresh) { return null; } const response = await fetch('/auth/refresh', { method: 'POST', body: JSON.stringify({ refreshToken: refresh }), }); const data = await response.json(); localStorage.setItem('auth_token', data.accessToken); return data.accessToken; }, onRefreshFailed() { localStorage.clear(); window.location.href = '/login'; }, }); // Step 3: Use client normally return client; } /** * Example 2: Using a Token Store Class */ class TokenStore implements JwtTokenSource { private accessToken: string | null = null; private refreshTokenValue: string | null = null; getToken(): string | null { return this.accessToken; } async refreshToken(): Promise { if (!this.refreshTokenValue) { return null; } const response = await fetch('/auth/refresh', { method: 'POST', body: JSON.stringify({ refreshToken: this.refreshTokenValue }), }); const data = await response.json(); this.accessToken = data.accessToken; this.refreshTokenValue = data.refreshToken; return data.accessToken; } onRefreshFailed(): void { this.clear(); } setTokens(access: string, refresh: string): void { this.accessToken = access; this.refreshTokenValue = refresh; } clear(): void { this.accessToken = null; this.refreshTokenValue = null; } } export function example2_tokenStore() { const tokenStore = new TokenStore(); const client = createApiClient({ baseURL: 'https://api.example.com', }); createAuthInterceptor(client, tokenStore); // Can control tokens programmatically tokenStore.setTokens('initial-access', 'initial-refresh'); return { client, tokenStore }; } /** * Example 3: Public API (No Auth) */ export function example3_publicAPI() { // Just use the HTTP client without auth interceptor const client = createApiClient({ baseURL: 'https://api.public.com', }); // No auth interceptor needed return client; } /** * Example 4: URL Exclusion */ export function example4_urlExclusion() { const client = createApiClient({ baseURL: 'https://api.example.com', }); createAuthInterceptor( client, { getToken: () => localStorage.getItem('auth_token'), refreshToken: async () => { const response = await fetch('/auth/refresh', { method: 'POST' }); const data = await response.json(); return data.accessToken; }, }, { // Skip auth for public endpoints excludeUrls: ['/public', /^\/auth\//], }, ); return client; } /** * Example 5: Custom Headers and Prefix */ export function example5_customHeaders() { const client = createApiClient({ baseURL: 'https://api.example.com', }); createAuthInterceptor( client, { getToken: () => localStorage.getItem('auth_token'), refreshToken: async () => { const response = await fetch('/auth/refresh', { method: 'POST' }); const data = await response.json(); return data.accessToken; }, }, { authHeader: 'X-Auth-Token', // Custom header name tokenPrefix: 'JWT', // Custom prefix (instead of "Bearer") }, ); return client; }