All elements

Go

shelving/apimodule

Typed, provider-based framework for HTTP API access. Define your routes as Endpoint definitions, then call them through a composable provider stack — the same pattern the shelving/db module uses for databases.

Go

ClientAPIProviderOptionsinterface

Options for constructing a ClientAPIProvider.

{
	readonly url: PossibleURL;
	readonly options?: Omit<RequestOptions, "signal">;
	readonly timeout?: number | undefined;
}
Go

ClientAPIProviderclass

A client-side API provider that sends requests over the network using fetch().

new ClientAPIProvider<P, R>({ url, options = {}, timeout = 20_000 }: ClientAPIProviderOptions)
Go

MockEndpointAPIProviderclass

Provider that mocks an API that calls and matches an array of EndpointHandler objects returned from Endpoint.handler()

new MockEndpointAPIProvider<P, R, C>(handlers: EndpointHandlers<C>, context: C, source?: ClientAPIProvider<P, R>)
Go

ValidationAPIProviderclass

Provider that validates payloads and results against the endpoint's schemas, so a source of any type is made type-safe.

new ValidationAPIProvider<P, R>()
Go

CachedAPIProviderclass

API provider wrapper that serves requests through an APICache so repeated calls reuse cached results.

new CachedAPIProvider<P, R>(source: APIProvider<P, R>, maxAge: number = AVOID_REFRESH)
Go

CachedAPIProvider.invalidate()method

Invalidate the cached result for a specific endpoint and payload.

invalidate(endpoint: Endpoint<PP, RR>, payload: PP): void
Go

CachedAPIProvider.invalidateAll()method

Invalidate every cached result for an endpoint, across all payloads.

invalidateAll(endpoint: Endpoint<PP, RR>): void
Go

CachedAPIProvider.refresh()method

Refresh the cached result for a specific endpoint and payload.

refresh(endpoint: Endpoint<PP, RR>, payload: PP): void
Go

CachedAPIProvider.refreshAll()method

Refresh every cached result for an endpoint, across all payloads.

refreshAll(endpoint: Endpoint<PP, RR>): void
Go

APIProviderclass

Abstract base for API providers that send requests to a set of Endpoint definitions rooted at a common base URL.

new APIProvider<P, R>()
Go

APIProvider.renderURL()method

Render the full final URL for an API request to a given endpoint with a given payload.

renderURL(endpoint: Endpoint<PP, RR>, payload: PP, caller?: AnyCaller): URL
Go

APIProvider.createRequest()method

Create a Request that targets this endpoint with a given base URL.

createRequest(endpoint: Endpoint<PP, RR>, payload: PP, options?: RequestOptions, caller?: AnyCaller): Request
Go

APIProvider.fetch()method

Send a Request and return its Response (defaults to the JavaScript fetch() API).

fetch(request: Request): Promise<Response>
Go

APIProvider.parseResponse()method

Parse an HTTP Response for this endpoint into a result value.

parseResponse(_endpoint: Endpoint<PP, RR>, response: Response, caller?: AnyCaller): Promise<RR>
Go

APIProvider.call()method

Send a payload to an Endpoint and retrieve the parsed result.

call(endpoint: Endpoint<PP, RR>, payload: PP, options?: RequestOptions, caller?: AnyCaller): Promise<RR>
Go

MockAPIFetchCalltype

Record of a single mocked fetch, pairing the request with the response the handler returned.

{
	readonly request: Request;
	readonly response: Response;
}
Go

MockAPIRequestCalltype

Record of a single request build, capturing the endpoint, payload, options, and built request.

{
	readonly endpoint: AnyEndpoint;
	readonly payload: unknown;
	readonly options: RequestOptions | undefined;
	readonly request: Request;
}
Go

MockAPIResponseCalltype

Record of a single response parse, capturing the endpoint, response, and parsed result.

{
	readonly endpoint: AnyEndpoint;
	readonly response: Response;
	readonly result: unknown;
}
Go

MockAPIProviderclass

Provider that records API calls and serves them from a handler without sending network requests.

new MockAPIProvider<P, R>(handler: RequestHandler = _mockHandler, source: APIProvider<P, R> = new ClientAPIProvider({ url: "https://api.mock.com" }))
Go

DebugAPIProviderclass

Provider that logs every request, response, and error to the console in detail to help diagnose issues in development.

new DebugAPIProvider<P, R>()
Go

JSONAPIProviderclass

Client API provider that always sends request bodies as JSON and parses responses as JSON.

new JSONAPIProvider<P, R>()
Go

LoggingAPIProviderclass

Provider that logs fetches to the console to keep useful request/response logs in production.

new LoggingAPIProvider<P, R>(source: APIProvider<P, R>, onRequest: Callback<[Request]> = logRequest, onResponse: Callback<[Response, Request]> = logRequestResponse, onError: Callback<[reason: unknown, Request]> = logRequestError)
Go

XMLAPIProviderclass

Client API provider that always sends request bodies as XML and parses responses as plain text.

new XMLAPIProvider<P, R>()
Go

Endpointclass

A typed API resource definition pairing a method and path with payload and result schemas.

new Endpoint<P, R>(method: RequestMethod, path: AbsolutePath, payload: Schema<P>, result: Schema<R>)
Go

Endpoint.renderPath()method

Render the path for this endpoint with the given payload.

renderPath(payload: P, caller: AnyCaller = this.renderPath): AbsolutePath
Go

Endpoint.match()method

Match a method/path pair against this endpoint and return any matched {placeholder} params.

match(method: RequestMethod, path: AbsolutePath, caller: AnyCaller = this.match): RequestParams | undefined
Go

Endpoint.handler()method

Create an endpoint handler pairing for this endpoint.

handler(callback: EndpointCallback<P, R, C>): EndpointHandler<P, R, C>
Go

Endpoint.toString()method

Convert this endpoint to a string in METHOD /path form, e.g. GET /user/{id}

toString(): string
Go

AnyEndpointtype

An Endpoint with any payload and result type, for use where the specific types don't matter.

Endpoint<any, any>
Go

Endpointstype

An immutable list of endpoints.

ImmutableArray<AnyEndpoint>
Go

PayloadTypetype

Extract the payload type from an Endpoint.

X extends Endpoint<infer Y, unknown> ? Y : never
Go

EndpointTypetype

Extract the result type from an Endpoint.

X extends Endpoint<unknown, infer Y> ? Y : never
Go

HEAD()function

Define a HEAD endpoint at a path, with validated payload and result types.

HEAD(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>
HEAD(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>
HEAD(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>
Go

GET()function

Define a GET endpoint at a path, with validated payload and result types.

GET(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>
GET(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>
GET(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>
Go

POST()function

Define a POST endpoint at a path, with validated payload and result types.

POST(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>
POST(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>
POST(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>
Go

PUT()function

Define a PUT endpoint at a path, with validated payload and result types.

PUT(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>
PUT(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>
PUT(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>
Go

PATCH()function

Define a PATCH endpoint at a path, with validated payload and result types.

PATCH(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>
PATCH(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>
PATCH(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>
Go

DELETE()function

Define a DELETE endpoint at a path, with validated payload and result types.

DELETE(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>
DELETE(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>
DELETE(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>
Go

EndpointCallbacktype

A function that handles an endpoint request, receiving a validated payload and returning a result.

(payload: P, request: Request, context: C) => R | Response | Promise<R | Response>
Go

EndpointHandlerinterface

A typed endpoint definition paired with its implementation callback.

{
	readonly endpoint: Endpoint<P, R>;
	readonly callback: EndpointCallback<P, R, C>;
}
Go

AnyEndpointHandlertype

An EndpointHandler with any payload and result type, for use where the specific types don't matter.

EndpointHandler<any, any, C>
Go

EndpointHandlerstype

A collection of endpoint handlers that can be matched and invoked by handleEndpoints().

Iterable<AnyEndpointHandler<C>>
Go

handleEndpoints()function

Handle a Request with the first matching endpoint handler after stripping any base-path prefix from the request pathname.

handleEndpoints(base: PossibleURL, handlers: EndpointHandlers<C>, request: Request, context: C, caller?: AnyCaller): Promise<Response>
handleEndpoints(base: PossibleURL, handlers: EndpointHandlers<void>, request: Request, context?: undefined, caller?: AnyCaller): Promise<Response>
Go

EndpointStoreclass

Store that loads and tracks the result of calling a single API endpoint with a fixed payload, through an APIProvider.

new EndpointStore<P, R>(endpoint: Endpoint<P, R>, payload: P, provider: APIProvider<P, R>)
Go

EndpointCacheclass

Cache of EndpointStore objects for a single endpoint, keyed by the rendered request URL of each payload.

new EndpointCache<P, R>(endpoint: Endpoint<P, R>, provider: APIProvider<P, R>)
Go

EndpointCache.get()method

Get (or create) the EndpointStore for the given payload.

get(payload: P, caller: AnyCaller = this.get): EndpointStore<P, R>
Go

EndpointCache.call()method

Fetch (or return a cached result) for the given payload.

call(payload: P, maxAge: number = AVOID_REFRESH, caller: AnyCaller = this.call): Promise<R>
Go

EndpointCache.invalidate()method

Invalidate a specific store so the next read refetches.

invalidate(payload: P, caller: AnyCaller = this.invalidate): void
Go

EndpointCache.invalidateAll()method

Invalidate all stores so the next read of any payload refetches.

invalidateAll(): void
Go

EndpointCache.refresh()method

Trigger a refetch on a specific store.

refresh(payload: P, maxAge?: number, caller: AnyCaller = this.invalidate): Promise<void>
Go

EndpointCache.refreshAll()method

Trigger a refetch on all stores.

refreshAll(maxAge?: number): Promise<void>
Go

APICacheclass

Cache of EndpointCache objects keyed by Endpoint, providing memoised API results across many endpoints.

new APICache<P, R>(provider: APIProvider<P, R>)
Go

APICache.get()method

Get (or create) the EndpointCache for the given endpoint.

get(endpoint: Endpoint<PP, RR>): EndpointCache<PP, RR>
get(endpoint: Endpoint): EndpointCache
Go

APICache.call()method

Fetch (or return a cached result) for the given endpoint and payload.

call(endpoint: Endpoint<PP, RR>, payload: PP, maxAge: number = AVOID_REFRESH, caller: AnyCaller = this.call): Promise<RR>
Go

APICache.invalidate()method

Invalidate a specific store for an endpoint so the next read refetches.

invalidate(endpoint: Endpoint<PP, RR>, payload: PP): void
Go

APICache.invalidateAll()method

Invalidate all stores for an endpoint so the next read of any payload refetches.

invalidateAll(endpoint: Endpoint<PP, RR>): void
Go

APICache.refresh()method

Trigger a refetch on a specific store for an endpoint.

refresh(endpoint: Endpoint<PP, RR>, payload: PP, maxAge?: number): void
Go

APICache.refreshAll()method

Trigger a refetch on all stores for an endpoint.

refreshAll(endpoint: Endpoint<PP, RR>, maxAge?: number): void
Go

shelving/bunmodule

DBProvider implementation for PostgreSQL using Bun's built-in Bun.sql API. No external database driver is required.

Go

BunPostgreSQLProviderclass

PostgreSQL database provider backed by Bun's built-in Bun.SQL driver.

new BunPostgreSQLProvider<I, T>(sql: SQL)
Go

shelving/cloudflaremodule

DBProvider implementations for Cloudflare Workers. Two backends are available: Workers KV for simple key-value storage and D1 for relational SQL.

Go

KVNamespaceinterface

Minimal interface matching the Cloudflare Workers KV namespace runtime object.

{
	get(key: string, options: { type: "json" }): Promise<unknown>;
	put(key: string, value: string): Promise<void>;
	delete(key: string): Promise<void>;
}
Go

KVNamespace.get()method

get(key: string, options: { type: "json" }): Promise<unknown>
Go

KVNamespace.put()method

put(key: string, value: string): Promise<void>
Go

KVNamespace.delete()method

delete(key: string): Promise<void>
Go

D1Valuetype

Value that can be passed through the D1 Worker API as a bound parameter.

boolean | null | number | string
Go

D1Metainterface

Metadata returned by the D1 Worker API alongside a query result.

{
	readonly changed_db?: boolean | undefined;
	readonly duration?: number | undefined;
	readonly last_row_id?: number | undefined;
	readonly rows_read?: number | undefined;
	readonly rows_written?: number | undefined;
}
Go

D1Resultinterface

Result object returned by D1PreparedStatement.run().

{
	readonly success: boolean;
	readonly meta?: D1Meta | undefined;
	readonly results?: readonly T[] | undefined;
}
Go

D1ExecResultinterface

Result object returned by D1Database.exec().

{
	readonly count: number;
	readonly duration: number;
}
Go

D1PreparedStatementinterface

Minimal prepared statement interface for D1 databases and sessions.

{
	bind(...values: D1Value[]): D1PreparedStatement;
	first<T = Record<string, unknown>>(column?: string): Promise<T | null>;
	raw<T = unknown[]>(options?: { columnNames?: boolean }): Promise<readonly T[]>;
	run<T extends Record<string, unknown> = Record<string, unknown>>(): Promise<D1Result<T>>;
}
Go

D1PreparedStatement.bind()method

bind(...values: D1Value[]): D1PreparedStatement
Go

D1PreparedStatement.first()method

first(column?: string): Promise<T | null>
Go

D1PreparedStatement.raw()method

raw(options?: { columnNames?: boolean }): Promise<readonly T[]>
Go

D1PreparedStatement.run()method

run(): Promise<D1Result<T>>
Go

D1Databaseinterface

Minimal D1 binding/session interface used by CloudflareD1Provider.

{
	batch<T extends Record<string, unknown> = Record<string, unknown>>(
		statements: readonly D1PreparedStatement[],
	): Promise<readonly D1Result<T>[]>;
	exec?(query: string): Promise<D1ExecResult>;
	prepare(query: string): D1PreparedStatement;
}
Go

D1Database.batch()method

batch(statements: readonly D1PreparedStatement[]): Promise<readonly D1Result<T>[]>
Go

D1Database.exec()method

exec(query: string): Promise<D1ExecResult>
Go

D1Database.prepare()method

prepare(query: string): D1PreparedStatement
Go

CloudflareD1Providerclass

SQLite database provider backed by Cloudflare D1.

new CloudflareD1Provider<I, T>(db: D1Database)
Go

CloudflareKVProviderclass

Cloudflare Workers KV database provider.

new CloudflareKVProvider<I, T>(kv: KVNamespace)
Go

shelving/dbmodule

Typed database provider abstraction. Define your schema once as a Collection, then swap providers (in-memory, SQLite, Firestore, Cloudflare D1, …) without changing any call sites. Providers are composable wrappers — add validation, logging, or caching by stacking them in a chain.

Go

SQLFragmentinterface

SQL fragment made from template strings plus embedded expressions, ready to be composed into a query.

{
	readonly strings: ImmutableArray<string>;
	readonly values: ImmutableArray<unknown>;
}
Go

SQLProviderclass

Abstract database provider that implements CRUD and query operations by generating and executing SQL.

new SQLProvider<I, T>()
Go

SQLProvider.exec()method

Execute an SQL query built from a template literal and return the resulting rows.

exec(strings: TemplateStringsArray, ...values: ImmutableArray<unknown>): Promise<ImmutableArray<X>>
Go

SQLProvider.sql()method

Define an SQL fragment using Javascript template literal format.

sql(strings: TemplateStringsArray, ...values: ImmutableArray<unknown>): SQLFragment
Go

SQLProvider.sqlIdentifier()method

Define an SQL fragment for an escaped identifier, e.g. "myTable".

sqlIdentifier(name: string): SQLFragment
Go

SQLProvider.sqlExtract()method

Define an SQL fragment that extracts a value at a key for comparison, e.g. "a" #>> {"b","c"} in Postgres.

sqlExtract(key: Segments): SQLFragment
Go

SQLProvider.sqlConcat()method

Define an SQL fragment that joins a series of fragments with a separator, e.g. "a" = 1 AND "b" = 2.

sqlConcat(values: ImmutableArray<SQLFragment>, separator = ", ", before = "", after = ""): SQLFragment
Go

SQLProvider.sqlSetters()method

Define an SQL fragment for setting a list of values, e.g. "a" = 1, "b" = 2.

sqlSetters(data: TT): SQLFragment
Go

SQLProvider.sqlUpdates()method

Define an SQL fragment for a set of updates, e.g. "a" = 1, "b" = "b" + 5.

sqlUpdates(updates: Updates<TT>): SQLFragment
Go

SQLProvider.sqlUpdate()method

Define an SQL fragment for a single update action.

sqlUpdate({ action, key, value }: Update): SQLFragment
Go

SQLProvider.sqlValues()method

Define an SQL fragment for VALUES syntax, e.g. ("a", "b") VALUES (1, 2).

sqlValues(data: Data): SQLFragment
Go

SQLProvider.sqlClauses()method

Define an SQL fragment for the WHERE, ORDER BY and LIMIT clauses of a query, e.g. WHERE x = 1 ORDER BY "name" LIMIT 0, 50.

sqlClauses(query: Query<Item>): void
Go

SQLProvider.sqlWhere()method

Define an SQL fragment for a WHERE clause, e.g. WHERE x = 1 AND y <= 100.

sqlWhere(query: Query<Item>): void
Go

SQLProvider.sqlFilter()method

Define an SQL fragment for a single filter clause on a column, e.g. x = 1 or x IN (1, 2).

sqlFilter({ key, operator, value }: QueryFilter): SQLFragment
Go

SQLProvider.sqlOrder()method

Define an SQL fragment for an ORDER BY clause, e.g. ORDER BY "a" ASC, "b" DESC.

sqlOrder(query: Query<Item>): void
Go

SQLProvider.sqlSort()method

Define an SQL fragment for an individual column in an ORDER BY, e.g. "a" ASC.

sqlSort({ key, direction }: QueryOrder): SQLFragment
Go

SQLProvider.sqlLimit()method

Define an SQL fragment for a LIMIT clause, e.g. LIMIT 50.

sqlLimit(query: Query<Item>): void