Skip to content

Stratum Runner APIs

Stratum generally reuses existing Bingo runner APIs when possible:

The bingo-stratum package provides additional runner APIs for other layers:

Each Stratum runner API allows up to two parameters:

  1. The construct to be produced
  2. An object with properties from the corresponding Stratum Context

runBlock

Given a Block, creates a Creation output by running its produce().

runBlock allows up to two parameters:

  1. block (required): a Block
  2. context (required): any properties from a Block Context

For example, given this Block that produces the start of a README.md file, runBlock can run its produce() with any provided options:

import { Base, createBlock } from "bingo-stratum";
declare const base: Base<{ title: string }>;
const blockReadme = base.createBlock({
produce({ options }) {
return {
files: {
"README.md": `# ${options.title}`,
},
};
},
});
// { files: { "README.md": `# My App` }}
runBlock(blockReadme, { options: { title: "My App" } });

addons

Any number of Addons defined by the Block.

For example, given this Block with a prefix Addon and a name Option, both can be specified in runBlock:

import { Base, createBlock } from "bingo-stratum";
declare const base: Base<{ name: string }>;
const blockPrefixedReadme = base.createBlock({
addons: {
prefix: z.string().default("My"),
},
produce({ addons, options }) {
return {
files: {
"README.md": `# ${addons.prefix} ${options.title}`,
},
};
},
});
// { files: { "README.md": `# The App` }}
runBlock(blockPrefixedReadme, {
addons: {
prefix: "The",
},
options: {
name: "App",
},
});

offline

Whether to hint to the Block not to make network requests.

This is equivalent to the --offline CLI flag. If provided, Input Context fetchers will be hinted not to make any network requests.

For example, this Base is told to run offline:

import { runBlock } from "bingo";
import { base } from "./base";
const blockInstallDependencies = base.createBlock({
produce({ offline }) {
return {
scripts: [offline ? "pnpm install --offline" : "pnpm install"],
};
},
});
// { scripts: ["pnpm install"] }
runBlock(blockInstallDependencies);
// { scripts: ["pnpm install --offline"] }
runBlock(blockInstallDependencies, { offline: true });

options

Any number of options defined by the Block’s Base.

For example, this Block is run with one repository option:

import { createBase } from "bingo-stratum";
import { z } from "zod";
const base = createBase({
options: {
repository: z.string(),
},
});
const blockPackageJson = createBlock({
produce() {
return {
files: {
"package.json": JSON.stringify({ name: options.repository }),
},
};
},
});
// { files: { "package.json": `{repository":"my-app"}` } }
runBlock(block, {
options: {
repository: "my-app",
},
});

runPreset

Given a Preset, runs a Creation output by calling each of its Blocks produce().

runPreset allows up to two parameters:

  1. preset (required): a Preset
  2. context (optional): any of the following properties

runPreset returns the Preset’s Creation, including both direct creations and indirect creations.

For example, given this Preset that includes the blockReadme from runBlock, runPreset can run its produce() with any provided options:

import { producePreset } from "bingo";
import { base } from "./base";
import { blockReadme } from "./blockReadme";
const preset = base.createPreset({
name: "Example",
blocks: [blockReadme],
});
// { files: { "README.md": `# My App` } }
producePreset(preset, {
options: { title: "My App" },
});

addons

Any of Addons to pass to the Preset’s Blocks.

For example, this production adds a "generated" Addon to a Prettier Block:

import { Preset, runPreset } from "bingo";
import { z } from "zod";
import { blockPrettier } from "./blockPrettier";
declare const preset: Preset;
await runPreset(preset, {
addons: [blockPrettier({ ignores: ["generated"] })],
options: {
name: "My Production",
},
preset: "example",
});

blocks

Any Blocks to add and/or remove.

For example, this production swaps in a Jest Block instead of a Vitest Block:

import { Preset, runPreset } from "bingo";
import { z } from "zod";
import { blockJest } from "./blockJest";
import { blockVitest } from "./blockVitest";
declare const preset: Preset;
await runPreset(preset, {
blocks: {
add: [blockJest],
exclude: [blockVitest],
},
options: {
name: "My Production",
},
preset: "example",
});

See Configurations > blocks for how this is used.

offline

Whether to hint to the Preset not to make network requests.

This is equivalent to the --offline CLI flag. If provided, Input Context fetchers will be hinted not to make any network requests.

For example, this Preset is told to run offline:

import { Preset, runPreset } from "bingo";
import { z } from "zod";
declare const preset: Preset;
await runPreset(preset, {
offline: true,
options: {},
preset: "example",
});

options

Any options defined by the Preset’s Base.

This must include all required options from the Base. It may also include any other optional Options.

For example, this Preset is run with a name option:

import { Preset, runPreset } from "bingo";
import { z } from "zod";
declare const preset: Preset<{ name: z.ZodString }>;
await runPreset(preset, {
options: {
name: "My Production",
},
preset: "example",
});

Adding Base Options

Although Presets are associated with Bases, running runPreset does not automatically infer default option values. If you want to include the inferred options from a Preset’s Base you’ll have to call the prepareOptions API first yourself.

For example, this directly passes produced Options from a Base to a Preset:

import { base } from "./base";
import { preset } from "./preset";
const options = await prepareBase(base);
await runPreset(preset, { options });
Made with 💝 in Boston by Josh Goldberg.