import Settings from 'settings'; import logger from '../utils/log'; import { headers, cookies } from 'next/headers'; import { ServerVariables } from './server-variables'; export enum FetchResponseType { JSON = 'json', TEXT = 'text' } const appFetch = async ({ url, locale, currency, init = {}, responseType = FetchResponseType.JSON }: { url: RequestInfo; locale: string; currency: string; init?: RequestInit; responseType?: FetchResponseType; }): Promise => { let response: T; let status: number; let ip = ''; try { const nextHeaders = headers(); const nextCookies = cookies(); ip = nextHeaders.get('x-forwarded-for') ?? ''; const commerceUrl = Settings.commerceUrl; const currentLocale = Settings.localization.locales.find( (l) => l.value === locale ); if (commerceUrl === 'default') { logger.error('Commerce URL is not set. Current value is "default"'); return undefined; } const requestURL = `${decodeURIComponent(commerceUrl)}${url}`; init.headers = { ...(init.headers ?? {}), ...(ServerVariables.globalHeaders ?? {}), 'Accept-Language': currentLocale.apiValue, 'x-currency': currency, 'x-forwarded-for': ip, cookie: nextCookies.toString() }; init.next = { revalidate: Settings.usePrettyUrlRoute ? 0 : 60 }; logger.debug(`FETCH START ${url}`, { requestURL, init, ip }); const req = await fetch(requestURL, init); status = req.status; logger.debug(`FETCH END ${url}`, { status: req.status, ip }); if (responseType === FetchResponseType.JSON) { response = (await req.json()) as T; } else { response = (await req.text()) as unknown as T; } logger.trace(`FETCH RESPONSE`, { url, response, ip }); } catch (error) { const logType = status === 500 ? 'fatal' : 'error'; if (!url.toString().includes('/cms/seo/')) { logger[logType](`FETCH FAILED`, { url, status, error, ip }); } } return response; }; export default appFetch;