pnpm (TypeScript)

Identical to the npm recipe in every file -- same package.json, same tsconfig.json -- so the only difference is the package manager. pnpm's content-addressed store and strict node_modules layout change nothing about how generated DSDL is consumed.

Language TypeScript
Build system pnpm
Idiom B -- your project owns the manifest
Regeneration None -- regeneration is an explicit step

Notes

Generated TypeScript is ordinary TypeScript source; nothing about it interacts with how your dependencies are laid out on disk, so a package manager with a strict, non-flat node_modules needs no special handling.

pnpm is not in the toolshed image, but corepack is, and corepack enable pnpm is the whole of the provisioning. See the npm recipe for why the generated tree is compiled as source rather than installed as a package.

Prerequisites

Tool Why
pnpm installs the TypeScript compiler and runs the scripts
node runs the compiled round-trip program

Commands

Run these from the recipe directory, with dsdl/ and src/ copied alongside it. This is the exact sequence CI runs.

# generate
dsdlc --target-language ts dsdl/lanyard --ts-module lanyard --outdir generated
# install
pnpm install --silent
# build
pnpm run --silent build
# round-trip
pnpm run --silent start

The types this builds

The whole lanyard namespace -- twenty-four definitions, browsable from the showroom overview, where each one is paired with its wire-layout facts and a declaration excerpt in every language.

The build files

package.json

{
  "name": "lanyard-roundtrip",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "build": "tsc -p .",
    "start": "node dist/src/ts/roundtrip.js"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "typescript": "^5.6.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es2022",
    // commonjs, not esnext, and this is the load-bearing choice.
    //
    // The generated files import each other without file extensions ("./reading_1_0"). Node's ESM
    // resolver requires extensions, so an ESM build emits JavaScript that Node then refuses to load
    // -- you would need a bundler to rewrite the specifiers. The CommonJS emit resolves them at
    // require() time and runs as-is, which is why this is a two-command build with no bundler.
    "module": "commonjs",
    "moduleResolution": "node",
    "strict": true,
    "outDir": "dist",
    "skipLibCheck": true
  },
  "include": ["src/ts/**/*.ts", "generated/**/*.ts"]
}