shelving/util/httpmodule

Typed utilities for building and parsing Request and Response objects using the standard Fetch API. The helpers handle content-type negotiation, body serialisation, and error-to-response conversion so you don't have to repeat that logic in every endpoint or client.

Things to know:

Usage

Creating requests

ts
import { createRequest, createJSONRequest, createHeadRequest } from "shelving/util";

// Smart constructor — picks content type from payload.
createRequest("POST", "https://api.example.com/items", { name: "Widget" });
createRequest("GET",  "https://api.example.com/items", { status: "active" });
// GET → appends ?status=active to URL

// Explicit JSON request.
createJSONRequest("PUT", "https://api.example.com/items/1", { name: "Widget" });

// Body-less GET with query params.
createHeadRequest("GET", "https://api.example.com/search", { q: "hello" });

Parsing request and response bodies

ts
import { parseRequestBody, parseRequestJSON, parseResponseBody } from "shelving/util";

// In a server handler:
const body = await parseRequestBody(request); // respects Content-Type
const json = await parseRequestJSON(request); // always expects JSON

// After fetch():
const data = await parseResponseBody(response);

Building responses

ts
import { getResponse, getErrorResponse } from "shelving/util";

// In a request handler:
return getResponse({ id: "1", name: "Widget" }); // 200 with JSON body
return getResponse(undefined);                    // 204 No Content

// In a catch block:
return getErrorResponse(error);           // 500, no details
return getErrorResponse(error, true);     // 500, includes message in dev

Merging request options

ts
import { mergeRequestOptions } from "shelving/util";

const defaults = { headers: { Authorization: "Bearer token" }, credentials: "include" };
const overrides = { headers: { "X-Request-ID": "abc" }, signal: controller.signal };

const merged = mergeRequestOptions(defaults, overrides);
// headers: { Authorization: "Bearer token", "X-Request-ID": "abc" }

Functions

Go

parseRequestBody()function

Parse the body content of an HTTP Request based on its content type, or throw RequestError if the content could not be parsed.

parseRequestBody(request: Request, caller: AnyCaller = parseRequestBody): Promise<unknown>
Go

parseRequestJSON()function

Parse JSON from an HTTP Request, or return undefined when the request has no body.

parseRequestJSON(request: Request, caller: AnyCaller = parseRequestJSON): Promise<unknown>
Go

parseRequestFormData()function

Parse FormData from an HTTP Request, or return undefined when the request has no body.

parseRequestFormData(request: Request, caller: AnyCaller = parseRequestFormData): Promise<FormData | undefined>
Go

parseResponseBody()function

Parse the body content of an HTTP Response based on its content type, or throw ResponseError if the content could not be parsed.

parseResponseBody(response: Response, caller: AnyCaller = parseResponseBody): Promise<unknown>
Go

parseResponseJSON()function

Parse JSON from an HTTP Response, or return undefined when the response has no body.

parseResponseJSON(response: Response, caller: AnyCaller = parseResponseJSON): Promise<unknown>
Go

parseResponseFormData()function

Parse FormData from an HTTP Response, or return undefined when the response has no body.

parseResponseFormData(response: Response, caller: AnyCaller = parseResponseFormData): Promise<FormData>
Go

getResponse()function

Get an HTTP Response for an unknown value.

getResponse(value: unknown): Response
Go

getErrorResponse()function

Get an HTTP Response for an unknown error value.

getErrorResponse(reason: unknown, debug = false): Response
Go

isRequestMethod()function

Is a string a supported HTTP request method?

isRequestMethod(method: string): method is RequestMethod
Go

isRequestHeadMethod()function

Is a string a supported HTTP request method that never sends a body?

isRequestHeadMethod(method: string): method is RequestHeadMethod
Go

mergeRequestOptions()function

Merge provider-level and call-level request options.

mergeRequestOptions({ headers: aHeaders, signal: aSignal, ...a }: RequestOptions = {}, { headers: bHeaders, signal: bSignal, ...b }: RequestOptions = {}): RequestOptions
Go

createHeadRequest()function

Create a body-less Request.

createHeadRequest(method: RequestHeadMethod, url: PossibleURL, params: Nullish<PossibleURIParams>, options: RequestOptions = {}, caller: AnyCaller = createHeadRequest): Request
Go

createTextRequest()function

Create a plain-text Request.

createTextRequest(method: RequestMethod, url: PossibleURL, body: string, options: RequestOptions = {}, caller: AnyCaller = createTextRequest): Request
Go

createJSONRequest()function

Create a JSON Request.

createJSONRequest(method: RequestBodyMethod, url: PossibleURL, body: unknown, options: RequestOptions = {}, caller: AnyCaller = createJSONRequest): Request
Go

createFormDataRequest()function

Create a multipart form-data Request.

createFormDataRequest(method: RequestBodyMethod, url: PossibleURL, body: FormData, options: RequestOptions = {}, caller: AnyCaller = createFormDataRequest): Request
Go

createXMLRequest()function

Create an XML Request.

createXMLRequest(method: RequestBodyMethod, url: PossibleURL, data: Data, options: RequestOptions = {}, caller: AnyCaller = createXMLRequest): Request
Go

createRequest()function

Create a Request instance with a valid content type based on the body.

createRequest(method: RequestMethod, url: PossibleURL, payload: unknown, options: RequestOptions = {}, caller: AnyCaller = createRequest): Request
Go

assertRequestHeadPayload()function

Assert that the payload for a HEAD or GET method is a data object, null, or undefined.

assertRequestHeadPayload(payload: unknown, method: RequestHeadMethod, caller: AnyCaller = assertRequestHeadPayload): asserts payload is Nullish<Data>

Types

Go

RequestHandlertype

A handler function takes a Request and optional extra arguments and returns a Response (possibly asynchronously).

(request: Request, ...args: A) => Response | Promise<Response>
Go

OptionalRequestHandlertype

An optional request handler that may return undefined to indicate no match.

(request: Request, ...args: A) => Response | Promise<Response> | undefined
Go

OptionalRequestHandlerstype

A list of optional request handlers.

Iterable<OptionalRequestHandler<A>>
Go

RequestHeadMethodtype

HTTP request methods that have no body.

"HEAD" | "GET"
Go

RequestBodyMethodtype

HTTP request methods that have a body.

"POST" | "PUT" | "PATCH" | "DELETE"
Go

RequestMethodtype

HTTP request methods.

RequestHeadMethod | RequestBodyMethod
Go

RequestParamstype

Params in requests are a dictionary of strings.

ImmutableDictionary<string>
Go

RequestOptionstype

Configurable options for endpoint requests.

Pick<
	RequestInit,
	"cache" | "credentials" | "headers" | "integrity" | "keepalive" | "mode" | "redirect" | "referrer" | "referrerPolicy" | "signal"
>