@umbraculum/api-client
v0.0.3
Published
Typed API client with pluggable auth strategies (cookie sessions for web; bearer tokens for native + Node). The transport layer between any client and services/api. Returned payloads are runtime-validated by parsers from @umbraculum/contracts. Platform-cl
Downloads
530
Readme
@umbraculum/api-client
Typed API client with pluggable auth strategies (cookie sessions for web; bearer tokens for native + Node).
[!NOTE] Part of Umbraculum — an open-source toolset for building workspace-shaped operational applications.
What this is
The transport layer between any client and services/api. Web (Next.js) and native (React Native + Expo) both consume from this package, but they authenticate differently — the web app rides a cookie session (sid httpOnly), the native app sends a bearer token (Authorization: Bearer <token>). This package abstracts that split behind two interchangeable auth-strategy factories (cookieAuth() and bearerTokenAuth(getToken)); the rest of the client surface is identical across platforms. Returned payloads are runtime-validated by the parsers in @umbraculum/contracts. See docs/AUTH-STRATEGY.md for the platform-wide auth direction.
Scope
- Contains: the
createApiClient(baseUrl, auth, options?)factory, auth strategies, typed platform facades (Phase E), RFC-0007 render-job helpers, OpenAPI-derived platform path/component types (PlatformOpenApiPaths, …), and afetchinjection point for environments where the globalfetchis not appropriate (Node tests, RN Hermes). Brewery OpenAPI types and HTTP facades:@umbraculum/brewery-api-client. - Does not contain: contract DTO/parser definitions (those live in
@umbraculum/contracts); auth backend logic — token issuance, session creation (lives inservices/api/src/routes/auth/); UI session-state management (lives in the consuming app).
Typed facades (Phase E)
Two-layer client: OpenAPI types (compile-time) + contracts parsers (runtime). Never trust JSON.parse + type assertion alone.
First-party apps reach the API through nginx at /api/*. Facades map OpenAPI path keys to client paths via toClientPath() internally.
| Facade module | Example calls | Contracts parser |
|---------------|---------------|------------------|
| platform/auth | getAuthMe, login, loginNative, signup, logout, setActiveWorkspace, patchAuthPreferences, exchangeWebviewToken | AuthMeResponseSchema, AuthLogin*Schema, AuthSignup*Schema, … |
| platform/workspaces | listWorkspaces, createWorkspace, getHealth | WorkspacesListResponseSchema, HealthResponseSchema |
| platform/modules | getWorkspaceBilling, listIntegrationDevices | WorkspaceBillingResponseSchema, IntegrationDevicesListResponseSchema |
| platform/ai | getWorkspaceAiSettings, patchWorkspaceAiSettings, getWorkspaceAiUsage, createAiUpgradeBillingIntent | WorkspaceAiSettingsResponseSchema, WorkspaceAiUsageResponseSchema, BillingIntentResponseSchema |
| platform/ads | getAdSlot | AdSlotResponseSchema |
| platform/platformAdmin | listPlatformWorkspaces, listPlatformRecipes, platform recipe import, platform ads CRUD | PlatformWorkspacesListResponseSchema, PlatformAdsListResponseSchema, … |
| platform/rendering | submitRenderJob, runAsyncRenderJobExport, … | RenderJob*ResponseSchema |
| platform/integrations | workspace integration CRUD, devices, tilt attach/detach, recent sessions | @umbraculum/contracts integrations schemas |
| automation/vessels | listVessels, getVessel | VesselListResponseSchema, VesselStateResponseSchema |
| pim/products | listProducts, createProduct, getProduct, listProductVariants | Product*ResponseSchema, VariantListResponseSchema |
| pim/attributeSets | listAttributeSets, getAttributeSet | AttributeSet*ResponseSchema |
| pim/categories | listCategories | CategoryListResponseSchema |
| mrp/productionOrders | listProductionOrders, getProductionOrder, listMaterialRequirements | ProductionOrder*ResponseSchema, MaterialRequirementListResponseSchema |
| crp/planning | listResources, getResource, listWorkCenters, listScheduledOperations, listCapacityConflicts, getCapacityLoad | @umbraculum/crp-contracts response schemas |
Full path → parser map: src/facadeParserMap.ts (PLATFORM_*, AUTOMATION_*, PIM_*, MRP_*, CRP_* maps). Brewery vertical facades live in @umbraculum/brewery-api-client.
import { bearerTokenAuth, createApiClient, listWorkspaces } from "@umbraculum/api-client";
import { listRecipes } from "@umbraculum/brewery-api-client";
import { listVessels } from "@umbraculum/api-client/automation";
const client = createApiClient(baseUrl, bearerTokenAuth(() => token));
const workspaces = await listWorkspaces(client);
const recipes = await listRecipes(client);
const vessels = await listVessels(client);Errors from non-2xx responses throw ApiClientError (status + body).
External consumer quickstart
Install from npm (monorepo contributors use workspace file: links instead — see DEVELOPMENT.md):
npm install @umbraculum/[email protected] @umbraculum/[email protected]
# brewery reference vertical (separate package):
npm install @umbraculum/[email protected] @umbraculum/[email protected]
# plus @umbraculum/<code>[email protected] for each canonical domain you integrate withBrowse OpenAPI paths on the docs site before wiring calls:
- Platform catalog: docs.umbraculum.dev/openapi-platform
- Brewery add-on (reference vertical): docs.umbraculum.dev/openapi-brewery
Runnable sample (no monorepo clone): umbraculum-integrator-sample — copy of scripts/integrator-bearer-smoke.mjs. Maintainer sync: when api-client semver changes, update the sample repo quickstart.mjs and @umbraculum/* pins.
Subpath imports (tree-shaking friendly):
| Import | Use when |
|--------|----------|
| @umbraculum/api-client | Platform: auth, workspaces, health, billing, AI, ads, integrations, rendering |
| @umbraculum/brewery-api-client | Reference brewery vertical add-on (recipes, water, brew sessions, …) |
| @umbraculum/api-client/automation | Canonical automation hot paths |
| @umbraculum/api-client/pim | Canonical PIM hot paths |
| @umbraculum/api-client/mrp | Canonical MRP hot paths |
| @umbraculum/api-client/crp | Canonical CRP hot paths |
import { bearerTokenAuth, createApiClient, listWorkspaces } from "@umbraculum/api-client";
import { listVessels } from "@umbraculum/api-client/automation";
const client = createApiClient("https://your-host.example", bearerTokenAuth(() => process.env.API_TOKEN!));
const { workspaces } = await listWorkspaces(client);
const vessels = await listVessels(client);Wire authority remains @umbraculum/contracts parsers inside each facade — see @umbraculum/contracts.
Exports
createApiClient(baseUrl, auth, options?)options.fetch(optional): inject a cross-platformfetchimplementation
cookieAuth()(web)bearerTokenAuth(getToken)(native + Node)- Platform facades — see
src/platform/*(re-exported from main entry) @umbraculum/api-client/transport— shared JSON transport helpers for vertical facade packages@umbraculum/brewery-api-client— brewery add-on facades (packages/verticals/brewery/api-client)@umbraculum/api-client/automation— canonical automation facades@umbraculum/api-client/pim— canonical PIM facades@umbraculum/api-client/mrp— canonical MRP facades@umbraculum/api-client/crp— canonical CRP facadesPlatformOpenApiPathsand relatedcomponents/operationstype exports (generated from committed platform OpenAPI JSON)
OpenAPI codegen (Phase E)
Types under src/generated/ are produced from services/api/openapi/openapi.json and brewery.json:
npm run openapi:codegen -w @umbraculum/api-client # regenerate
npm run openapi:codegen:check -w @umbraculum/api-client # drift check (T1 OpenAPI slice)Run inside the Node container per docs/TESTING.md. Commit regenerated files whenever committed OpenAPI artifacts change.
Auth direction (current)
- Web: cookie-based sessions (
sidhttpOnly cookie). UsecookieAuth(). - Native: bearer-only. Use
bearerTokenAuth(getToken)and sendAuthorization: Bearer <token>. - Node: if used, treat it as bearer-only (do not rely on cookies).
Webview caveat (“already logged in”)
If we later want opening a whitelisted web page in a native webview to be already authenticated without additional token-handling, we must implement a bridging mechanism (e.g. cookie/session handoff or a token → webview session mechanism). This is not automatic with bearer-only native auth.
Build / test / lint (local)
This package ships runtime-safe JS + types:
- Runtime entrypoint:
dist/index.js - Type entrypoint:
dist/index.d.ts
Commands (run from repo root, container-friendly per the node-npm-container-only skill shipped by umbraculum-node-react-cursor-assistant):
- Build:
npm run build -w @umbraculum/api-clientornpm run build:packages - Test:
npm test -w @umbraculum/api-client(vitest in container; seedocs/TESTING.md). - Lint: covered by root
npm run lint. - Typecheck: handled by the per-workspace typecheck CI gate; see
docs/TYPING.md§"Per-workspace CI gate".
How it fits in
- Consumed by:
apps/web(cookie auth),apps/native(bearer auth); Node-side test harnesses and scripts that need to call the API as an authenticated user (also bearer). - Depends on:
@umbraculum/contracts(platform parsers),@umbraculum/*-contracts(canonical module parsers). Does not depend on Next.js, Expo, React Navigation, or any UI framework.
Status
Phase E complete (2026-06-01). Phase E5–E10 (2026-06): brewery water facades + native migration; web auth/me via fetchAuthMe; canonical module facade subpaths + web (automation|pim|mrp|crp)/ page migration; E8 brewery web tranche; E9 platform web tranche; E10 native platform tail (AdSlot, openWebFallback). Published on npm at 0.0.1 — see External consumer quickstart.
The "webview caveat" above is the one explicitly-flagged limitation: bearer-only native auth does not automatically give a webview an authenticated session — that requires a future bridging mechanism (cookie/session handoff or token-to-session exchange), which is on the trajectory but not yet implemented.
Further reading
docs/API-OPENAPI.md— OpenAPI catalogs + Phase E roadmapdocs/AUTH-STRATEGY.md— platform-wide auth direction (cookie web + bearer native + future webview bridge)docs/AUTH-HARDENING-ASSESSMENT.md— auth hardening review and findingsdocs/PLATFORM-ARCHITECTURE.md— platform visiondocs/DOCS-README-STANDARDS.md— module README standard this file conforms to@umbraculum/contracts— the typed response parsers this client returns
