@genzai/templates
v0.1.8
Published
Directory-based project templates for Genzai
Maintainers
Readme
@genzai/templates
Directory-based project templates for Genzai.
Overview
@genzai/templates provides a simple way to create code generators from directory structures. It walks template directories, executes .gen.ts generator files, and copies static files, returning a standard Generator that works seamlessly with Genzai's generate() function.
Installation
npm install @genzai/templates @genzai/core tsxNote: tsx is required as a peer dependency to load TypeScript generator files at runtime.
Usage
Basic Example
import { generate } from "@genzai/core";
import { template } from "@genzai/templates";
// Create a generator that uses template
const myAppGenerator = async (ctx) => template("./templates/my-app", ctx);
// Use it like any other generator
await generate(myAppGenerator, "./output", {
projectName: "my-app",
apiUrl: "https://api.example.com",
});Template Directory Structure
A template directory can contain:
- Static files: Copied as-is to the output
.gen.tsfiles: TypeScript files that export Generators- Directories: Recursively processed
Example structure:
templates/my-app/
.genzai.json # Optional config for regeneration strategies
src/
index.ts # Static - copied as-is
config.gen.ts # Dynamic - executes generator
components/
Button.tsx # Static
package.json.gen.ts # Dynamic
README.md # Static
.gitignore # StaticConfiguring Regeneration Strategies
For static files that can't contain JSDoc markers (JSON, markdown, etc.), use a .genzai.json config file in the template root:
{
"files": {
"package.json": { "regenerationStrategy": "preserve-edits" },
"src/**/*.ts": { "regenerationStrategy": "overwrite" }
},
"default": { "regenerationStrategy": "overwrite" }
}Pattern matching:
- Exact paths:
"package.json" - Glob patterns:
"src/**/*.ts"(matches any.tsfile insrc/) *matches any characters except/**matches any characters including/
The config sets meta.regenerationStrategy on static file nodes, which is then used by regenerationStrategyMiddleware from @genzai/core.
Creating Generator Files (.gen.ts)
Generator files must export a default Generator function that returns an array of nodes:
// package.json.gen.ts
import { file } from "@genzai/core";
interface Context {
projectName: string;
dependencies: Record<string, string>;
}
export default (ctx: Context) => [
file("package.json", () =>
JSON.stringify(
{
name: ctx.projectName,
version: "1.0.0",
dependencies: ctx.dependencies,
},
null,
2
)
),
];Composing with Other Generators
Templates can be composed with other Genzai generators:
import { generate, folder, file } from "@genzai/core";
import { template } from "@genzai/templates";
const myGenerator = async (ctx) => [
folder("project", [
...(await template("./templates/base", ctx)), // Load from directory
file("custom.ts", () => "// custom"), // Add extra file
]),
];
await generate(myGenerator, "./output", context);With Middleware
Templates work seamlessly with Genzai middleware:
import { generate, defaultMiddleware } from "@genzai/core";
import { template } from "@genzai/templates";
import { prettierMiddleware } from "@genzai/prettier";
import { slotMiddleware } from "@genzai/slots";
const myAppGenerator = async (ctx) => template("./templates/my-app", ctx);
await generate(
myAppGenerator,
"./output",
context,
{
middlewares: [...defaultMiddleware, slotMiddleware, prettierMiddleware],
}
);API
template(templatePath, context)
Loads a template directory and returns nodes.
Parameters:
templatePath(string): Path to template directory (absolute or relative)context(C): Context object to pass to.gen.tsgenerators
Returns:
Promise<Node[]>: A promise that resolves to an array of nodes
Throws:
- Error if path is empty or not a string
- Error if path doesn't exist or isn't a directory
- Error if
.gen.tsfiles don't export valid Generators
Example:
const myGenerator = async (ctx) => template("./templates/my-app", ctx);
await generate(myGenerator, "./output", context);How It Works
- Directory Walking: Recursively walks the template directory
- File Processing:
.gen.tsfiles: Dynamically loaded withtsxand executed as async Generators with the provided context- Directories: Recursively processed as folders
- Other files: Copied as-is using lazy content loading
- Output: Returns an array of nodes that can be used in any generator
Error Handling
The package provides comprehensive validation and error messages:
- Template path validation (exists, is directory, readable)
- Generator file validation (valid TypeScript, exports default function)
- File system error handling with context
- Detailed error messages with file paths
License
MIT
