UNPKG

starkon

Version:

Complete Next.js boilerplate with authentication, i18n & CLI - Create production-ready apps instantly

161 lines (143 loc) 3.77 kB
import { AxiosRequestConfig, InternalAxiosRequestConfig } from 'axios' // API Endpoints export const API_ENDPOINTS = { AUTH: { LOGIN: '/auth/login', REFRESH: '/auth/refresh', LOGOUT: '/auth/logout', REGISTER: '/auth/register', FORGOT_PASSWORD: '/auth/forgot-password', RESET_PASSWORD: '/auth/reset-password', VERIFY_EMAIL: '/auth/verify-email', RESEND_VERIFICATION: '/auth/resend-verification', ME: '/auth/me', PROFILE: '/auth/profile', CHANGE_PASSWORD: '/auth/change-password', }, USER: { PROFILE: '/user/profile', UPDATE: '/user/update', DELETE: '/user/delete', UPLOAD_AVATAR: '/user/avatar', }, POSTS: { LIST: '/posts', CREATE: '/posts', UPDATE: '/posts', DELETE: '/posts', }, } as const // HTTP Status Codes export const HTTP_STATUS = { OK: 200, CREATED: 201, NO_CONTENT: 204, BAD_REQUEST: 400, UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, CONFLICT: 409, UNPROCESSABLE_ENTITY: 422, TOO_MANY_REQUESTS: 429, INTERNAL_SERVER_ERROR: 500, BAD_GATEWAY: 502, SERVICE_UNAVAILABLE: 503, GATEWAY_TIMEOUT: 504, } as const // Error Codes export const ERROR_CODES = { TOKEN_EXPIRED: 'TOKEN_EXPIRED', INVALID_TOKEN: 'INVALID_TOKEN', NETWORK_ERROR: 'NETWORK_ERROR', VALIDATION_ERROR: 'VALIDATION_ERROR', SERVER_ERROR: 'SERVER_ERROR', RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED', PERMISSION_DENIED: 'PERMISSION_DENIED', RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND', } as const // Request Timeout export const REQUEST_TIMEOUT = { DEFAULT: 10000, UPLOAD: 30000, DOWNLOAD: 60000, LONG_RUNNING: 120000, } as const // Type Definitions export interface ApiResponse<T = any> { data: T message?: string success: boolean status: number } export interface ApiError { message: string status: number code?: string details?: any } export interface RefreshTokenResponse { token: string refreshToken: string expiresIn: number } export interface RequestConfig extends AxiosRequestConfig { skipAuth?: boolean skipErrorHandling?: boolean retryAttempts?: number showErrorToast?: boolean skipSuccessToast?: boolean skipErrorToast?: boolean skipCache?: boolean skipRetry?: boolean cacheTime?: number } // Request Queue for Token Refresh interface QueuedRequest { resolve: (value: any) => void reject: (error: any) => void config: InternalAxiosRequestConfig } class RequestQueueClass { private static instance: RequestQueueClass private isRefreshing = false private failedQueue: QueuedRequest[] = [] static getInstance(): RequestQueueClass { if (!RequestQueueClass.instance) { RequestQueueClass.instance = new RequestQueueClass() } return RequestQueueClass.instance } addToQueue(config: InternalAxiosRequestConfig): Promise<any> { return new Promise((resolve, reject) => { this.failedQueue.push({ resolve, reject, config }) }) } processQueue(error: any = null, token: string | null = null): void { this.failedQueue.forEach(({ resolve, reject, config }) => { if (error) { reject(error) } else if (token) { config.headers = config.headers || {} config.headers.Authorization = `Bearer ${token}` resolve(config) } else { reject(new Error('Token yenileme başarısız')) } }) this.failedQueue = [] } setRefreshing(status: boolean): void { this.isRefreshing = status } isRefreshingToken(): boolean { return this.isRefreshing } clearQueue(): void { this.failedQueue.forEach(({ reject }) => { reject(new Error('Request queue cleared')) }) this.failedQueue = [] this.isRefreshing = false } } export const RequestQueue = RequestQueueClass