@genzai/prettier
v0.1.2
Published
Prettier formatting middleware for code generation
Maintainers
Readme
@genzai/prettier
Prettier formatting middleware for automatic code formatting during generation.
Installation
npm install @genzai/prettier @genzai/core prettier
# or
pnpm add @genzai/prettier @genzai/core prettier
# or
yarn add @genzai/prettier @genzai/core prettierNote: prettier is a peer dependency and must be installed separately.
Overview
@genzai/prettier provides middleware that automatically formats generated code using Prettier. This ensures all generated files follow consistent formatting standards without manual intervention.
Features
- ✨ Automatic Formatting: Format code as it's generated
- 🎨 Prettier Integration: Uses your project's Prettier configuration
- 🔌 Drop-in Middleware: Easy integration with
@genzai/core - 📝 Language Support: Works with all languages Prettier supports
Quick Start
import { write } from "@genzai/core";
import { prettierMiddleware } from "@genzai/prettier";
await write(plan, "./output", [], {
middlewares: [prettierMiddleware],
});API Reference
prettierMiddleware
Middleware that formats file content using Prettier.
import { prettierMiddleware } from "@genzai/prettier";
import { write } from "@genzai/core";
await write(nodes, "./output", [], {
middlewares: [prettierMiddleware],
});Usage Examples
Basic Usage
import { file, folder, write } from "@genzai/core";
import { prettierMiddleware } from "@genzai/prettier";
const generator = folder(
"my-project",
file("index.ts", () => `
export const greeting="Hello";
function test(){return true;}
`)
);
const plan = await generator({});
await write(plan, "./output", [], {
middlewares: [prettierMiddleware],
});
// Output will be properly formatted:
// export const greeting = "Hello";
// function test() {
// return true;
// }With Multiple Middleware
import { write } from "@genzai/core";
import { prettierMiddleware } from "@genzai/prettier";
import { slotMiddleware } from "@genzai/slots";
import { loggingMiddleware } from "@genzai/logging";
await write(plan, "./output", [], {
middlewares: [
loggingMiddleware,
slotMiddleware,
prettierMiddleware, // Format after slots are applied
],
});Combining with Slots
import { file } from "@genzai/core";
import { slot } from "@genzai/slots";
import { prettierMiddleware } from "@genzai/prettier";
import { slotMiddleware } from "@genzai/slots";
const componentFile = file(
"Component.tsx",
() => `
import React from 'react';
export const Component = () => {
${slot.begin("implementation")}
return <div>Default</div>;
${slot.end}
};
`
);
// Both generated and slot content will be formatted
await write([componentFile], "./output", [], {
middlewares: [slotMiddleware, prettierMiddleware],
});Configuration
The middleware automatically uses your project's Prettier configuration:
.prettierrc.prettierrc.json.prettierrc.ymlprettier.config.jspackage.json(prettierfield)
If no configuration is found, Prettier's defaults are used.
Example .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80
}How It Works
- Context Check: Verifies the node is a file (folders are skipped)
- Format Detection: Prettier infers the parser from file extension
- Format Content: Applies formatting to the content
- Pass Through: Sends formatted content to next middleware
Current Status
⚠️ Note: The current implementation is a placeholder. The actual formatting logic is commented out and needs to be implemented.
To implement formatting, uncomment and complete the code in middleware.ts:
export const prettierMiddleware: Middleware = async (context, next) => {
if (context.nodeType === "folder") return next(context);
// Implement formatting here
const prettier = await import("prettier");
const formatted = await prettier.format(context.content, {
filepath: context.path,
});
return next({
...context,
content: formatted,
});
};Best Practices
- Place Last: Put prettier middleware last so it formats the final output
- Consistent Config: Use the same Prettier config for generated and manual code
- File Extensions: Ensure files have correct extensions for parser detection
- Error Handling: Consider wrapping in try-catch for parse errors
Middleware Order
Order matters! Place prettier middleware strategically:
// ✅ Good: Format after all content modifications
middlewares: [
loggingMiddleware,
slotMiddleware,
prettierMiddleware, // Last, formats final content
]
// ❌ Less ideal: Formatting might be overridden
middlewares: [
prettierMiddleware, // Formats too early
slotMiddleware, // Might add unformatted content
]Language Support
Prettier supports many languages out of the box:
- JavaScript/TypeScript
- JSX/TSX
- JSON
- CSS/SCSS/Less
- HTML
- Markdown
- YAML
- GraphQL
- And more...
Error Handling
If formatting fails (e.g., syntax errors), consider:
export const prettierMiddleware: Middleware = async (context, next) => {
if (context.nodeType === "folder") return next(context);
try {
const prettier = await import("prettier");
const formatted = await prettier.format(context.content, {
filepath: context.path,
});
return next({
...context,
content: formatted,
});
} catch (error) {
console.warn(`Failed to format ${context.path}:`, error);
// Continue with unformatted content
return next(context);
}
};Performance Considerations
- Formatting adds time to generation (usually minimal)
- Prettier is fast but runs on every file
- Consider skipping formatting for large binary-like files
- Cache Prettier config resolution if possible
Related Packages
@genzai/core- Core generation framework (required)@genzai/slots- Slot-based content preservation@genzai/logging- Logging middleware@genzai/merge-strategy- File conflict resolution
Dependencies
- Peer Dependency:
prettier(^3.0.0)
License
MIT
