/** * Shared HTTP client types + request helpers for Host and standalone dev. * Keep body/query/timeout/response parsing in one place so implementations cannot drift. */ type HttpResponseKind = 'json' | 'text' | 'blob' | 'response'; type HttpQueryValue = string | number | boolean | undefined | null | Array; type HttpQuery = Record; interface HttpOptions { /** Extra request headers (wins over auto Content-Type) */ headers?: Record; /** Timeout in ms */ timeout?: number; /** Skip authentication (Host may omit Authorization / credentials) */ skipAuth?: boolean; /** Query string params; `undefined` / `null` values are skipped */ query?: HttpQuery; /** * Response parsing mode. Default `json`. * - `json` / `text` / `blob`: throw {@link HttpError} when `!response.ok` * - `response`: return the raw {@link Response} (caller checks status / headers) */ responseKind?: HttpResponseKind; /** AbortSignal; combined with `timeout` when both are set */ signal?: AbortSignal; /** * Override Content-Type for JSON/string bodies. * Ignored for FormData / Blob / URLSearchParams / ArrayBuffer (browser sets boundary). */ contentType?: string; } interface HttpClient { get: (url: string, options?: HttpOptions) => Promise; post: (url: string, body?: unknown, options?: HttpOptions) => Promise; put: (url: string, body?: unknown, options?: HttpOptions) => Promise; patch: (url: string, body?: unknown, options?: HttpOptions) => Promise; delete: (url: string, options?: HttpOptions) => Promise; } declare class HttpError extends Error { readonly status: number; readonly statusText: string; readonly response: Response; constructor(message: string, response: Response); } /** Bodies that must not be JSON.stringified and must not force Content-Type. */ declare function isRawHttpBody(body: unknown): body is FormData | Blob | URLSearchParams | ArrayBuffer | ArrayBufferView; declare function appendHttpQuery(url: string, query?: HttpQuery): string; declare function prepareHttpBody(body: unknown, contentType?: string): { body?: BodyInit; contentType?: string; }; /** Merge optional timeout with an outer AbortSignal into one signal. */ declare function createRequestAbort(timeout?: number, outer?: AbortSignal): { signal?: AbortSignal; cleanup: () => void; }; declare function parseHttpResponse(response: Response, kind?: HttpResponseKind): Promise; interface ExecuteHttpRequestArgs { method: string; body?: unknown; options?: HttpOptions; /** Platform/auth headers applied before options.headers */ headers?: Record; /** Extra fetch init (credentials, mode, …) */ requestInit?: Omit; fetch?: typeof globalThis.fetch; /** Invoked after fetch, before ok / parse (e.g. Host 401 handling) */ onResponse?: (response: Response) => void; } /** * Shared request pipeline: query → body → abort → fetch → (optional) ok check → parse. */ declare function executeHttpRequest(url: string, args: ExecuteHttpRequestArgs): Promise; export { type ExecuteHttpRequestArgs, type HttpClient, HttpError, type HttpOptions, type HttpQuery, type HttpQueryValue, type HttpResponseKind, appendHttpQuery, createRequestAbort, executeHttpRequest, isRawHttpBody, parseHttpResponse, prepareHttpBody };