@canonical/anatomy-dsl
v0.2.2
Published
Anatomy DSL meta-model: TypeScript types mirroring the OWL ontology, and a YAML-to-Turtle transform
Downloads
641
Maintainers
Keywords
Readme
Anatomy DSL
A YAML-based DSL for representing design system component anatomies — platform-agnostic structural primitives that precede implementation.
Quick Example
---
node:
uri: global.component.button
styles:
layout.type: flow
layout.direction: horizontal
layout.align: center
spacing.internal: spacing/medium
appearance.background: color/surface/button
appearance.radius: radius/button
edges:
- node:
uri: global.subcomponent.button-icon
relation:
cardinality: "0..1"
slotName: icon
- node:
role: label text
relation:
cardinality: "1"
slotName: defaultStyle values are design token paths (spacing/medium, color/surface/button) — forward-slash delimited references resolved at runtime against the active theme. Primitives like flow and center are used for layout semantics that don't vary across themes.
Install
bun add -D @canonical/anatomy-dslUsage
import { parse } from "yaml";
import { parseAnatomyYAML, anatomyToTTL } from "@canonical/anatomy-dsl";
const raw = parse(readFileSync("Button.anatomy.yaml", "utf8"));
const spec = parseAnatomyYAML(raw);
const ttl = anatomyToTTL(spec);The button example above produces:
@prefix : <http://anatomy-dsl.example.org/ontology#> .
[] a :Specification ;
:rootNode [
a :NamedNode ;
:uri "global.component.button" ;
:hasStyle
[ :styleKey "layout.type" ; :styleValue "flow" ] ,
[ :styleKey "layout.direction" ; :styleValue "horizontal" ] ,
[ :styleKey "layout.align" ; :styleValue "center" ] ,
[ :styleKey "spacing.internal" ; :styleValue "spacing/medium" ] ,
[ :styleKey "appearance.background" ; :styleValue "color/surface/button" ] ,
[ :styleKey "appearance.radius" ; :styleValue "radius/button" ] ;
:hasEdge [
a :Edge ;
:edgeTarget [
a :NamedNode ;
:uri "global.subcomponent.button-icon"
] ;
:hasRelation [
a :Relation ;
:cardinality "0..1" ;
:slotName "icon"
]
] , [
a :Edge ;
:edgeTarget [
a :AnonymousNode ;
:role "label text"
] ;
:hasRelation [
a :Relation ;
:cardinality "1" ;
:slotName "default"
]
]
] .API
parseAnatomyYAML(raw: unknown): Specification
Converts a parsed YAML object (from any YAML library) into the typed Specification structure. Handles field mapping between the YAML format and the TypeScript types.
anatomyToTTL(spec: Specification): string
Pure function. Takes a Specification, returns a Turtle (RDF) string. No I/O, no side effects.
Types
All types mirror the OWL ontology exactly:
| Type | Description |
|------|-------------|
| Specification | Root — contains exactly one NamedNode |
| NamedNode | Design system entity with a uri |
| AnonymousNode | Structural element with a role |
| Node | NamedNode \| AnonymousNode (discriminated on type) |
| Edge | Reified parent→child relationship |
| Relation | Cardinality and optional slot name |
| Style | Reified key-value tuple |
| Switch | Polymorphic position (discriminator: props \| internal \| override) |
| SwitchCase | One alternative within a switch |
Repository Structure
definitions/ Turtle ontology (OWL) + SHACL shapes
schemas/ JSON Schema for validating .anatomy.yaml files
docs/ API reference (merged WD404 + WD404.1)
examples/ Example anatomy files (YAML + Turtle pairs)
src/ TypeScript types, parser, and transformScope
The Anatomy DSL describes structure only. It does not handle:
- Prop mapping — which props a component accepts and how they map to behaviour
- State or state machines — component states, transitions, or interaction logic
- Modifier descriptions — only design token references are supported, not semantic modifier definitions
Design Notes
Styles are modelled as reified key-value tuples (hasStyle [ styleKey "…" ; styleValue "…" ]). This keeps the ontology open-ended while remaining lossless. Frequently used style keys may be promoted to first-class datatype properties in a future version.
Specification Status
| Index | Title | Status | |---------|--------------------------|----------------| | WD404 | Anatomy DSL | Approved | | WD404.1 | Anatomy DSL — Addendum 1 | Pending Review |
