@kleb/http (0.4.0)
Installation
@kleb:registry=npm install @kleb/http@0.4.0"@kleb/http": "0.4.0"About this package
@kleb/http
Framework-neutral, browser-compatible HTTP helpers.
JSON request bodies
Use parseJsonBodyUnknown when the route performs its own narrowing. It returns unknown so
untrusted JSON cannot be treated as an application type without a runtime check:
import { HttpError, parseJsonBodyUnknown } from "@kleb/http";
const body = await parseJsonBodyUnknown(request);
if (typeof body !== "object" || body === null || !("name" in body)) {
throw new HttpError(400, "Invalid request body");
}
For runtime validation and inferred output, pass any Standard Schema v1-compatible schema to
parseJsonBodyWithSchema. Both synchronous and asynchronous schema validators are supported, and
no schema-library dependency is required:
import { parseJsonBodyWithSchema } from "@kleb/http";
const body = await parseJsonBodyWithSchema(request, userSchema, {
requireContentType: true,
maxBytes: 64 * 1024,
});
// `body` is the schema's inferred output type.
Schema failures and exceptions become a stable, exposed HttpError with status 400, code
invalid_body, and message Request body failed validation. Schema issue text, thrown messages,
input values, and causes are not copied onto the error, because validator diagnostics can contain
request secrets.
parseJsonBody<T> remains available for one compatibility release but is deprecated. Its
caller-selected generic is only a type assertion and does not validate the JSON. Migrate to
parseJsonBodyUnknown or parseJsonBodyWithSchema.
Limits, cancellation, and memory
JSON reads have a default 1 MiB byte limit. Set maxBytes when a route needs a different cap. A
valid Content-Length over the cap is rejected before reading; streamed or chunked bodies are
counted while being read. Set requireContentType to accept only application/json and structured
JSON media types such as application/problem+json.
The parser best-effort cancels the request body when it rejects early with 413 or 415, and when
a streamed body crosses the byte limit. Cancellation failures never replace the primary HTTP
error. The request's AbortSignal is observed while reads are pending; signal aborts and stream
AbortErrors are normalized to status 499 with code request_aborted.
The byte cap bounds the chunks retained before parsing, but this is not a streaming JSON parser.
The implementation joins retained chunks into a contiguous byte array, decodes a JavaScript
string, and then creates the parsed value. Peak memory can therefore be several times maxBytes,
plus the parsed object graph; a transport-provided chunk that crosses the limit also exists until
that read is discarded. Choose lower route-specific limits for large or untrusted payloads, and
use a dedicated streaming format/parser when payloads cannot safely be buffered.
Responses
import { errorResponse, jsonResponse } from "@kleb/http";
return jsonResponse({ ok: true }, { status: 201 });
// In an outer request handler:
return errorResponse(error, { requestId });
Unknown errors and non-exposed server errors use Internal server error by default. Error details
are omitted unless explicitly requested.