// The Journal API client for pages and components. On the server it calls // the internal base (runtimeConfig.journal.apiBase) and forwards the visitor's // x-forwarded-for, plus the address of the peer that reached Nuxt, so the Go // rate limiter keeps one bucket per visitor instead of one for the Nuxt // server, also on route-cached renders. In the browser it calls the same-origin public base. The base is // always runtime config, never request input. import { createJournalClient, type JournalClient, type JournalFetcher } from '../utils/client.ts' export function useJournalApi(): JournalClient { const config = useRuntimeConfig() if (import.meta.server) { const base = (config.journal as { apiBase: string }).apiBase // Under route caching the request copy has no headers; the address the // layer's server/plugins/journal-client-address.ts recorded comes first. const event = useRequestEvent() const recorded = event?.context.journalForwardedFor as string | undefined const incoming = useRequestHeaders(['x-forwarded-for'])['x-forwarded-for'] const peer = event?.node?.req?.socket?.remoteAddress const forwarded = recorded || [incoming, peer].filter((v): v is string => typeof v === 'string' && v !== '').join(', ') const headers: Record = forwarded ? { 'x-forwarded-for': forwarded } : {} const fetcher: JournalFetcher = (path, query) => $fetch(path, { baseURL: base, query, headers }) return createJournalClient(fetcher) } const base = (config.public.journal as { apiBase: string }).apiBase const fetcher: JournalFetcher = (path, query) => $fetch(path, { baseURL: base, query }) return createJournalClient(fetcher) }