Skip to content

Contexts

Context objects are provided to Blocks, Inputs, and Bases. Each contains shared helper functions and information.

Base Contexts

The Context object provided to the produce object of Bases.

options

Any manually provided values as described by the Base’s options.

Base produce() methods are designed to fill in any options not manually provided by the user. Options that are manually provided are available under the Base Context’s options.

For example, this Base defaults an name option to a kebab-case version of its title option:

export const base = createBase({
options: {
name: z.string().optional(),
title: z.string(),
},
produce({ options }) {
return {
name: options.title.toLowerCase().replaceAll(" ", "-"),
};
},
});

take

Executes an Input. This is the same as Input Contexts’ take.

Block Contexts

The Context object provided to the produce object of Blocks.

addons

Any Block Addons that have been provided by other Blocks.

For example, this Gitignore Block defines an ignores Addon that other Blocks can use to add to its created .gitignore file:

export const blockGitignore = base.createBlock({
addons: {
ignores: z.array(z.string()).default([]),
},
produce({ addons }) {
return {
files: {
".gitignore": ["/node_modules", ...addons.ignores].join("\n"),
},
};
},
});

options

User-provided values as described by the parent Base.

Bases fill in option values before running Blocks. Each Block created by a Base will run with the same set of options.

For example, this Base defines a title option, which is then used by a Block to print a README.md heading:

import { createBase } from "create";
export const base = createBase({
options: {
name: z.string(),
},
});

Input Contexts

The Context object provided to the produce object of Inputs.

args

The arguments provided to this input from its take call.

These (for now) must be an object storing each arg as a Zod type.

For example, a minimal Input that combines two numbers:

import { createInput } from "create";
import { z } from "zod";
export const inputFromFile = createInput({
args: {
a: z.number(),
b: z.number(),
},
async produce({ args }) {
return args.a + args.b;
},
});

Unlike that minimal example, Inputs generally use one or more of the following properties to read from the user’s file system and/or network.

fetcher

The global fetch function, to make network calls.

For example, an Input that retrieves a random Cat fact:

import { createInput } from "create";
export const inputCatFact = createInput({
async produce({ fetcher }) {
const response = await fetcher("https://catfact.ninja/fact");
const data = (await response.json()) as { fact: string };
return data.fact;
},
});

fs

A virtual wrapper around the file system.

For now, the fs object contains a single property:

  • readFile: Given a file path, returns a Promise for its contents as a string

For example, this input reads the contents of a file from disk as a string:

import { createInput } from "create";
import { z } from "zod";
export const inputFromFile = createInput({
args: {
fileName: z.string(),
},
async produce({ args, fs }) {
return (await fs.readFile(args.fileName)).toString();
},
});

runner

An execa shell script to run commands.

This is useful for data that’s easiest to pull from the CLI.

For example, an Input that retrieves the current Git user’s email:

import { createInput } from "create";
export const inputGitUserEmail = createInput({
async produce({ runner }) {
return (await runner("git config user.email")).stdout;
},
});

take

Executes an Input.

The take function is provided to both Blocks and Inputs so that they can run another Input with the same Context they’re running in.

For example, this Block uses take to run Inputs that reads from a local file and run npm whoami to make sure the user is listed in an AUTHORS.md file:

import { base } from "./base";
import { inputFromFile } from "./inputFromFile";
import { inputNpmWhoami } from "./inputNpmWhoami";
const fileName = "AUTHORS.md";
export const blockFileModified = base.createBlock({
async produce({ take }) {
const existing = await take(inputFromFile, { fileName });
const author = await take(inputNpmWhoami);
return {
files: {
[fileName]: existing.includes(`${author}\n`)
? existing
: `${existing}\n${author}`,
},
};
},
});

System Contexts

The Context object provided to producer APIs.

fetcher

The global fetch function, to make network calls. This is the same as Input Contexts’ fetcher.

fs

A virtual wrapper around the file system. This is an expanded version of Input Contexts’ fs.

System fs objects include the following properties:

  • readFile: Given a file path, returns a Promise for its contents as a string
  • writeDirectory: Given a directory path, returns a Promise for creating a directory there if one doesn’t exist
  • writeFile: Given a file path and text contents, returns a Promise for writing to the file

options

Any values as described by the Base’s options for the entity being produced.

runner

An execa shell script to run commands. This is an the same as Input Contexts’ runner.