Jostraca code generation, made repeatable

Insert values from your model

Substitute values from the data model into file content with the double-dollar syntax.

Rendered from docs/how-to/insert-model-values.md in the generator repository — where a correction belongs, and where the test suite runs every example on this page or states why it does not.

Pass a model to Jostraca(), and write $$path$$ in content. The path is resolved against the model and the value is substituted as text.

import { Jostraca, Project, File, Content } from 'jostraca'

const model = {
  service: { name: 'acme-api', port: 8080 },
  owner: { team: 'platform' },
}

const jostraca = Jostraca({ model })

await jostraca.generate({ folder: './out' }, () => {
  Project({}, () => {
    File({ name: 'config.json' }, () => {
      Content('{\n')
      Content('  "name": "$$service.name$$",\n')
      Content('  "port": $$service.port$$,\n')
      Content('  "team": "$$owner.team$$"\n')
      Content('}\n')
    })
  })
})

The generated config.json:

{
  "name": "acme-api",
  "port": 8080,
  "team": "platform"
}

The port came out unquoted because substitution inserts the value as text and the surrounding JSON was already written the way it wanted to be. Quoting is yours to control, not the template’s.

Three things the syntax does not do, all deliberate:

  • No conditionals, loops or expressions. The code around the content is a programming language already; use it.
  • No substitution in names. A file or folder name is an ordinary JavaScript expression, so build it with the language: File({name: model.service.name + '.json'}).
  • No blanking on a miss. An unresolved $$nope$$ is left in the output verbatim, so a typo is visible instead of silently gone.

For one value that is not in the model, pass extra—remembering that Content’s second positional argument is children, so this needs the props form:

import { Jostraca, Project, File, Content } from 'jostraca'

const jostraca = Jostraca({ model: { n: 5 } })

await jostraca.generate({ folder: './out' }, () => {
  Project({}, () => {
    File({ name: 'extra.txt' }, () => {
      Content({ src: 'n=$$n$$ m=$$m$$\n', extra: { m: 9 } })
    })
  })
})

The generated extra.txt:

n=5 m=9

See also#