Plugins & fluent API
Use tree-shakable subpaths so bundlers include only what you need:
@hamdymohamedak/openfetch/plugins—retry,timeout,hooks,debug,strictFetch@hamdymohamedak/openfetch/sugar—createFluentClient(fluent URL chains)
See Getting started — Subpath imports for import examples, Configuration for request options, Retry & cache for retry and cache middleware, Interceptors & middleware for stack order with use(), and Features & request pipeline for how plugins sit in the full stack.
Plugins (@hamdymohamedak/openfetch/plugins)
| Export | Role |
|---|---|
retry(options?) | Wraps createRetryMiddleware with an attempts alias for maxAttempts. |
timeout(ms) | Per-request timeout middleware (sets timeout on ctx.request). |
hooks({ … }) | Single middleware: onRequest / onResponse / onError around next(), plus onBeforeRetry and onAfterResponse merged into ctx.request.retry (same semantics as OpenFetchRetryOptions). |
debug(options?) | Middleware: structured request / response / error phases (masking headers, redacting URLs). Distinct from createClient({ debug, logger }) — see Debugging. |
strictFetch() | Sets redirect: "error" when unset so redirects are not followed silently. |
hooks and retry
When you combine hooks({ onBeforeRetry, onAfterResponse }) with createRetryMiddleware / retry():
onBeforeRetryruns after a failed attempt, before backoff, when another attempt may still run.onAfterResponseruns after a successfulnext()producedctx.response(i.e. after fulldispatch, includingtransformResponse). ThrowOpenFetchForceRetry(exported from the main package) fromonAfterResponseto force another fetch attempt inside the retry loop.
Order reminder: register retry so it wraps the stack you want retried; hooks is usually outside retry if you want onRequest once per client call (see Interceptors & middleware).
Fluent API (@hamdymohamedak/openfetch/sugar)
ts
import { createFluentClient } from "@hamdymohamedak/openfetch/sugar";
const api = createFluentClient({ baseURL: "https://api.example" });
// Terminals start one HTTP request each (unless using .memo()).
const data = await api("/users").get().json();
const text = await api("/health").text();.json()—unwrapResponse+responseType: "json"..json(schema)— same, plus Standard Schema validation (throwsSchemaValidationErroron failure), equivalent to passingjsonSchemaon the config..text()/.blob()/.arrayBuffer()/.stream()/.raw()/.send()— see source typings forRequestChain..memo()— buffers one raw response for multiple terminals on the same chain (not a general HTTP cache).
The callable client also exposes use, interceptors, defaults, and the imperative get / post / … methods from createClient.
