Jostraca code generation, made repeatable

Branch and loop in a generator

Use ordinary JavaScript control flow to decide what a generator emits.

Rendered from docs/how-to/branch-and-loop.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.

There is no conditional syntax to learn, because a component call is a function call. Use if, use for, use map.

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

const model = {
  name: 'acme',
  typescript: true,
  routes: ['health', 'login'],
}

await Jostraca().generate({ folder: './out' }, () => {
  Project({ folder: model.name }, () => {

    if (model.typescript) {
      File({ name: 'tsconfig.json' }, () => Content('{}\n'))
    }

    Folder({ name: 'routes' }, () => {
      for (const route of model.routes) {
        File({ name: route + (model.typescript ? '.ts' : '.js') }, () => {
          Content('export const name = "' + route + '"\n')
        })
      }
    })
  })
})
acme/routes/health.ts
acme/routes/login.ts
acme/tsconfig.json

To skip a component, do not call it. There is no no-op component to substitute—None exists internally and is not exported—so the branch is the mechanism.

each is available when you want its extras: it takes an object as readily as an array, it can sort, and it wraps scalars so a uniform callback works either way. A plain loop is otherwise fine and reads better.

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

const services = { beta: { port: 2 }, alpha: { port: 1 } }

await Jostraca().generate({ folder: './out' }, () => {
  Project({}, () => {
    File({ name: 'ports.txt' }, () => {
      each(services, (svc) => {
        Content(svc.key$ + '=' + svc.port + '\n')
      })
    })
  })
})

The generated ports.txt:

alpha=1
beta=2

Note the order. each visits object keys sorted, not in insertion order, so that the TypeScript and Go implementations produce the same bytes. svc.key$ is the key, stamped on by each.

See also#