import { userAgent } from '@nibling/sdk/user-agent'; declare const upstreamBrand: unique symbol; /** `fetch` that names us to the service it calls. Only `upstream()` makes one, so every dependency that * takes an `Upstream` (the router, the gateway, backfill, ingest, identity) cannot be handed a bare fetch. */ export type Upstream = ((input: string | URL | Request, init?: RequestInit) => Promise) & { readonly [upstreamBrand]: true }; /** Wraps `base` so every request carries the nibling User-Agent, with `contact` as the address in it. */ export function upstream(base: typeof fetch, contact?: string): Upstream { const ua = userAgent(contact); const wrapped = (input: string | URL | Request, init?: RequestInit) => { const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined)); headers.set('user-agent', ua); // workerd throws "Illegal invocation" when fetch is called as a method of another object. return base(input, { ...init, headers }); }; return wrapped as Upstream; }