Skip to content

Getting started

This walks through the TypeScript reference implementation, openbody-ts: validate an OpenBody record against the published JSON Schema, then run it through the canonical-normalization pipeline (conformance/EQUIVALENCE.md — which the reference implementation implements as the conformance suite’s equivalence oracle). A reference implementation is one implementation, not normative — SPEC.md is the source of truth.

Install

Terminal window
npm install @openbody/openbody-ts

Requires Node ≥ 20.19. The published package bundles the schema + registry snapshots it needs, so there’s nothing else to set up. Working from a git checkout instead — to contribute, or to run the conformance vectors against ../openbody — is covered by the repo’s CONTRIBUTING.md and Run the conformance vectors.

Validate a record

validate(record) checks a record against the OpenBody JSON Schema (Draft 2020-12, SPEC §§4–7). Validate wire records — not the canonical form the equivalence method produces, which is a comparison artifact, not the binding.

import { validate } from "@openbody/openbody-ts";
// A minimal reps-scored WorkUnit — the one required-tier element of Training core (§3.3).
const workUnit = {
id: "wu-squat-1",
recordType: "WorkUnit",
subject: "subj-001",
exerciseRef: "squat.barbell.high-bar",
scoring: "reps",
prescription: { reps: 5, load: { value: 100, unit: "kg", basis: "marked_weight" } },
};
const result = validate(workUnit);
console.log(result); // → valid / list of schema errors

Normalize & compare

normalizeDocument(doc) runs the canonical-normalization pipeline (conformance/EQUIVALENCE.md) — number → lowest-terms fixed-point, unit canonicalization, scalar→Target expansion, ExerciseRef fold, sets expansion, deterministic id assignment, flatten + partOf, status default, then RFC 8785 serialization — producing a sorted set of canonical record byte strings. equivalent(a, b) is true iff two documents normalize to the same set.

import { equivalent } from "@openbody/openbody-ts";
// The nested document and the flat + partOf encoding of one structure are equivalent (§7.2).
console.log(equivalent(nestedDoc, flatDoc)); // → true

Next

  • Run the conformance vectors against the reference implementation.
  • Concepts — the data model, the two pillars, exercise identity, canonicalization.
  • Mapping guides — turn a real export into OpenBody records: ten formats and counting, from Hevy and Strava to Fitbit Takeout and theCrag — see the supported-formats matrix. The mappers also resolve source exercise names to canonical registry ids where the registry covers them, falling back to a lossless opaque string otherwise.