@cuple/client
Functions
createClient()
createClient<
T>(config):Client<T, { }>
Defined in: packages/client/src/client.ts:3
Type Parameters
T
T extends RecursiveApi
Parameters
config
path
string
Returns
Client<T, { }>
cupleEndpointKey()
cupleEndpointKey(
endpoint):string
Defined in: packages/client/src/cache-key.ts:30
Identifies the route. JSON, not a joined string, because path is a URL.
Parameters
endpoint
AnyEndpointRef
Returns
string
cupleRequestKey()
cupleRequestKey(
endpoint,args): readonly [string,string,unknown]
Defined in: packages/client/src/cache-key.ts:18
Cache key of one call: [endpointKey, clientKey, input].
with({ middleware }) runs per request and what it returns never reaches the
key, so a client whose middleware varies needs with({ key }) to keep those
responses apart.
options (the RequestInit) is left out. It is transport configuration, not
request identity — the server never sees it — and it tends to hold values
like an AbortSignal that caches hash by identity, which would make the key
change on every render. Two calls differing only in credentials or cache
therefore share an entry; give them different with({ key }) if that matters.
Parameters
endpoint
AnyEndpointRef
args
unknown
Returns
readonly [string, string, unknown]
fetchCuple()
fetchCuple<
TEndpoint>(endpoint, ...args):CuplePromise<TEndpoint["tOutput"]>
Defined in: packages/client/src/client.ts:310
Sends one request. Like fetch, it resolves with whatever the server
answered — success, a 404, an invalid-body — typed as the route's
results, and rejects only when there was no answer:
| Outcome | Rejects with |
|---|---|
| No response: unreachable, DNS, CORS | CupleTransportError |
| Body is not JSON: proxy HTML, gateway page | CupleTransportError (statusCode) |
options.signal aborted | DOMException (name: "AbortError") |
Narrow it on the promise: .thenKeepSuccess() for just the data,
.thenReject(["unexpected-error"]) to send results nobody handles where
unhandled errors go. Rejected results throw CupleUnexpectedResponseError.
See CuplePromise. The HTTP status is never interpreted: it is
copied onto the result as statusCode, and which result goes with which
status is the server's choice, set by apiResponse.
A non-JSON body is always an error here — fetchCuple only speaks Cuple's
envelope. For downloads, streams and any other custom response, define the
route with getRaw/postRaw/… on the server and call it with plain fetch;
raw routes are not part of the client API. (Raw request bodies are fine:
pass an ArrayBuffer, Blob, Uint8Array or ReadableStream as body.)
Type Parameters
TEndpoint
TEndpoint extends ClientEndpointRef
Parameters
endpoint
TEndpoint
args
...FetchCupleArgs<TEndpoint>
Returns
CuplePromise<TEndpoint["tOutput"]>
fetchCupleSSE()
fetchCupleSSE<
TEndpoint>(endpoint, ...args):CuplePromise<TEndpoint["tOutput"]>
Defined in: packages/client/src/client.ts:405
Type Parameters
TEndpoint
TEndpoint extends ClientSSEEndpointRef
Parameters
endpoint
TEndpoint
args
...FetchCupleSSEArgs<TEndpoint>
Returns
CuplePromise<TEndpoint["tOutput"]>
transportErrorResult()
transportErrorResult(
error):TransportErrorResult
Defined in: packages/client/src/client.ts:61
Parameters
error
Returns
Classes
CuplePromise
Defined in: packages/client/src/client.ts:115
A request's result. Like fetch, it resolves with every response the
server sent, and rejects when there was none: a network failure as
CupleTransportError, an abort as AbortError. Narrow it with:
| Method | Resolves with |
|---|---|
| (default) | every result the server sent |
.thenKeepSuccess() | success |
.thenKeep([...]) | exactly the listed results; "success" isn't implied |
.thenKeepAlso([...]) | what it resolved with so far, plus the listed results |
.thenReject([...]) | every result the server sent, except the listed ones |
.thenRejectAlso([...]) | what it resolved with so far, minus the listed results |
.thenKeepAll() | every result, plus transport-error and abort |
Results it doesn't keep reject as CupleUnexpectedResponseError.
List "transport-error" or "abort" to keep them as values.
Each method starts from the response again, so they chain in any order.
Extends
Promise<TValue>
Type Parameters
TAll
TAll extends object
TValue
TValue = TAll
Accessors
[species]
Get Signature
get
static[species]():PromiseConstructor
Defined in: packages/client/src/client.ts:121
Returns
PromiseConstructor
Overrides
Promise.[species]
Constructors
Constructor
new CuplePromise<
TAll,TValue>(executor):CuplePromise<TAll>
Defined in: docs/node_modules/typescript/lib/lib.es2015.promise.d.ts:31
Creates a new Promise.
Parameters
executor
(resolve, reject) => void
A callback used to initialize the promise. This callback is passed two arguments: a resolve callback used to resolve the promise with a value or the result of another promise, and a reject callback used to reject the promise with a provided reason or error.
Returns
CuplePromise<TAll>
Inherited from
Promise<TValue>.constructor
Methods
thenKeep()
thenKeep<
TResult>(results):CuplePromise<TAll,Listed<TAll,TResult>>
Defined in: packages/client/src/client.ts:185
Resolve with exactly the listed results. The list is complete:
thenKeep(["order-not-found"]) rejects a success too.
"transport-error" and "abort" can be listed too: a network failure then
resolves as { result: "transport-error", statusCode, message }, an abort
as { result: "abort", statusCode: null, message }.
Type Parameters
TResult
TResult extends string
Parameters
results
readonly TResult[]
Returns
CuplePromise<TAll, Listed<TAll, TResult>>
thenKeepAll()
thenKeepAll():
CuplePromise<TAll,TransportErrorResult|AbortResult|TAll>
Defined in: packages/client/src/client.ts:241
Resolve with everything: every result the server sent, plus
transport-error and abort. Only a bug in your own code rejects.
Returns
CuplePromise<TAll, TransportErrorResult | AbortResult | TAll>
thenKeepAlso()
thenKeepAlso<
TResult>(results):CuplePromise<TAll,TValue|Listed<TAll,TResult>>
Defined in: packages/client/src/client.ts:201
Also resolve with the listed results:
thenKeepSuccess().thenKeepAlso(["invalid-body"]) resolves with
success | invalid-body. Mostly for "transport-error" and "abort",
which reject unless listed.
Type Parameters
TResult
TResult extends string
Parameters
results
readonly TResult[]
Returns
CuplePromise<TAll, TValue | Listed<TAll, TResult>>
thenKeepSuccess()
thenKeepSuccess():
CuplePromise<TAll,Extract<TAll, {result:"success"; }>>
Defined in: packages/client/src/client.ts:169
Resolve with success only; anything else rejects. For code that wants
the data: const { post } = await fetchCuple(...).thenKeepSuccess().
Returns
CuplePromise<TAll, Extract<TAll, { result: "success"; }>>
thenReject()
thenReject<
TResult>(results):CuplePromise<TAll,Exclude<TAll, {result:TResult; }>>
Defined in: packages/client/src/client.ts:216
Resolve with every result the server sent, except the listed ones, which
reject: thenReject(["unexpected-error"]) sends a 500 where unhandled
errors go. A network failure or an abort still rejects.
Type Parameters
TResult
TResult extends string
Parameters
results
readonly TResult[]
Returns
CuplePromise<TAll, Exclude<TAll, { result: TResult; }>>
thenRejectAlso()
thenRejectAlso<
TResult>(results):CuplePromise<TAll,Exclude<TValue, {result:TResult; }>>
Defined in: packages/client/src/client.ts:227
Also reject the listed results: what it resolved with so far, minus these.
Type Parameters
TResult
TResult extends string
Parameters
results
readonly TResult[]
Returns
CuplePromise<TAll, Exclude<TValue, { result: TResult; }>>
of()
staticof<TAll,TValue>(response,keep?):CuplePromise<TAll,TValue>
Defined in: packages/client/src/client.ts:129
response is everything the server answered; keep says what resolves.
Type Parameters
TAll
TAll extends object
TValue
TValue = TAll
Parameters
response
Promise<TAll>
keep?
Keep = ...
Returns
CuplePromise<TAll, TValue>
CupleTransportError
Defined in: packages/client/src/client.ts:35
The server did not answer in Cuple's format: it was unreachable (DNS, CORS,
offline), or it answered with a body that is not JSON (a proxy's HTML error
page). The original error is kept as cause.
A bug in your own code never produces this, so it is safe to treat as "retry later" rather than "report".
Extends
Error
Constructors
Constructor
new CupleTransportError(
message,options):CupleTransportError
Defined in: packages/client/src/client.ts:42
Parameters
message
string
options
cause
unknown
statusCode?
number | null
Returns
Overrides
Error.constructor
Properties
cause
readonlycause:unknown
Defined in: packages/client/src/client.ts:38
What failed underneath: fetch's TypeError, or the JSON SyntaxError.
Overrides
Error.cause
name
name:
string="CupleTransportError"
Defined in: packages/client/src/client.ts:36
Overrides
Error.name
statusCode
readonlystatusCode:number|null
Defined in: packages/client/src/client.ts:40
The HTTP status, when a response arrived but its body was not JSON.
CupleUnexpectedResponseError
Defined in: packages/client/src/client.ts:17
Extends
Error
Constructors
Constructor
new CupleUnexpectedResponseError(
response?):CupleUnexpectedResponseError
Defined in: packages/client/src/client.ts:19
Parameters
response?
message?
string
result?
string
statusCode?
number
Returns
Overrides
Error.constructor
Properties
response?
optionalresponse?:object
Defined in: packages/client/src/client.ts:20
message?
optionalmessage?:string
result?
optionalresult?:string
statusCode?
optionalstatusCode?:number
statusCode
statusCode:
number|null
Defined in: packages/client/src/client.ts:18
Type Aliases
AbortResult
AbortResult =
object
Defined in: packages/client/src/client.ts:70
An aborted request, as a result: list "abort" in thenKeepAlso/thenKeep.
Properties
message
message:
string
Defined in: packages/client/src/client.ts:70
result
result:
"abort"
Defined in: packages/client/src/client.ts:70
statusCode
statusCode:
null
Defined in: packages/client/src/client.ts:70
Client
Client<
TApi,TPreloadedData> =MapApi<TApi,TPreloadedData> &NonNullable<unknown> extendsTPreloadedData?object:NonNullable<unknown>
Defined in: packages/client/src/client.ts:550
Type Parameters
TApi
TApi extends RecursiveApi
TPreloadedData
TPreloadedData = NonNullable<unknown>
ClientEndpointRef
ClientEndpointRef =
object
Defined in: packages/client/src/client.ts:258
Properties
_sse?
optional_sse?:never
Defined in: packages/client/src/client.ts:262
clientProps
clientProps:
ClientProps
Defined in: packages/client/src/client.ts:263
tInput
tInput:
Record<string,unknown>
Defined in: packages/client/src/client.ts:259
tMethod
tMethod:
any
Defined in: packages/client/src/client.ts:261
tOutput
tOutput:
any
Defined in: packages/client/src/client.ts:260
ClientProps
ClientProps =
object
Defined in: packages/client/src/map-api.ts:26
Properties
finalware?
optionalfinalware?: (response) =>unknown|Promise<unknown>
Defined in: packages/client/src/map-api.ts:46
Runs after every response, set by client.with({ finalware }). Its return
value replaces the response; the declared types do not follow it.
Parameters
response
any
Returns
unknown | Promise<unknown>
key?
optionalkey?:string| (() =>string)
Defined in: packages/client/src/map-api.ts:41
Identifies what middleware injects, set by client.with({ key }). Cache
integrations put it in the cache key, so responses that differ only by
injected data are never mixed up. Either a string or a synchronous getter
— the key has to be buildable during render, before any request runs.
method
method:
any
Defined in: packages/client/src/map-api.ts:27
middleware?
optionalmiddleware?: () =>any
Defined in: packages/client/src/map-api.ts:34
Runs before every request, set by client.with({ middleware }). What it
returns is merged into the request data.
Returns
any
path
path:
any
Defined in: packages/client/src/map-api.ts:29
segments
segments:
any
Defined in: packages/client/src/map-api.ts:28
ClientSSEEndpointRef
ClientSSEEndpointRef =
object
Defined in: packages/client/src/client.ts:392
Properties
_sse
_sse:
true
Defined in: packages/client/src/client.ts:396
clientProps
clientProps:
ClientProps
Defined in: packages/client/src/client.ts:397
tInput
tInput:
Record<string,unknown>
Defined in: packages/client/src/client.ts:393
tMethod
tMethod:
any
Defined in: packages/client/src/client.ts:395
tOutput
tOutput:
any
Defined in: packages/client/src/client.ts:394
CupleResult
CupleResult<
TEndpoint> =TEndpoint["tOutput"]
Defined in: packages/client/src/client.ts:267
Everything an endpoint can resolve to.
Type Parameters
TEndpoint
TEndpoint extends ClientEndpointRef
CupleResultOf
CupleResultOf<
TEndpoint,TResult> =Extract<CupleResult<TEndpoint>, {result:TResult; }>
Defined in: packages/client/src/client.ts:276
One named case, e.g. CupleResultOf<typeof e, "notFound">.
Type Parameters
TEndpoint
TEndpoint extends ClientEndpointRef
TResult
TResult extends string
CupleSuccess
CupleSuccess<
TEndpoint> =Extract<CupleResult<TEndpoint>, {result:"success"; }>
Defined in: packages/client/src/client.ts:270
Just the successful case: what thenKeepSuccess() resolves with.
Type Parameters
TEndpoint
TEndpoint extends ClientEndpointRef
CupleWithOptions
CupleWithOptions<
TParams> =object
Defined in: packages/client/src/client.ts:506
Options for client.with(..).
The two fields are deliberately separate concerns: data is about the
request, key is about the cache. A cookie-authenticated app needs only
key; a static API-key client needs only data.
Type Parameters
TParams
TParams
Properties
finalware?
optionalfinalware?: (response) =>unknown|Promise<unknown>
Defined in: packages/client/src/client.ts:547
Runs after every response this client receives, before it is handed back.
For the cross-cutting work that has to happen whether or not a hook is involved: redirecting on an expired session, reporting failures. Throwing from here turns a result into an exception, which is how a redirect works.
Returning a value replaces the response; returning nothing keeps it.
The types do not follow it. A replaced response still has the endpoint's declared type, because the response type is fixed by the route definition and there is no way to thread a per-client transformation back through it. Reshaping data here will lie to every caller — observe, throw, or narrow by hand at the call site.
Parameters
response
any
Returns
unknown | Promise<unknown>
key?
optionalkey?:string| (() =>string)
Defined in: packages/client/src/client.ts:531
Identifies what middleware injects, for cache integrations.
middleware runs per request, so nothing it returns reaches the cache
key: two calls that differ only in what it injected would share one entry.
This is how a cache tells them apart. Most often that is who the request is
for, but it is whatever the middleware actually varies by — a tenant, a
locale, an API version.
Key what the response depends on, not the injected bytes. A refreshed token is new data but the same identity; a key that moved with it would discard the cache on every refresh and orphan pending invalidations.
A getter must be synchronous, since the key is built during render. It is read on each render, so whatever it reads has to live somewhere that re-renders the tree — otherwise pass a plain string and build one client per value.
middleware?
optionalmiddleware?: () =>Promise<TParams> |TParams
Defined in: packages/client/src/client.ts:512
Runs before every request this client sends; what it returns is merged into the request data, under the per-call options. Awaited at fetch time, so it can refresh a token.
Returns
Promise<TParams> | TParams
FetchCupleArgs
FetchCupleArgs<
TEndpoint> =objectextendsTEndpoint["tInput"] ? [Merge<TEndpoint["tInput"],GenericOptions>] : [Merge<TEndpoint["tInput"],GenericOptions>]
Defined in: packages/client/src/client.ts:281
Type Parameters
TEndpoint
TEndpoint extends ClientEndpointRef
FetchCupleSSEArgs
FetchCupleSSEArgs<
TEndpoint> =objectextendsTEndpoint["tInput"] ? [Merge<TEndpoint["tInput"],GenericOptions>] : [Merge<TEndpoint["tInput"],GenericOptions>]
Defined in: packages/client/src/client.ts:400
Type Parameters
TEndpoint
TEndpoint extends ClientSSEEndpointRef
MapApi
MapApi<
TApi,TPreloadedData> ={ [Key in keyof TApi]: TApi[Key] extends { tInput: infer TInput; tMethod: infer TMethod extends string } ? AlterEndpoint<TApi[Key], TInput, TMethod, TPreloadedData> : MapApi<TApi[Key], TPreloadedData> }
Defined in: packages/client/src/map-api.ts:2
Exclude data set with .with() for the whole API
Type Parameters
TApi
TApi
TPreloadedData
TPreloadedData
RecursiveApi
RecursiveApi = { [Key in string]: { _handler: (req: any, res: any) => void; _method: any; tInput: any; tMethod: any; tOutput: any } | RecursiveApi }
Defined in: packages/client/src/client.ts:487
TransportErrorResult
TransportErrorResult =
object
Defined in: packages/client/src/client.ts:55
A network failure as a result, for code that handles it as a value: list
"transport-error" in thenKeepAlso/thenKeep (or resolveAlso on a
read). statusCode is set when a response arrived but wasn't Cuple's (a
proxy's error page); null when there was no response at all.
Properties
message
message:
string
Defined in: packages/client/src/client.ts:58
result
result:
"transport-error"
Defined in: packages/client/src/client.ts:56
statusCode
statusCode:
number|null
Defined in: packages/client/src/client.ts:57