/** * HTTP wire helpers shared by every client that talks to a Siteping * endpoint (widget `ApiClient`, dashboard `createEndpointSource`). * * One definition of the query-string encoding and the HTTP→typed-error * mapping — two clients implementing them independently already drifted * once (the dashboard forgot to serialize `statuses`), so they live here * now. */ import { SitepingError, SitepingNetworkError } from "./errors.js"; import type { FeedbackQuery } from "./types.js"; /** * A fresh `clientId` for a write the server dedupes a resend of — a feedback, * or a reply in a thread. */ export declare function newClientId(): string; /** * Encode a `FeedbackQuery` as the endpoint's expected query string. * Omitted/empty filters are not serialized; `statuses` uses the CSV form * the server's schema splits (`statuses=open,in_progress`). */ export declare function feedbackQueryToSearchParams(query: FeedbackQuery): URLSearchParams; /** * Merge caller-supplied `extra` headers over a client's `defaults` * (`Content-Type`, `Authorization` from `apiKey`). Header names are * case-insensitive, so a default spelled differently is dropped and the * explicit value replaces it — a plain object merge kept both, and fetch * joined them (`authorization: "Basic x"` over an apiKey went out as * "Bearer k, Basic x"). */ export declare function mergeRequestHeaders(defaults: Record, extra: Record | undefined): Record; /** * Append `params` to `endpoint`, which may already carry a query string * (`/api/siteping?tenant=acme`) or a fragment — naive `${endpoint}?${params}` * produced `?tenant=acme?projectName=…`, a 400. Plain string work, so * relative endpoints stay relative and nothing depends on `location`. */ export declare function withSearchParams(endpoint: string, params: URLSearchParams): string; /** * Map a non-OK `Response` to the appropriate typed error: * - 401 / 403 → `SitepingAuthError`, with its `status` * - other 4xx → `SitepingValidationError`, with its `status` * - 5xx (or anything else) → generic `SitepingError` (code `"SERVER"`) * * The response body is consumed via `.text()` so the caller keeps the * server-supplied message in the thrown error; `.text()` failures fall back * to `"Unknown error"` (kept verbatim — host apps grep for it). */ export declare function errorFromResponse(response: Response, label: string): Promise; /** * Whether a failed reply met a full thread — a store's `StoreLimitError`, or * a 409 (the endpoint's other 409, a clientId reused on another feedback, * never comes from clients that mint one per reply). Retrying won't help. */ export declare function isThreadFull(error: unknown): boolean; /** * Whether a failed reply delete found nothing to delete — a store's * `StoreNotFoundError`, or a 404: it is gone already. (Unlike * `isStoreNotFound`, no Prisma `P2025`: a browser source never meets one.) */ export declare function isCommentGone(error: unknown): boolean; /** * Normalise an exception thrown by `fetch` (or a timeout AbortController) * into a `SitepingNetworkError`. AbortErrors count as network failures — * in Siteping client code they always come from internal timeouts, never a * user-driven cancellation. */ export declare function networkErrorFromException(error: unknown, label: string): SitepingNetworkError;