import { router } from 'expo-router' import * as SecureStore from 'expo-secure-store' interface FetchLoggerOptions { enableLogging?: boolean; logRequest?: boolean; logResponse?: boolean; logError?: boolean; } const defaultOptions: FetchLoggerOptions = { enableLogging: __DEV__, logRequest: true, logResponse: true, logError: true, }; const originalFetch = global.fetch; export const createFetchWithLogger = (options: FetchLoggerOptions = {}) => { const config = { ...defaultOptions, ...options }; return async (input: RequestInfo | URL, init?: RequestInit): Promise => { const startTime = Date.now(); const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url; const method = init?.method || 'GET'; try { const token = await SecureStore.getItemAsync('token'); if (token) { init = { ...init, headers: { ...init?.headers, 'authorization': `Bearer ${token}`, }, }; } const response = await originalFetch(input, init); if (response.status === 401) { console.warn('πŸ” 401 ζœͺζŽˆζƒοΌŒθ·³θ½¬εˆ°η™»ε½•ι‘΅') router.replace('/auth') } return response; } catch (error) { const duration = Date.now() - startTime; if (config.enableLogging && config.logError) { console.group(`❌ [FETCH ι”™θ――] ${method} ${url}`); console.error('πŸ“ URL:', url); console.error('πŸ”§ Method:', method); console.error('⏱️ Duration:', `${duration}ms`); if (init?.headers) { console.error('πŸ“‹ Request Headers:', JSON.stringify(init.headers, null, 2)); } if (init?.body) { try { const bodyContent = typeof init.body === 'string' ? init.body : JSON.stringify(init.body); console.error('πŸ“¦ Request Body:', bodyContent); } catch (e) { console.error('πŸ“¦ Request Body: [ζ— ζ³•εΊεˆ—εŒ–]'); } } console.error('πŸ’₯ Error Type:', error?.constructor?.name || 'Unknown'); console.error('πŸ’₯ Error Message:', error instanceof Error ? error.message : String(error)); if (error instanceof Error && error.stack) { console.error('πŸ“š Stack Trace:', error.stack); } if (error && typeof error === 'object') { console.error('πŸ” Error Details:', JSON.stringify(error, Object.getOwnPropertyNames(error), 2)); } console.groupEnd(); } throw error; } }; }; export const fetchWithLogger = createFetchWithLogger(); export const setupGlobalFetchLogger = (options?: FetchLoggerOptions) => { const loggedFetch = createFetchWithLogger(options); global.fetch = loggedFetch as typeof fetch; return () => { global.fetch = originalFetch; }; };