first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
# `http-check/http-check`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`createHttpCheck` returns a `CheckFn` that probes an HTTP endpoint and reports `healthy` when the response status appears in `expectedStatusCodes`. It is the standard building block for "is upstream X reachable?" probes — used to check downstream APIs, gateways, internal dependency surfaces, and anything else with a `/health` or `/status` endpoint. The factory accepts an injectable `fetchImpl` so tests never touch real network sockets, and an injectable `Clock` so `responseTime` is deterministic.
## Features
- Method, headers, and expected-status-code overrides via the `HttpCheckConfig` argument.
- AbortController-driven per-request timeout that maps to `responseTime` + the human-readable `"HTTP check timed out after Xms"` message.
- Network errors are returned as `unhealthy` with `details.error` containing the raw message — not thrown.
- Zod boundary validation: empty `url`, empty `method`, non-positive `timeout` all throw `HealthCheckError(INVALID_OPTIONS)`.
- `fetchImpl` defaults to `globalThis.fetch` bound to `globalThis`; tests pass a stub.
## Usage: Basic
```ts
import { createHttpCheck } from "@suaveplan/health-check";
const check = createHttpCheck({ url: "https://upstream.example/health" });
const result = await check();
```
## Usage: Advanced
```ts
import { createHttpCheck } from "@suaveplan/health-check";
const check = createHttpCheck(
{
url: "https://internal.api/health",
method: "HEAD",
headers: { authorization: `Bearer ${token}` },
timeout: 1_500,
expectedStatusCodes: [200, 204],
fetchImpl: instrumentedFetch,
},
{ clock: () => performance.now() },
);
```
## API Reference
- `createHttpCheck(config, options?)` → `CheckFn`.
- `config: HttpCheckConfig` — `url` required; `method`, `headers`, `timeout`, `expectedStatusCodes`, `fetchImpl` optional.
- `options.clock?: Clock` — overrides `Date.now` for response-time measurement.
## Implementation Notes
The check never re-throws. Network errors, abort errors, and unexpected status codes are all funnelled into `CheckResult` objects so the `HealthChecker` can record them uniformly. Abort detection is case-insensitive on `"abort"` / `"timeout"` and also consults `controller.signal.aborted` so adapters that surface only a generic error message still classify correctly. The `responseTime` is measured between the clock readings around `fetchImpl` so it includes DNS, TCP, TLS, and the server's processing time — matching how operators read latency dashboards. The factory is pure: it validates options once and returns a closure that captures the normalised config, so the per-call cost is just the fetch + a small amount of bookkeeping.