aontu

Inject values from the host program

Fill `$name` variables from the calling program to parameterise a model from code.

Rendered from docs/how-to/inject-host-values.md in the engine repository, where a correction belongs, and where the test suite executes every example on this page.

A $name with no dot is not a path: it names a value the calling program supplies. This is how a model takes parameters from code (a port from the environment, a region from a flag) without a second source file.

In TypeScript, set variables on a context and pass it as the third argument:

import { Aontu } from 'aontu'
import { IntegerVal } from 'aontu/dist/val/IntegerVal'

const aontu = new Aontu()
const ctx = aontu.ctx()
ctx.vars.port = new IntegerVal({ peg: 8080 })

aontu.generate('server: { port: $port }', undefined, ctx)
// { server: { port: 8080 } }

In Go, build a map[string]Val with the exported constructors (NewInteger, NewString, NewNumber, NewBoolean, NewNull, NewScalarKind, NewMap, NewList, and the exact-leaf pair NewBigInteger / NewBigDecimal) and use the Vars variants:

vars := map[string]aontu.Val{"port": aontu.NewInteger(8080)}
out, err := aontu.New().GenerateVars("server: { port: $port }", vars)
// out == map[string]any{"server": map[string]any{"port": 8080}}

A $name nobody supplied is refused, under its own error code:

$ echo 'server: port: $port' | aontu
[aontu/unknown_var]: Cannot unify values at path $.server.port
...
$ echo $?
1

The similar-looking [aontu/no_path]: Cannot resolve value at path … is the path case: a $.reference that names nothing in the document. Two different mistakes, two different codes (read a conflict error has the anatomy).

An injected variable is a value like any other, so it unifies rather than overrides: server: { port: $port } beside server: { port: integer & max(65535) } checks the injected value against the constraint, and a bad injection fails with a located conflict. That makes variables a safe seam: the document keeps its say. The exact-leaf constructors take a bigint, a Decimal, or the digits as text, never a host number, which binary64 has already rounded before the library could look (exact-input constructors).

The constructor tables are in the API reference, for TypeScript and Go; the language rule is Variables $name.