npm package: @genzai/prettier
Description: Prettier formatting middleware for code generation
Latest version: 0.1.2

# @genzai/prettier

Prettier formatting middleware for automatic code formatting during generation.

## Installation

```bash
npm install @genzai/prettier @genzai/core prettier
# or
pnpm add @genzai/prettier @genzai/core prettier
# or
yarn add @genzai/prettier @genzai/core prettier
```

**Note**: `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

```typescript
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.

```typescript
import { prettierMiddleware } from "@genzai/prettier";
import { write } from "@genzai/core";

await write(nodes, "./output", [], {
  middlewares: [prettierMiddleware],
});
```

## Usage Examples

### Basic Usage

```typescript
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

```typescript
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

```typescript
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.yml`
- `prettier.config.js`
- `package.json` (`prettier` field)

If no configuration is found, Prettier's defaults are used.

### Example `.prettierrc`

```json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 80
}
```

## How It Works

1. **Context Check**: Verifies the node is a file (folders are skipped)
2. **Format Detection**: Prettier infers the parser from file extension
3. **Format Content**: Applies formatting to the content
4. **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`:

```typescript
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

1. **Place Last**: Put prettier middleware last so it formats the final output
2. **Consistent Config**: Use the same Prettier config for generated and manual code
3. **File Extensions**: Ensure files have correct extensions for parser detection
4. **Error Handling**: Consider wrapping in try-catch for parse errors

## Middleware Order

Order matters! Place prettier middleware strategically:

```typescript
// ✅ 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:

```typescript
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