buildURL
v0.0.1Appends serialised query parameters to a URL string Null and undefined values are omitted. Existing query strings are preserved.
Signature
export function buildURL(
url: string,
query: Record<string, string | number | boolean | null | undefined>,
): string{ ... }Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
url | string | — | Base URL (may already contain a query string) |
query | Record<string, string | number | boolean | null | undefined> | — | Base URL (may already contain a query string) |
Returns
stringURL with query stringRelated Types
$Fetch
The main fetch interface with method shortcuts, raw access, and factory methods
interface $Fetch<Plugins extends readonly FetchPlugin[] = []>| Property | Type | Default | Description |
|---|---|---|---|
native | typeof fetch | — | Access to the underlying native fetch function |
FetchOptions
Options for a fetch request, extending native RequestInit with additional features
interface FetchOptions<R extends ResponseType = 'json', T = unknown> extends Omit<RequestInit, 'body'>, FetchHooks<T, R>| Property | Type | Default | Description |
|---|---|---|---|
baseURL? | string | undefined | — | Base URL prepended to all relative request URLs |
body? | BodyInit | Record<string, unknown> | unknown[] | null | undefined | — | Request body — plain objects are automatically JSON-serialized |
ignoreResponseError? | boolean | undefined | — | Suppress throwing on 4xx/5xx responses |
query? | Record<string, string | number | boolean | null | undefined> | undefined | — | URL query parameters serialized and appended to the request URL |
params? | Record<string, string | number | boolean | null | undefined> | undefined | — | — |
parseResponse? | ((responseText: string) => T) | undefined | — | Custom response parser — overrides built-in JSON.parse |
responseType? | R | undefined | — | Expected response format — drives body parsing |
duplex? | "half" | undefined | — | Enable duplex streaming. Automatically set to "half" when a ReadableStream is used as body. |
timeout? | number | undefined | — | Request timeout in milliseconds. Uses AbortSignal.timeout internally. |
retry? | number | false | undefined | — | Number of retry attempts on failure, or false to disable. Defaults to 1 for non-payload methods. |
retryDelay? | number | ((context: FetchContext<T, R>) => number) | undefined | — | Delay in milliseconds between retries, or a function receiving the context |
retryStatusCodes? | readonly number[] | undefined | — | HTTP status codes that trigger a retry. Defaults to [408, 409, 425, 429, 500, 502, 503, 504]. |
ResolvedFetchOptions
FetchOptions after merging defaults — headers are always a Headers instance
interface ResolvedFetchOptions<R extends ResponseType = 'json', T = unknown> extends FetchOptions<R, T>| Property | Type | Default | Description |
|---|---|---|---|
headers | Headers | — | — |
CreateFetchOptions
Global options for createFetch
interface CreateFetchOptions<Plugins extends readonly FetchPlugin[] = []>| Property | Type | Default | Description |
|---|---|---|---|
defaults? | (FetchOptions<"json", unknown> & MergePluginOptions<Plugins>) | undefined | — | Default options merged into every request |
fetch? | typeof fetch | undefined | — | Custom fetch implementation — defaults to globalThis.fetch |
plugins? | Plugins | undefined | — | Plugins composed once at createFetch time. Each plugin may contribute defaults, lifecycle hooks, and typed option fields. |
FetchPlugin
A reusable bundle of defaults and lifecycle hooks that extends a fetch instance. Plugins are composed once at `createFetch` time — their defaults and hooks are flattened into the instance closure, so attaching plugins adds zero per-request overhead beyond the contributed hooks themselves.
interface FetchPlugin<Name extends string = string, OptionsExt = unknown, ContextExt = unknown>| Property | Type | Default | Description |
|---|---|---|---|
namereadonly | Name | — | Plugin identifier |
defaults?readonly | FetchOptions<"json", unknown> | undefined | — | Default options contributed by the plugin — merged under user defaults |
hooks?readonly | FetchHooks<unknown, "json"> | undefined | — | Lifecycle hooks executed before any user per-request hooks |
execute?readonly | FetchExecuteMiddleware | undefined | — | Onion-style middleware wrapping the fetch attempt + response parse. Plugins compose in registration order; calling `next()` invokes the next middleware or ultimately the core executor. May call `next()` multiple times (e.g. to implement retries). |
setup?readonly | ((context: { readonly defaults: FetchOptions; }) => void) | undefined | — | Invoked once per createFetch, after all plugin defaults are merged |
__types?readonly | { options: OptionsExt; context: ContextExt; } | undefined | — | Phantom marker for type-only option/context extensions — never present at runtime. Populated via dummy field in `definePlugin` generics. |
FetchContext
Mutable context object passed to all hooks and the core fetch pipeline
interface FetchContext<T = unknown, R extends ResponseType = 'json'>| Property | Type | Default | Description |
|---|---|---|---|
request | FetchRequest | — | — |
options | ResolvedFetchOptions<R, T> | — | — |
response? | FetchResponse<T> | undefined | — | — |
error? | Error | undefined | — | — |
FetchHooks
Lifecycle hooks for the fetch pipeline
interface FetchHooks<T = unknown, R extends ResponseType = 'json'>| Property | Type | Default | Description |
|---|---|---|---|
onRequest? | any | — | Called before the request is sent |
onRequestError? | any | — | Called when the request itself throws (e.g. network error, timeout) |
onResponse? | any | — | Called after a successful response is received and parsed |
onResponseError? | any | — | Called when the response status is 4xx or 5xx |
ResponseMap
Maps response type keys to their parsed value types
interface ResponseMap| Property | Type | Default | Description |
|---|---|---|---|
blob | Blob | — | — |
text | string | — | — |
arrayBuffer | ArrayBuffer | — | — |
stream | ReadableStream<Uint8Array<ArrayBufferLike>> | — | — |
FetchResponse
Extended Response with a parsed `_data` field
interface FetchResponse<T> extends Response| Property | Type | Default | Description |
|---|---|---|---|
_data? | T | undefined | — | — |
IFetchError
Shape of errors thrown by $fetch
interface IFetchError<T = unknown> extends Error| Property | Type | Default | Description |
|---|---|---|---|
request? | FetchRequest | undefined | — | — |
options? | FetchErrorOptions | undefined | — | — |
response? | FetchResponse<T> | undefined | — | — |
data? | T | undefined | — | — |
status? | number | undefined | — | — |
statusText? | string | undefined | — | — |
statusCode? | number | undefined | — | — |
statusMessage? | string | undefined | — | — |
FetchExecuteMiddleware
Onion-style wrapper around a single fetch attempt. Invoking `next()` delegates to the next middleware in the chain or, at the innermost layer, performs the actual `fetch` call and response body parsing. `context.response` / `context.error` are populated by the time `next()` resolves. Middlewares may call `next()` zero, one, or many times (retries).
export type FetchExecuteMiddleware = (
context: FetchContext,
next: () => Promise<void>,
) => Promise<void>;MergePluginOptions
Intersection of all `OptionsExt` carried by a plugin tuple. Empty tuple resolves to `unknown`.
export type MergePluginOptions<Plugins extends readonly FetchPlugin[]>
= [Plugins[number]] extends [never]
? unknown
: UnionToIntersection<PluginOptionsOf<Plugins[number]>>;MergePluginContext
Intersection of all `ContextExt` carried by a plugin tuple. Empty tuple resolves to `unknown`.
export type MergePluginContext<Plugins extends readonly FetchPlugin[]>
= [Plugins[number]] extends [never]
? unknown
: UnionToIntersection<PluginContextOf<Plugins[number]>>;FetchHook
A function invoked at a specific point in the fetch lifecycle
export type FetchHook<C = FetchContext> = (context: C) => MaybePromise<void>;ResponseType
Supported response body parsing modes
export type ResponseType = keyof ResponseMap | 'json';MappedResponseType
Resolves the response value type from a ResponseType key
export type MappedResponseType<R extends ResponseType, T = unknown> = R extends keyof ResponseMap
? ResponseMap[R]
: T;FetchErrorOptions
Subset of FetchOptions stored on FetchError — strips lifecycle hooks, parseResponse, and retryDelay callback that are invariant in T/R
export type FetchErrorOptions = Omit<
FetchOptions<ResponseType>,
keyof FetchHooks | 'parseResponse' | 'retryDelay'
>;Fetch
The native fetch function signature
export type Fetch = typeof globalThis.fetch;FetchRequest
A fetch request — URL string, URL object, or Request object
export type FetchRequest = string | URL | Request;