### Install Axios API Client Package Source: https://github.com/ronasit/axios-api-client/blob/main/README.md Installs the @ronas-it/axios-api-client package using npm. This is the first step to using the library in your project. ```bash npm i @ronas-it/axios-api-client ``` -------------------------------- ### Complete Authentication Setup with TypeScript Source: https://context7.com/ronasit/axios-api-client/llms.txt Demonstrates a full authentication flow using TypeScript, including token management, automatic refresh interceptors, and unauthorized request handling. It configures an ApiService instance with custom state management for authentication tokens. ```typescript import { ApiService, AuthConfiguration, RefreshTokenInterceptorOptions, tokenInterceptor, onRequestRefreshTokenInterceptor, onResponseRefreshTokenInterceptor, unauthorizedInterceptor, checkIsTokenExpired, isServerError } from '@ronas-it/axios-api-client'; // Configuration const authConfig: AuthConfiguration = { refreshTokenRoute: '/auth/refresh', unauthorizedRoutes: ['/auth/login', '/auth/register', '/auth/forgot-password'], logoutRoute: '/auth/logout' }; // State management (use your preferred state solution) class AuthStore { private accessToken: string | null = null; private isAuthenticated = false; setAuth(token: string) { this.accessToken = token; this.isAuthenticated = true; } clearAuth() { this.accessToken = null; this.isAuthenticated = false; } getToken = () => this.accessToken ?? ''; getIsAuthenticated = () => this.isAuthenticated; } const authStore = new AuthStore(); const apiService = new ApiService('https://api.example.com'); // Refresh token options const refreshOptions: RefreshTokenInterceptorOptions = { configuration: authConfig, getIsAuthenticated: authStore.getIsAuthenticated, runTokenRefreshRequest: async () => { const { token } = await apiService.post<{ token: string; expiresIn: number }>('/auth/refresh'); authStore.setAuth(token); return token; }, onError: async () => { authStore.clearAuth(); await apiService.post('/auth/logout').catch(() => {}); window.location.href = '/login'; } }; // Register all interceptors apiService.useInterceptors({ request: [ [tokenInterceptor({ getToken: authStore.getToken })], [onRequestRefreshTokenInterceptor(refreshOptions)] ], response: [ [null, onResponseRefreshTokenInterceptor(refreshOptions)], [null, unauthorizedInterceptor({ publicEndpoints: authConfig.unauthorizedRoutes, onError: () => { authStore.clearAuth(); window.location.href = '/login'; } })] ] }); // Login function async function login(email: string, password: string) { const response = await apiService.post<{ token: string; user: { id: number; name: string } }>( '/auth/login', { email, password } ); authStore.setAuth(response.token); return response.user; } // Usage const user = await login('user@example.com', 'password123'); const profile = await apiService.get('/profile'); // Token automatically added const posts = await apiService.get('/posts', { page: 1, limit: 20 }); ``` -------------------------------- ### Initialize and Use ApiService Class in TypeScript Source: https://context7.com/ronasit/axios-api-client/llms.txt Demonstrates how to initialize the ApiService class with different configurations and perform various HTTP requests (GET, POST, PUT, PATCH, DELETE). It also shows how to retrieve the full Axios response and handle errors using type guards. ```typescript import { ApiService } from '@ronasit/axios-api-client'; // Basic initialization const apiService = new ApiService('https://api.example.com'); // With custom Axios configuration const apiServiceWithConfig = new ApiService('https://api.example.com', { timeout: 30000, headers: { 'X-Custom-Header': 'value' } }); // GET request - returns data only by default interface User { id: number; name: string; email: string; } const user = await apiService.get('/users/1'); // Result: { id: 1, name: 'John', email: 'john@example.com' } // GET with query parameters const users = await apiService.get('/users', { page: 1, limit: 10 }); // Request: GET /users?page=1&limit=10 // POST request with body data const newUser = await apiService.post('/users', { name: 'Jane Doe', email: 'jane@example.com' }); // PUT request for full update await apiService.put('/users/1', { name: 'John Updated', email: 'john.updated@example.com' }); // PATCH request for partial update await apiService.patch('/users/1', { name: 'John Patched' }); // DELETE request await apiService.delete('/users/1'); // Get full Axios response including headers and status const fullResponse = await apiService.get('/users/1', null, { fullResponse: true }); // Result: { data: {...}, status: 200, headers: {...}, config: {...} } // Error handling with type guard try { await apiService.get('/protected-resource'); } catch (error) { if (ApiService.isAxiosError<{ message: string }>(error)) { console.error('API Error:', error.response?.data.message); console.error('Status:', error.response?.status); } } ``` -------------------------------- ### Configure and Use API Service with Interceptors (TypeScript) Source: https://github.com/ronasit/axios-api-client/blob/main/README.md Shows a comprehensive example of configuring the ApiService with authentication details and applying various interceptors. This includes token management, automatic token refresh, and handling unauthorized requests. Dependencies include the ApiService class and specific interceptor functions. ```typescript import { ApiService, AuthConfiguration, RefreshTokenInterceptorOptions, tokenInterceptor, onResponseRefreshTokenInterceptor, onRequestRefreshTokenInterceptor, unauthorizedInterceptor } from '@ronas-it/axios-api-client'; const configuration: AuthConfiguration = { apiURL: 'https://api.your-app.dev', auth: { refreshTokenRoute: '/auth/refresh', unauthorizedRoutes: ['/auth/forgot-password', '/auth/restore-password'], logoutRoute: '/logout', }, }; const apiService = new ApiService(configuration.apiURL); const options: RefreshTokenInterceptorOptions = { configuration: configuration.auth, getIsAuthenticated: () => { /* get isAuthenticated state here */ return true; // Placeholder }, runTokenRefreshRequest: async () => { const { token, ttl } = await apiService.get('/refresh'); /* do something with token and ttl */ return token; }, onError: () => apiService.post('/logout'), }; apiService.useInterceptors({ request: [ [ tokenInterceptor({ getToken: () => { /* get token here */ return 'your_token'; // Placeholder }, }), ], ], }); apiService.useInterceptors({ request: [[onRequestRefreshTokenInterceptor(options)]], response: [ [ null, onResponseRefreshTokenInterceptor(options), ], [ null, unauthorizedInterceptor({ publicEndpoints: configuration.auth.unauthorizedRoutes, onError: () => apiService.post('/logout'), }), ], ], }); ``` -------------------------------- ### Create API Service Instance (TypeScript) Source: https://github.com/ronasit/axios-api-client/blob/main/README.md Demonstrates how to create a new instance of the ApiService. It requires the API's base URL for configuration. This instance is then used for making API requests. ```typescript import { ApiService } from '@ronas-it/axios-api-client'; import { configuration } from './configuration'; export const apiService = new ApiService(configuration.apiURL); ``` -------------------------------- ### Implement JWT Token Authentication with tokenInterceptor in TypeScript Source: https://context7.com/ronasit/axios-api-client/llms.txt Shows how to use the `tokenInterceptor` to automatically add JWT Bearer tokens to request headers. It covers setting up a simple token storage mechanism and applying the interceptor to an ApiService instance. ```typescript import { ApiService, tokenInterceptor } from '@ronas-it/axios-api-client'; const apiService = new ApiService('https://api.example.com'); // Simple token storage let authToken: string | null = null; const setToken = (token: string) => { authToken = token; }; const getToken = () => authToken ?? ''; // Add token interceptor apiService.useInterceptors({ request: [ [tokenInterceptor({ getToken })] ] }); // After login, store the token const loginResponse = await apiService.post<{ token: string }>('/auth/login', { email: 'user@example.com', password: 'password123' }); setToken(loginResponse.token); // Subsequent requests automatically include Authorization header // Request headers: { Authorization: 'Bearer eyJhbGciOiJIUzI1NiIs...' } const profile = await apiService.get('/profile'); ``` -------------------------------- ### Identify Server Errors (5xx Status Codes) Source: https://context7.com/ronasit/axios-api-client/llms.txt Checks if an HTTP status code represents a server error (5xx range). This utility is useful for differentiating between client-side issues and server-side problems during error handling. It takes a numeric status code as input and returns true for 5xx codes, and false otherwise. ```typescript import { isServerError } from '@ronas-it/axios-api-client'; // Check various status codes isServerError(500); // true - Internal Server Error isServerError(502); // true - Bad Gateway isServerError(503); // true - Service Unavailable isServerError(504); // true - Gateway Timeout isServerError(400); // false - Bad Request (client error) isServerError(401); // false - Unauthorized (client error) isServerError(404); // false - Not Found (client error) isServerError(200); // false - OK (success) // Use in error handling try { await apiService.get('/data'); } catch (error) { if (ApiService.isAxiosError(error)) { if (isServerError(error.response?.status)) { console.error('Server error - please try again later'); // Show retry button, notify admins, etc. } else { console.error('Client error - check your request'); // Show validation errors, redirect to login, etc. } } } ``` -------------------------------- ### Check JWT Token Expiration Source: https://context7.com/ronasit/axios-api-client/llms.txt Decodes a JWT token and checks if it has expired based on the 'exp' claim. It works in both client and server environments, using a base-64 polyfill for 'atob' in Node.js. The function takes a JWT string as input and returns a boolean indicating if the token is expired. ```typescript import { checkIsTokenExpired } from '@ronas-it/axios-api-client'; // Example JWT token (expired) const expiredToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZXhwIjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'; const isExpired = checkIsTokenExpired(expiredToken); // Result: true (token expired on 2018-01-18) // Use in conditional logic const token = localStorage.getItem('accessToken'); if (token && checkIsTokenExpired(token)) { // Token is expired, need to refresh or re-authenticate await refreshToken(); } ``` -------------------------------- ### Check for Validation Errors in Error Response Source: https://context7.com/ronasit/axios-api-client/llms.txt A type guard utility that determines if an error response contains field-level validation messages. This is particularly helpful when handling API requests that return specific errors for invalid input fields. It takes an error response object as input and returns true if validation errors are present. ```typescript import { isErrorWithValidationErrors, ApiService } from '@ronas-it/axios-api-client'; const apiService = new ApiService('https://api.example.com'); try { await apiService.post('/users', { email: 'invalid-email', password: '123' // too short }); } catch (error) { if (ApiService.isAxiosError(error) && isErrorWithValidationErrors(error.response)) { // TypeScript knows error.response.data.errors exists const { errors } = error.response.data; // errors structure: { [fieldName]: string[] } // Example: { email: ['Invalid email format'], password: ['Password must be at least 8 characters'] } Object.entries(errors).forEach(([field, messages]) => { console.log(`${field}: ${messages.join(', ')}`); }); // Display in form // setFormErrors(errors); } } ``` -------------------------------- ### Proactively Refresh JWT Token Before Request (TypeScript) Source: https://context7.com/ronasit/axios-api-client/llms.txt This request interceptor checks if the JWT token is expired before making a request and automatically refreshes it. It requires configuration for the refresh route, authentication status, token expiration check, and the token refresh request itself. It integrates with the ApiService to apply the interceptor. ```typescript import { ApiService, tokenInterceptor, onRequestRefreshTokenInterceptor, AuthConfiguration, RefreshTokenInterceptorOptions } from '@ronas-it/axios-api-client'; const apiService = new ApiService('https://api.example.com'); // Auth state management let isAuthenticated = false; let accessToken: string | null = null; const authConfig: AuthConfiguration = { refreshTokenRoute: '/auth/refresh', unauthorizedRoutes: ['/auth/login', '/auth/register', '/auth/forgot-password'], logoutRoute: '/auth/logout' }; const refreshOptions: RefreshTokenInterceptorOptions = { configuration: authConfig, getIsAuthenticated: () => isAuthenticated, // Optional: custom token expiration check (uses JWT exp claim by default) getIsTokenExpired: () => { if (!accessToken) return true; // Custom expiration logic return false; }, runTokenRefreshRequest: async () => { const response = await apiService.post<{ token: string; ttl: number }>('/auth/refresh'); accessToken = response.token; return response.token; }, onError: async (error) => { console.error('Token refresh failed:', error); isAuthenticated = false; accessToken = null; await apiService.post('/auth/logout'); } }; apiService.useInterceptors({ request: [ [tokenInterceptor({ getToken: () => accessToken ?? '' })], [onRequestRefreshTokenInterceptor(refreshOptions)] ] }); // Token is automatically refreshed before requests if expired const data = await apiService.get('/protected-data'); ``` -------------------------------- ### Handle 401 Unauthorized Responses on Public Endpoints (TypeScript) Source: https://context7.com/ronasit/axios-api-client/llms.txt This response error interceptor handles 401 Unauthorized responses by executing a callback, typically for logging out the user, while specifically ignoring public endpoints. It requires a list of public endpoints and an `onError` callback function. The interceptor is added to the response interceptors of the ApiService. ```typescript import { ApiService, unauthorizedInterceptor } from '@ronas-it/axios-api-client'; const apiService = new ApiService('https://api.example.com'); const publicEndpoints = [ '/auth/login', '/auth/register', '/auth/forgot-password', '/auth/reset-password' ]; apiService.useInterceptors({ response: [ [ null, unauthorizedInterceptor({ publicEndpoints, onError: (error) => { console.log('Unauthorized access detected:', error?.response?.config.url); // Clear auth state and redirect localStorage.removeItem('token'); window.location.href = '/login'; } }) ] ] }); // 401 on public endpoints is ignored await apiService.post('/auth/login', { email: 'wrong@example.com', password: 'wrong' }); // Error is thrown but onError callback is NOT called // 401 on protected endpoints triggers onError await apiService.get('/protected/data'); // onError callback IS called, user is logged out ``` -------------------------------- ### Refresh JWT Token on 401 Response and Retry Request (TypeScript) Source: https://context7.com/ronasit/axios-api-client/llms.txt This response error interceptor handles 401 Unauthorized responses by refreshing the JWT token and automatically retrying the failed request. It requires configuration for authentication status, token refresh logic, and an error handler for failed refreshes. The interceptor is applied to the response pipeline of the ApiService. ```typescript import { ApiService, tokenInterceptor, onResponseRefreshTokenInterceptor, AuthConfiguration, RefreshTokenInterceptorOptions } from '@ronas-it/axios-api-client'; const apiService = new ApiService('https://api.example.com'); let isAuthenticated = true; let accessToken = 'initial-token'; const authConfig: AuthConfiguration = { refreshTokenRoute: '/auth/refresh', unauthorizedRoutes: ['/auth/login', '/auth/register'], logoutRoute: '/auth/logout' }; const refreshOptions: RefreshTokenInterceptorOptions = { configuration: authConfig, getIsAuthenticated: () => isAuthenticated, runTokenRefreshRequest: async () => { // This is called when a 401 is received const response = await apiService.post<{ token: string }>('/auth/refresh'); accessToken = response.token; return response.token; }, onError: async (error) => { // Called when refresh fails - typically logout the user isAuthenticated = false; accessToken = ''; window.location.href = '/login'; } }; apiService.useInterceptors({ request: [ [tokenInterceptor({ getToken: () => accessToken })] ], response: [ [null, onResponseRefreshTokenInterceptor(refreshOptions)] ] }); // If request returns 401, token is refreshed and request is automatically retried const userData = await apiService.get('/user/profile'); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.