Skip to content

Producer APIs

Production APIs can be used to create Creations:

Each production API takes in up to two arguments:

  1. The construct to be produced
  2. An object with properties from the construct’s context as well as System contexts

produceBase

Given a Base, creates an options object by running its produce().

produceBase takes in up to two argument:

  1. base (required): a Base
  2. settings (optional): any properties from a Base Context, except for take

For example, given this Base that declares an optional value option that defaults to "default", produceBase can run its produce() with any provided options:

import { createBase, produceBase } from "create";
import { z } from "zod";
const base = createBase({
options: {
value: z.string().optional(),
},
produce(options) {
return {
value: options.value ?? "default",
};
},
});
// { value: "default" }
await produceBase(base);
// { value: "override" }
await produceBase(base, {
options: {
value: "override",
},
});

options

Any number of options defined by the base.

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

import { Base } from "create";
import { z } from "zod";
declare const base: Base<{ name: z.ZodString }>;
await produceBase(base, {
options: {
name: "My Production",
},
});

produceBlock

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

produceBlock takes in up to two arguments:

  1. block (required): a Block
  2. settings (required): at least options, as well as any other properties from a Block Context

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

import { produceBlock } from "create";
import { base } from "./base";
const blockReadme = base.createBlock({
produce(options) {
return {
files: {
"README.md": `# ${options.title}`,
},
};
},
});
// { files: { "README.md": `# My App` }}
await produceBlock(blockReadme, { options: { title: "My App" } });

args

Any number of Args defined by the Block.

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

import { Block } from "create";
declare const block: Block<{ prefix: string }, { name: string }>;
await produceBlock(block, {
args: {
prefix: "The",
},
options: {
name: "Production",
},
});

created

Any Creations to simulate having been made from previously-produced Blocks.

options

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

For example, this Block is run with no Args and one name Option:

import { Block } from "create";
declare const block: Block<never, { name: string }>;
await produceBlock(block, {
options: {
name: "My Production",
},
});

produceInput

Given an Input, runs its produce() with any provided args.

produceInput takes in up to two arguments:

  1. input (required): an Input
  2. settings (required): at least options, as well as any other properties from an Input Context other than take

For example, this Input production reads data from an existing data.json file on disk:

import { createInput, produceInput } from "create";
const inputDataJson = createInput({
async produce({ fs }) {
return await JSON.parse(await fs.readFile("data.json"));
},
});
await produceInput(inputDataJson);

args

For example, this Input production reads data from a JSON file on disk by path:

import { createInput } from "create";
import { z } from "zod";
const inputJsonFile = createInput({
args: {
path: z.string(),
},
async produce({ args, fs }) {
return await JSON.parse(await fs.readFile(args.path));
},
});
await produceInput(inputJsonFile, {
args: "data.json",
});

producePreset

Given a Preset, creates a Creation output by running each of its Blocks produce().

producePreset takes in up to two arguments:

  1. preset (required): a Preset
  2. settings (required):
    • options (required): Base options to run with
    • optionsAugment (optional): a function to augment options from the Base
    • (optional) any other properties from a Block Context

producePreset returns a Promise for the Preset’s Creation. Both direct creations and indirect creations will be present.

For example, given this Preset that includes the block from produceBlock, producePreset can run its produce() with any provided options:

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

options

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

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

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

optionsAugment

A function that takes in the explicitly provided options and returns any remaining options.

Preset options are generated through three steps:

  1. Any options provided by producePreset’s second parameter’s options
  2. Calling the Preset’s Base’s produce method, if it exists
  3. Calling to an optional optionsAugment method of producePreset’s second parameter

In other words, optionsAugment runs after the Preset’s Base’s produce method, if it exists. This can be useful to prompt for any options not determined by produce().

For example, this optionsAugment uses a Node.js prompt to fill in a name option if it isn’t provided:

import { Preset, producePreset } from "create";
import readline from "node:readline/promises";
import { z } from "zod";
declare const preset: Preset<{ name: z.ZodString }>;
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
await producePreset(preset, {
optionsAugment({ options }) {
return {
name: options.name ?? (await rl.question("What is your name?")),
};
},
});

System Overrides

The properties specific to System Contexts can be overridden in production APIs.

This can be useful if you’d like a production’s Inputs to run in a virtual environment or otherwise augment system interactions.

For example, this Block production adds an authorization header to all network requests:

import { produceBlock } from "create";
import { blockUsingNetwork } from "./blockUsingNetwork";
await produceBlock(blockUsingNetwork, {
fetcher: async (...args) => {
const request = new Request(...args);
request.headers.set("Authorization", "Bearer ...");
return await fetch(request);
},
});