@calternal/api-client
Typed shared HTTP transport; #484 adds bounded generated file/event codecs and explicit empty-response statuses. Empty 202/204 replies are shared transport semantics; all other JSON parsing stays strict. Failure envelopes and Retry-After survive the SPA/WebMCP boundary (#835). Browser 401 replies notify session owners without buffering streamed bodies; session epochs prevent stale replies (#555). Credentials and route authorization remain the server’s responsibility (DESIGN §§41, 48). Binary tool responses reserve room for base64 expansion within the shared 1 MiB result limit (#760).
Classes
Section titled “Classes”ApiError
Section titled “ApiError”Keep status, server details and Retry-After through SPA and WebMCP failures (#835, DESIGN §41).
Extends
Section titled “Extends”Error
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new ApiError(
status,code,message,details?,payload?,retryAfter?):ApiError
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
status |
number |
code |
"bad_request" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "name_conflict_case" | "name_too_long" | "push_endpoint_rejected" | "too_many_requests" | "internal" | "service_unavailable" |
message |
string |
details? |
Record<string, string> | null |
payload? |
unknown |
retryAfter? |
string | null |
Returns
Section titled “Returns”Overrides
Section titled “Overrides”Error.constructor
Properties
Section titled “Properties”
readonlycode:"bad_request"|"unauthorized"|"forbidden"|"not_found"|"conflict"|"name_conflict_case"|"name_too_long"|"push_endpoint_rejected"|"too_many_requests"|"internal"|"service_unavailable"
details
Section titled “details”
readonlydetails:Record<string,string> |null|undefined
payload
Section titled “payload”
readonlypayload:unknown
The complete decoded failure body, including future envelope fields (#835).
retryAfter
Section titled “retryAfter”
readonlyretryAfter:string|null
A server delay hint, without enabling an automatic write replay (#835).
status
Section titled “status”
readonlystatus:number
Type Aliases
Section titled “Type Aliases”ApiErrorCode
Section titled “ApiErrorCode”ApiErrorCode =
components["schemas"]["ErrorCode"]
ApiErrorEnvelope
Section titled “ApiErrorEnvelope”ApiErrorEnvelope =
components["schemas"]["ErrorEnvelope"]
ApiRequestOptions
Section titled “ApiRequestOptions”ApiRequestOptions<
Operation> =object&ParamOptions<Operation> &BodyOptions<Operation>
Type Declaration
Section titled “Type Declaration”| Name | Type | Description |
|---|---|---|
baseUrl? |
string |
Base URL for a server or test environment. |
cache? |
RequestCache |
Native fetch cache policy; no-store bypasses GET coalescing too. |
emptyResponseStatuses? |
readonly number[] |
Additional successful statuses whose contract permits an empty body (#484). |
headers? |
HeadersInit |
Extra request headers. |
maxBytes? |
number |
- |
pollMs? |
number |
- |
requestContentType? |
string | null |
- |
requestEncoding? |
"json" | "text" | "base64" | "none" |
Generated tool transport (#484); ordinary API calls keep strict JSON. |
responseEncoding? |
"json" | "text" | "base64" | "sse" |
- |
signal? |
AbortSignal |
Cancel this request. |
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
Operation |
ApiResponse
Section titled “ApiResponse”ApiResponse<
Operation> =Operationextendsobject?ResponseBody<Responses> :never
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
Operation |
Variables
Section titled “Variables”TIMEZONE_HEADER
Section titled “TIMEZONE_HEADER”
constTIMEZONE_HEADER:"X-Calternal-Timezone"="X-Calternal-Timezone"
The header that carries the active User IANA zone. Before a confirmed travel
switch, this is the device zone. The server takes every day key (“today”, a
Daily note, date:today) from it, never from UTC (#141).
Functions
Section titled “Functions”apiErrorFromResponse()
Section titled “apiErrorFromResponse()”apiErrorFromResponse(
status,payload,retryAfter?):ApiError
Preserve server error fields and delay hints without replaying a write (#835, DESIGN §41).
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
status |
number |
payload |
unknown |
retryAfter? |
string | null |
Returns
Section titled “Returns”apiFetch()
Section titled “apiFetch()”apiFetch<
P,M>(path,method, …__namedParameters):Promise<ApiResponse<OperationAt<P,M>>>
Make one credentialed JSON API request. It carries the active User zone and treats empty 202/204 replies as success for shared write endpoints.
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
P extends ApiPath |
M extends "get" | "post" | "put" | "patch" | "delete" | "head" | "options" |
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
path |
P |
method |
M |
…__namedParameters |
ApiFetchOptionsArgument<OperationAt<P, M>> |
Returns
Section titled “Returns”Promise<ApiResponse<OperationAt<P, M>>>
deviceTimeZone()
Section titled “deviceTimeZone()”deviceTimeZone():
string
The device’s IANA zone, the one source of the user’s day on this client.
Some engines report a legacy alias (Asia/Calcutta); the server accepts
every IANA name, including aliases.
Returns
Section titled “Returns”string
fetchDeduped()
Section titled “fetchDeduped()”fetchDeduped(
input,init?):Promise<Response>
Share duplicate GETs at the transport layer. Each caller gets an independent Response and owns its own abort signal; the network request is cancelled only when every caller has left. Keep successful snapshots for a short coalescing window because a page and its shell can mount their readers in adjacent turns after the first response completes. Writes clear snapshots. Keeping this below JSON decoding lets generated and handwritten clients share the same request.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
input |
RequestInfo | URL |
init? |
RequestInit |
Returns
Section titled “Returns”Promise<Response>
fetchSession()
Section titled “fetchSession()”fetchSession(
input,init):Promise<Response>
Notify browser owners of an expired session (#555). The web app owns cache cleanup/navigation; this transport has no dependency on the web storage module. Epochs ignore an old request’s 401 after sign-in, and bearer replies never end a browser session. Failed public authentication attempts do not end one either.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
input |
RequestInfo | URL |
init |
RequestInit |
Returns
Section titled “Returns”Promise<Response>
setDeviceTimeZoneOverride()
Section titled “setDeviceTimeZoneOverride()”setDeviceTimeZoneOverride(
timeZone):void
Use the User-confirmed zone for API day keys after a travel switch.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
timeZone |
string | null |
Returns
Section titled “Returns”void