Transport for Companies House: the settings resolver (per-call
opts first, then context variables, then defaults), a typed
HttpError, JSON GETs, and query-string building that drops unset
values.
| opts key | Context variable | Default |
|---|---|---|
api-key | companies-house.api-key | none: calls fail without it |
base-url | companies-house.base-url | https://api.company-information.service.gov.uk |
document-base-url | companies-house.document-base-url | https://document-api.company-information.service.gov.uk |
Per-call credentials. api-key in opts is masked in call
records and never written to context, so parallel flows and tenants
in one run don't see each other's keys. Present but blank or null, it
is an error, never a fallback to context. A per-call base-url or
document-base-url needs an api-key in the same opts: the
context key is never sent to a per-call URL.
Context Vars
companies-house.api-keycompanies-house.base-urlcompanies-house.document-base-url
Values
BASE_URL
BASE_URL: Str "https://api.company-information.service.gov.uk"
DOCUMENT_BASE_URL
DOCUMENT_BASE_URL: Str "https://document-api.company-information.service.gov.uk"
KEYED_URL_KEYS
KEYED_URL_KEYS: Vec [
"base-url",
"document-base-url"
]
PACKAGE_AGENT
PACKAGE_AGENT: Str "hot-dev-companies-house-pkg/0.1 (+https://hot.dev)"
SOURCE
SOURCE: Str "companies-house"
Functions
body-detail
fn (body: Any): Str?
get-json
fn (url: Str, headers: Map): Any
GET a JSON resource and return the decoded body, or an Err carrying HttpError.
get-json-or-null
fn (url: Str, headers: Map): Any
get-json, but a 404 gives null (a missing company) instead of an Err.
given
fn (v: Any): Bool
True for a non-null value that is not a blank string.
http-error
fn (response: ::hot::http/HttpResponse, url: Str): HttpError
Build an HttpError from a non-2xx response. Exposed for testing; every request uses it.
is-not-found
fn (e: Any): Bool
True when e is an HttpError with status 404.
path-segment
fn (value: Any): Str
Percent-encode one path segment.
pick
fn (opts: Map, key: Str, ctx-key: Str, default: Any): Any
query-string
fn (params: Map): Str
Build a ?a=1&b=2 suffix from a Map, dropping null and blank values (pure); "" when nothing remains.
request
fn (method: Str, url: Str, headers: Map): ::hot::http/HttpResponse
GET (or another method) a Companies House URL with headers, returning
the HttpResponse on 2xx or an Err carrying HttpError. A
transport failure passes through as its own Err.
require-api-key
fn (cfg: Map): Str
The API key from resolved settings, or an Err naming where to set it.
resolve
fn (opts: Map): Map
Resolve settings for one call: {api-key, base-url, document-base-url}. Values in opts win over context; an api-key
in opts is used for that call only and comes back unchanged. An
Err when api-key is in opts but blank or null, or when opts
has a URL without api-key.
Example
cfg ::companies-house::api/resolve({api-key: tenant.ch-key})
retry-after
fn (headers: Map): Int?
strip-slash
fn (url: Str): Str
Types
HttpError
HttpError type {
source: Str,
status: Int,
url: Str,
headers: Map,
body: Any,
retry-after: Int?,
message: Str
}
A non-2xx Companies House response. source is "companies-house"; url the
requested URL (Companies House takes no credentials in URLs); retry-after
the parsed Retry-After seconds on 429s; message a one-line
summary that never includes credentials.