simcapture-sdk
v0.17.1
Published
Typed SimCapture API client with auth, token caching, and 401 retry.
Readme
simcapture-sdk
SimCapture API client. A typed wrapper over the SimCapture REST API that handles
authentication, token caching, and 401 retry so consumers don't hand-roll
axios + login code per service.
npm install simcapture-sdkUsage
import { SimCaptureClient, SimCaptureError } from "simcapture-sdk";
const sc = new SimCaptureClient({
apiUrl: process.env.SIMCAPTURE_API!, // https://api.simcapture.com
inventoryUrl: process.env.SIMCAPTURE_INVENTORY_API!,
credentials: {
username: process.env.SIMCAPTURE_USER!,
password: process.env.SIMCAPTURE_PASSWORD!,
clientSubdomain: process.env.SIMCAPTURE_SUBDOMAIN!,
},
});
const orgs = await sc.organizations.findAll();
const reservations = await sc.reservations.findAll({
end: "2025-07-01T05:00:00.000Z",
start: "2026-12-31T05:00:00.000Z",
});
try {
await sc.reservations.findOne("bad-id");
} catch (e) {
if (e instanceof SimCaptureError) {
console.error(e.status, e.code, e.body); // real upstream status, not a blanket 400
}
}Resources
| Resource | Methods |
|---|---|
| organizations | findAll |
| locations | findAll |
| reservations | findAll, findOne, update, updateDetails, delete |
| courses | find, getItems |
| scenarios | findOne, updateSetup, updateDetails, getAttachment |
| simulators | findAll, findOne, update, getConfig |
| notifications | send |
| inventory | findAll, findOne, edit (inventory server) |
Auth behaviour
- Tokens are cached and reused until a soft TTL (
tokenTtlMs, default 30 min) elapses. - A
401clears the cache, re-logins once, and retries the failed request once. - Concurrent callers share a single in-flight
/authrequest.
Architecture (DDD)
domain/ entities, value-objects, ports (HttpClient, TokenStore), models, errors
application/ use-cases: Authenticator + one resource class per domain
infrastructure/ axios transport adapter + in-memory token store
config/ SimCaptureConfig + resolution/validation
client.ts composition root wiring infra → applicationflowchart TB
Consumer["Consumer (MS / frontend)"] --> Client["SimCaptureClient<br/>(composition root)"]
subgraph application["application"]
Resources["Resources<br/>reservations · scenarios · …"]
Auth["Authenticator<br/>token cache · 401 retry"]
end
subgraph domain["domain (no deps)"]
Ports["Ports<br/>HttpClient · TokenStore"]
Models["Models · VOs · SimCaptureError"]
end
subgraph infrastructure["infrastructure"]
Axios["AxiosHttpClient"]
Store["InMemoryTokenStore"]
end
Client --> Resources
Client --> Auth
Resources --> Auth
Resources -.depends on.-> Ports
Auth -.depends on.-> Ports
Auth --> Models
Axios -.implements.-> Ports
Store -.implements.-> Ports
Axios --> SimCapture["SimCapture API<br/>api + inventory servers"]
Client -. injects .-> Axios
Client -. injects .-> StoreDependencies point inward — the domain/application layers depend only on the
HttpClient/TokenStore ports, so they are unit-tested with fakes (no network).
Advanced consumers can inject their own transport or a shared token store via the
second SimCaptureClient constructor argument.
Development (Bun)
bun install
bun run typecheck # tsc --noEmit (strict)
bun test # unit tests against the ports (no real network)
bun run build # tsup → ESM + CJS + .d.ts in dist/ (Node-compatible)The published artifact is built with tsup for Node ≥18 (ESM + CJS + types). Bun is
the dev/build/test toolchain only — there are no bun:* imports in shipped code.
