@trainheroic-unofficial/dto
v3.6.0
Published
Domain DTOs and zod schemas for TrainHeroic — the single source of truth for shapes.
Readme
@trainheroic-unofficial/dto
Domain DTOs and zod schemas for the TrainHeroic API. This package is the single source of truth for request and response shapes. The SDK, the MCP tool layer, and the CLI all import their types from here.
Part of the trainheroic-unofficial workspace.
Contents
Install
Published to npm as a single ESM entry with type declarations; other packages in this
workspace depend on it via workspace:*. You can install it on its own:
npm install @trainheroic-unofficial/dtoIt depends on zod (v4), pulled in automatically as a dependency. Each schema
travels with its inferred type, so you validate and type from one import. .parse() throws a ZodError on bad data; use
.safeParse() if you want a result object instead.
import { workoutSpecSchema, type WorkoutSpec } from "@trainheroic-unofficial/dto";
// `input` is untrusted data (e.g. a parsed JSON file or request body).
const spec: WorkoutSpec = workoutSpecSchema.parse(input);It imports no node:* and touches no filesystem, so it runs in Node, browsers, and
Cloudflare workerd.
What's inside
Schemas come in two flavors. Input schemas are strict enough to validate user-supplied data such as workout specs, exercise-create bodies, and message drafts. Response schemas are deliberately tolerant: they use loose objects and accept a number or a numeric string for ids, so upstream API drift adds fields without breaking parsing.
src/ is organized by domain (common, exercise, workout, messaging, responses),
re-exported through index.ts. The central pieces:
idSchemanormalizes the API's number-or-string ids.workoutSpecSchema/WorkoutSpecis the input you hand to the SDK's workout encoder (the code injsthat turns a spec into TrainHeroic's payload): an optional top-level instruction plus an array of blocks, where each block carries an exercises array and each exercise references an exercise-library id.blockSpecSchemaandexerciseSpecSchemaare its parts;leaderboardSpecSchemacovers Red Zone leaderboards (TrainHeroic's competitive block type, where athletes are ranked on a score).- The read-back types (
ReadResult,ReadBlock,ReadExercise) describe a session decoded back out of the API into a readable shape, andAdvisorycarries the unit notes and warnings the encoder emits (for example, a prescription whose unit does not match the exercise's parameter type). - The
responsesmodule holds the tolerant schemas the SDK uses to sanity-check an API response before trusting it; these schemas accept unknown fields.
Develop
Run pnpm install once at the repo root (Node >= 24, pnpm 11), then from this package:
pnpm build # tsdown -> dist (ESM + .d.mts)
pnpm typecheck
pnpm test # vitest
pnpm exec vitest run test/workout.test.ts # one file