No description
|
Some checks failed
Build and Publish / build-and-publish (push) Failing after 44s
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .turbo | ||
| node_modules | ||
| src | ||
| .gitignore | ||
| CHANGELOG.md | ||
| eslint.config.js | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsconfig.tsbuildinfo | ||
| tsup.config.ts | ||
@lilith/http-client
Minimal HTTP client for the Lilith platform. This is a thin wrapper around Axios that provides transport layer functionality only.
Purpose
Provides a simple, configurable HTTP client factory without authentication concerns. Authentication is handled separately by @lilith/http-auth-interceptor.
Features
- Simple Axios instance factory
- Configurable base URL, timeout, and headers
- TypeScript support
- Composable with middleware (auth, logging, retry, etc.)
Installation
pnpm add @lilith/http-client
Usage
Basic Usage (No Authentication)
import { createApiClient } from '@lilith/http-client';
const client = createApiClient({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
});
const response = await client.get('/users');
With Authentication
For authentication, use @lilith/http-auth-interceptor:
import { createApiClient } from '@lilith/http-client';
import { createAuthInterceptor } from '@lilith/http-auth-interceptor';
// Create HTTP client
const client = createApiClient({
baseURL: 'https://api.example.com'
});
// Add authentication interceptor
createAuthInterceptor(client, {
getToken() {
return localStorage.getItem('auth_token');
},
async refreshToken() {
const refresh = localStorage.getItem('refresh_token');
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';
}
});
// Now all requests include auth token and handle 401 automatically
const response = await client.get('/users');
With Custom Interceptors
const client = createApiClient({
baseURL: 'https://api.example.com'
});
// Add request logging
client.interceptors.request.use((config) => {
console.log('Request:', config.method, config.url);
return config;
});
// Add response logging
client.interceptors.response.use(
(response) => {
console.log('Response:', response.status);
return response;
},
(error) => {
console.error('Error:', error.message);
throw error;
}
);
Configuration
ApiClientConfig
interface ApiClientConfig {
/**
* Base URL for API requests
* @default process.env.VITE_API_URL || 'http://localhost:4000/api'
*/
baseURL?: string;
/**
* Request timeout in milliseconds
* @default 10000
*/
timeout?: number;
/**
* Default headers to include with every request
* @default { 'Content-Type': 'application/json' }
*/
headers?: Record<string, string>;
}
Architecture
┌─────────────────────────────────────┐
│ Application Code │
│ (import { createApiClient }) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ @lilith/http-client │
│ (Transport: Axios wrapper) │
└──────────────┬──────────────────────┘
│
▼ (optional)
┌─────────────────────────────────────┐
│ @lilith/http-auth-interceptor │
│ (Auth: Token injection + refresh) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ axios │
│ (HTTP library) │
└─────────────────────────────────────┘
Migration from v1.x
Before (v1.x - Auth Built-In)
import { createApiClient } from '@lilith/http-client';
const client = createApiClient({
baseURL: 'https://api.example.com',
tokenStorageKey: 'auth_token',
refreshTokenStorageKey: 'refresh_token',
enableTokenRefresh: true,
handle401Redirects: true,
});
After (v2.x - Layered Architecture)
import { createApiClient } from '@lilith/http-client';
import { createAuthInterceptor } from '@lilith/http-auth-interceptor';
const client = createApiClient({
baseURL: 'https://api.example.com'
});
createAuthInterceptor(client, {
getToken: () => localStorage.getItem('auth_token'),
refreshToken: async () => {
const refresh = localStorage.getItem('refresh_token');
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';
}
});
Breaking Changes
- Removed auth configuration options:
tokenStorageKey,refreshTokenStorageKey,enableTokenRefresh,handle401Redirects,loginRoute,onTokenRefresh,onRefreshFailed - Removed custom interceptor options:
onRequest,onResponseError,enableLogging - Simplified to transport only: Use
@lilith/http-auth-interceptorfor authentication
Error Handling
Error types are still exported from @lilith/http-client:
import { isApiError, getErrorMessage } from '@lilith/http-client';
try {
await client.post('/users', userData);
} catch (error) {
if (isApiError(error)) {
console.error(error.response?.data.message);
}
toast.error(getErrorMessage(error));
}
Related Packages
- @lilith/http-auth-interceptor - JWT authentication interceptor
- @lilith/client-base - Abstract client interfaces for HTTP and WebSocket
License
MIT