Skip to content

Express

import express from 'express';
import { atlasRouter, unauthenticated } from '@ts-atlas/core/express';
const app = express();
app.use(atlasRouter(runtime, {
identify, // (req) => Actor | null; throw unauthenticated() for bad credentials
system, // the loaded system: file names and line counts in the map
map: (req) => isOperator(req), // GET /atlas/map, off by default
onError: (error) => console.error(error), // every error the router swallows
}));
Route What
POST /commands/:type Dispatches { ...body, type } as the identified actor. The body is the DispatchResult. Header Atlas-Await waits for views (views, view names, or all).
GET /queries/:name Runs a declared query. ?input=<json> is the whole input; otherwise every parameter except after and limit is a field, typed by the declared input (numbers, booleans, repeated params for arrays). The body is the QueryResult.
GET /atlas/map Mounted only when map is set. The map is the system’s blueprint (every command with its input shape and access, internal ones included), so it is off by default.

statusOf(code) (exported) maps rejection codes to statuses: accepted or ok 200, unknown-command and unknown-query 404, invalid-input 400, unauthenticated 401, forbidden 403, conflict 409, store-failed 503, internal-error 500, store-rejected and any other (domain) code 422.

Option Default Meaning
identify(req) none (everyone anonymous) The identity port: returns an Actor or null. Throw unauthenticated() for credentials that are not valid (401). Any other throw is an outage: 503 store-failed, reported to onError.
identifyErrors 'unavailable' 'unauthenticated' answers 401 for any throw, as before 0.5.0.
system the runtime’s capabilities The loaded system, for file names in the map.
onError(error, req) none Receives the error behind a 500 and an identify outage. Its own throws are ignored.
map off true mounts it for everyone; a function (req) => boolean | Promise<boolean> gates it (false answers 403 forbidden).
allowAwait 'authenticated' Whose Atlas-Await is honored: 'authenticated', 'all' or 'none'. An ignored header still runs the command; the answer has no awaited field.
awaitTimeoutMs the runtime’s 2000 Bounds an honored wait.

Every route is an error boundary: whatever throws (the runtime, identify, a body the JSON parser refuses) answers a rejection with no message: internal-error (500) for the unexpected, invalid-input (400) for an unparseable body. Exception text never reaches the client; read it in onError or the runtime trace.

isUnauthenticated(error) tells whether an error was made by unauthenticated().

A controller is a few lines: resolve the actor from your auth, await runtime.dispatch({ ...body, type }, { actor }), and map outcome and code to a status with statusOf.