Skip to content

Blocks

A Block defines the logic to create a portion of a repository. Each Block is associated with a parent Base. Blocks can then be listed in Presets associated with the same base.

Production

Blocks define their logic for created repository portions in a produce() function. produce() returns a Creation describing any produced output.

When create scaffolds a repository from a Preset, it merges together the produced outputs from its listed Blocks.

For example, this Block describes creating a .nvmrc file:

import { base } from "./base";
export const blockNvmrc = base.createBlock({
produce() {
return {
files: {
".nvmrc": "20.12.2",
},
};
},
});

That blockNvmrc can then be listed in a Preset’s blocks array:

import { base } from "./base";
import { blockNvmrc } from "./blockNvmrc";
export const presetVersioned = base.createPreset({
blocks: [
blockNvmrc,
// ...
],
});

That presetVersioned would then produce an .nvmrc file with text content 20.12.2 when run.

.nvmrc
20.12.2

Options

Each Block runs with the options defined by its parent Base.

For example, a Base with a name option could create a Block that generates part of a README.md file:

import { base } from "./base";
export const blockREADME = base.createBlock({
produce({ options }) {
return {
files: {
"README.md": `# ${options.name}`,
},
};
},
});

If create is run with --name My Repository, a README.md would be generated with that as its heading:

README.md
# My Repository

Addons

Blocks can define additional optional data called “Addons” that they can be receive from other Blocks. Blocks define Addons as the properties for a Zod object schema and then receive them in their context.

For example, this Block takes in a string array under a names Addon, to be printed in a names.txt file:

import { z } from "zod";
import { base } from "./base";
export const blockNames = base.createBlock({
addons: {
names: z.array(z.string()).default([]),
},
async produce({ addons }) {
return {
files: {
"names.txt": addons.names.join("\n"),
},
};
},
});

Other Blocks may produce Addons to be given to any other Blocks. These Addons will be merged together when a Preset containing the Blocks is run.

For example, this FruitNames Block composes Addons to the Names Block:

import { base } from "./base";
export const blockNames = base.createBlock({
async produce() {
return {
addons: [
blockNames({
names: ["apple", "banana", "cherry"],
}),
],
};
},
});

A Preset containing both Blocks would then produce a names.txt file with those three names as lines in its text:

names.txt
apple
banana
cherry

APIs