@sourapp/station-contract
v0.1.1
Published
Public station-facing API contract for the SourApp station (TUI + desktop). Defines only the narrow surface stations need; does not re-export any internal SourApp contract, DB, or schemas.
Readme
@sourapp/station-contract
Type-safe API contract for the SourApp station endpoints — Zod schemas, route definitions, and socket event names for the surface a station pairs with.
This package is the typed wire definition between SourApp and any client acting as a station (print server, kiosk, custom terminal). It uses ts-rest to keep the client and server in lockstep, and exports the same Zod schemas so you can validate payloads on both sides.
You generally do not install this directly — it ships as a dependency of @sourapp/station. Install it directly only if you're building your own station client.
Install
npm install @sourapp/station-contract zodRequires Node.js 20+. zod is a peer dependency.
What's in it
- Endpoint definitions for pairing (device-code flow), token refresh, registration, heartbeats, print job pull, status reporting.
- Zod schemas for every request and response —
StationFingerprint,StationPrinter,Station,PrintJobPayload,StationTokens, etc. - Socket event names for the realtime channel a station subscribes to.
Usage
import {
stationContract,
type StationFingerprint,
type PrintJobPayload,
StationSocketEvents,
} from "@sourapp/station-contract";
// stationContract is a ts-rest contract; types flow through automatically.
type InitiateBody = (typeof stationContract.initiateDeviceCode.body)["_type"];
// Use the schemas directly for runtime validation
import { StationFingerprintSchema } from "@sourapp/station-contract";
const fp: StationFingerprint = StationFingerprintSchema.parse(input);If you want a ts-rest client:
import { initClient } from "@ts-rest/core";
import { stationContract } from "@sourapp/station-contract";
const client = initClient(stationContract, {
baseUrl: "https://api.sour.systems",
baseHeaders: {},
});
const { body } = await client.initiateDeviceCode({
body: { fingerprint: fp },
});
// body.user_code, body.verification_uri, body.device_code, ...Endpoints
All routes live under /station/*. The base URL is https://api.sour.systems in production.
| Route | Method | Auth | Purpose |
| ------------------------------------ | ------ | --------- | --------------------------------------------------- |
| /station/device-code | POST | none | Begin a browser-approval pairing |
| /station/device-code/poll | POST | none | Poll for approval; returns tokens on success |
| /station/token/refresh | POST | none | Rotate refresh + access tokens |
| /station/register | POST | station | Submit hardware + printer info after pairing |
| /station/heartbeat | POST | station | Keep the station marked as online |
| /station/printers | POST | station | Update the server's view of attached printers |
| /station/print-jobs/pull | GET | station | Claim the next queued print job for this station |
| /station/print-jobs/:jobId/status | POST | station | Report a job's outcome (done / failed / cancelled) |
| /station/me | GET | station | Fetch the station's own configuration |
| /station/logout | POST | station | Revoke this station's tokens |
"Station auth" means a Bearer token issued at pairing time. See @sourapp/station for the reference client implementation.
Permission scope
Station tokens are narrowly scoped — they can heartbeat, receive print jobs, and read their own configuration. They cannot read or modify tickets, customers, inventory, other stations, or act as a user. The capability set is enforced server-side and shown to the human approver at pairing time.
Versioning
This package follows semver. A new minor version is published whenever the SourApp station API gains a backwards-compatible endpoint; a major version when a breaking change ships. Pin to a minor range if you're embedding this in another product.
License
MIT
