Generation

CLI Reference

Complete reference for all crouton-generate CLI commands and options

The @fyit/crouton-cli package provides a powerful CLI tool for generating complete CRUD collections. This reference covers all available commands, options, and workflows.

Installation

npm install -g @fyit/crouton-cli

After global installation, both crouton and crouton-generate commands are available everywhere:

crouton --help
# or
crouton-generate --help
Tip: The crouton command is an alias for crouton-generate. Both work identically.

Project-Level with npx

# Use directly without installation
npx @fyit/crouton-cli <command>

# Or add to project devDependencies
pnpm add -D @fyit/crouton-cli
npx crouton-generate <command>

Command Overview

The CLI provides the following commands:

CommandPurposeUsage
generateGenerate collectionsSingle collection or from config file
initScaffold a full appEnd-to-end: scaffold, generate, doctor, summary
configUse config fileAlternative syntax for config-based generation
addAdd modules/featuresAdd Crouton modules like auth, editor, events
rollbackRemove collectionsSingle, bulk, or interactive removal
doctorValidate appChecks deps, wrangler, stubs, schema wiring
scaffold-appCreate app skeletonGenerates boilerplate files for a new app
seed-translationsSeed i18n dataSeed translations from JSON locale files to DB
db-pullPull remote DBPull remote D1 database into local dev
deploy-setupSetup deploymentInteractive Cloudflare Pages deployment setup
deploy-checkCheck deploy readinessValidate wrangler config, CI workflow, bindings

Commands

generate

Generate a new CRUD collection with all necessary files.

Basic Syntax

crouton-generate <layer> <collection> [options]

Arguments

  • <layer> - Target layer name (e.g., shop, admin, blog)
  • <collection> - Collection name in plural form (e.g., products, users, posts)
Naming convention: Collection names are lowercased for folder paths. For example, productOptions becomes productoptions/ in the file system. Use kebab-case (e.g., product-options) for multi-word collection names.

Options

OptionTypeDefaultDescription
-f, --fields-file <path>string-Path to JSON schema file (required)
-d, --dialect <type>pg|sqlitesqliteDatabase dialect
--auto-relationsbooleanfalseAdd relation stubs in comments
--dry-runbooleanfalsePreview without creating files
--no-translationsbooleanfalseSkip translation field generation
--forcebooleanfalseOverwrite existing files
--no-dbbooleanfalseSkip database table creation
--hierarchybooleanfalseEnable hierarchy support (parentId, path, depth, order)
--seedbooleanfalseGenerate seed data file with drizzle-seed
--count <number>number25Number of seed records to generate
--no-auto-mergebooleanfalseSkip automatic merging of generated files with existing ones
-c, --config <path>string-Use config file instead

Examples

Basic generation:

crouton-generate shop products --fields-file=./schemas/product.json

With options:

crouton-generate admin users \
  --fields-file=./schemas/user.json \
  --dialect=pg \
  --force

Preview changes (dry run):

crouton-generate blog posts \
  --fields-file=./schemas/post.json \
  --dry-run

Using config file:

crouton-generate --config ./crouton.config.js

With hierarchy support:

crouton-generate content pages \
  --fields-file=./schemas/page.json \
  --hierarchy

What Gets Generated

Each generate command creates:

layers/[layer]/collections/[collection]/
├── app/
│   ├── components/
│   │   ├── _Form.vue                  # CRUD form with validation
│   │   ├── List.vue                   # Data table/list
│   │   └── RepeaterItem.vue           # For repeater fields (if needed)
│   └── composables/
│       └── use[Layer][Collection].ts  # Zod schema, columns, defaults (e.g., useShopProducts.ts)
├── server/
│   ├── api/teams/[id]/[collection]/
│   │   ├── index.get.ts               # GET all/by IDs
│   │   ├── index.post.ts              # CREATE
│   │   ├── [id].patch.ts              # UPDATE
│   │   └── [id].delete.ts             # DELETE
│   └── database/
│       ├── queries.ts                 # Query functions
│       ├── schema.ts                  # Drizzle schema
│       └── seed.ts                    # Seed data (with --seed flag)
├── types.ts                            # TypeScript interfaces
└── nuxt.config.ts                     # Layer configuration

Hierarchy Support

When using the --hierarchy flag (or hierarchy: true in config), additional files and fields are generated for tree/nested data structures:

Additional database fields:

  • parentId - Reference to parent record (nullable)
  • path - Materialized path for efficient tree queries
  • depth - Nesting level (0 for root items)
  • order - Sort order within siblings

Additional API endpoints:

  • [id]/move.patch.ts - Move item to new parent
  • reorder.patch.ts - Reorder sibling items

Additional queries:

  • getTreeData() - Fetch hierarchical data
  • updatePosition() - Update item position
  • reorderSiblings() - Reorder items at same level

Zod schema includes:

parentId: z.string().nullable().optional()

Default values include:

parentId: null
Tip: Hierarchy is ideal for nested categories, organizational structures, page trees, or any parent-child relationships.

Seed Data Generation

Generate realistic test data alongside your collections using drizzle-seed + Faker.

CLI usage:

# Generate with seed data (25 records by default)
crouton-generate shop products --fields-file=products.json --seed

# Generate with custom record count
crouton-generate shop products --fields-file=products.json --seed --count=100

Config file usage:

// crouton.config.js
export default {
  collections: [
    { name: 'products', fieldsFile: './schemas/products.json', seed: true },           // 25 records
    { name: 'categories', fieldsFile: './schemas/categories.json', seed: { count: 50 } } // custom count
  ],
  seed: {
    defaultCount: 25,          // default for all collections
    defaultTeamId: 'seed-team' // team ID for seeded data
  },
  // ... other config
}

Running seeds:

After generation, execute the seed file:

# Run directly
npx tsx ./layers/shop/collections/products/server/database/seed.ts

# Or import in your code
import { seedShopProducts } from './layers/shop/collections/products/server/database/seed'

await seedShopProducts({
  count: 100,
  teamId: 'my-team',
  reset: true  // optionally clear existing data first
})

Field-to-generator mapping:

The seed generator auto-detects field names and generates appropriate data:

Field PatternGenerated Data
emailf.email() - realistic email addresses
name, fullNamef.fullName() - person names
titlef.loremIpsum({ sentencesCount: 1 })
description, contentf.loremIpsum({ sentencesCount: 3 })
price, amountf.number({ minValue: 1, maxValue: 1000 })
Foreign keysPlaceholder values with dependency comments
Tip: Seed data is great for development, demos, and testing. The generated seed file can be customized after generation.

init

Scaffold a full Crouton app end-to-end: creates the app skeleton, generates collections from config, runs doctor validation, and prints a summary with next steps.

Syntax

crouton-generate init <name> [options]

Arguments

  • <name> - App name (required)

Options

OptionTypeDefaultDescription
--features <list>string-Comma-separated feature names (e.g., bookings,pages,editor)
--theme <name>string-Theme to wire into extends (e.g., ko)
-d, --dialect <type>stringsqliteDatabase dialect (sqlite or pg)
--no-cfbooleanfalseSkip Cloudflare-specific config (wrangler.toml, CF stubs)
--dry-runbooleanfalsePreview what will be generated without writing files

Example

# Create app with default settings
crouton-generate init my-app

# With features and theme
crouton-generate init my-app --features bookings,pages,editor --theme ko

# Preview without writing
crouton-generate init my-app --dry-run

What Gets Created

The init command runs a full pipeline:

  1. scaffold-app -- Creates the app skeleton (nuxt.config, package.json, schemas/, etc.)
  2. generate -- Generates collections from crouton.config.js (if collections are defined)
  3. doctor -- Validates everything is wired correctly
  4. Summary -- Prints next steps (dev server, deploy)
Tip: After running init, you can customize the generated crouton.config.js and schemas, then re-run crouton-generate config to regenerate collections.

add

Add pre-built features to your existing Nuxt Crouton project.

Syntax

crouton-generate add <feature> [options]

Arguments

  • <feature> - Feature to add (available: auth, i18n, admin, bookings, editor, assets, events, flow, email, maps, ai, devtools)

Options

OptionTypeDefaultDescription
--dry-runbooleanfalsePreview what will be generated
--forcebooleanfalseOverwrite existing files

Available Features

events

Add the crouton-events layer for audit trail tracking. This creates a complete event tracking system that automatically logs all collection mutations (create, update, delete).

# Add events layer
crouton-generate add events

# Preview what will be created
crouton-generate add events --dry-run

# Overwrite existing files
crouton-generate add events --force

What Gets Generated

The add events command creates:

layers/crouton-events/
├── nuxt.config.ts                      # Layer configuration
├── types.ts                            # TypeScript interfaces
└── server/
    ├── database/
    │   ├── schema.ts                   # Drizzle schema for events table
    │   └── queries.ts                  # Query functions (getAll, create, etc.)
    └── api/teams/[id]/crouton-collection-events/
        ├── index.get.ts                # GET all events
        ├── index.post.ts               # CREATE event
        ├── [eventId].patch.ts          # UPDATE event
        └── [eventId].delete.ts         # DELETE event

Auto-Updated Files

The command also updates:

  1. nuxt.config.ts - Adds './layers/crouton-events' to extends array
  2. server/database/schema/index.ts - Adds schema export

Next Steps After Adding Events

# 1. Run database migration
pnpm drizzle-kit generate
pnpm drizzle-kit migrate

# 2. Install the events tracking package (for auto-tracking)
pnpm add @fyit/crouton-events

# 3. Add to nuxt.config.ts extends
# '@fyit/crouton-events'
Note: The add events command creates the server-side storage layer. To enable automatic event tracking for all collection mutations, also install @fyit/crouton-events package. See Events Package for full documentation.

config

Alternative syntax for generating collections using a configuration file.

Syntax

crouton-generate config [configPath] [options]

Arguments

  • [configPath] - Path to config file (auto-detected if not specified)
Auto-detection: If no config path is provided, the CLI automatically searches for config files in this order:
  1. crouton.config.ts
  2. crouton.config.js
  3. crouton.config.mjs
  4. crouton.config.cjs

Options

OptionTypeDescription
--only <name>stringGenerate only a specific collection from the config

Examples

# Auto-detect config file (searches for crouton.config.js/.mjs/.cjs/.ts)
crouton-generate config

# Use specific config file
crouton-generate config ./configs/production.config.mjs

# Generate only a single collection from config
crouton-generate config --only products

# Combine config path with --only flag
crouton-generate config ./crouton.config.js --only pages

# Alternative: Use --config flag with generate command
crouton-generate --config ./crouton.config.js

Config File Format

See Configuration File section below for complete details.

rollback

Remove generated collections with various strategies.

Single Collection Rollback

Remove a specific collection:

crouton-generate rollback <layer> <collection> [options]

Arguments:

  • <layer> - Layer name containing the collection
  • <collection> - Collection name to remove

Options:

OptionDescription
--dry-runPreview what will be removed
--keep-filesOnly clean configs, keep generated files
--forceForce removal without warnings

Example:

# Preview removal
crouton-generate rollback shop products --dry-run

# Remove with confirmation
crouton-generate rollback shop products

# Force remove without prompts
crouton-generate rollback shop products --force

Bulk Rollback

Remove entire layers or multiple collections:

crouton-generate rollback-bulk [options]

Options:

OptionDescription
--layer <name>Remove entire layer with all collections
--config <path>Remove collections defined in config file
--dry-runPreview what will be removed
--keep-filesOnly clean configs, keep files
--forceForce removal without warnings

Examples:

# Remove entire layer
crouton-generate rollback-bulk --layer=shop

# Preview layer removal
crouton-generate rollback-bulk --layer=shop --dry-run

# Remove collections from config file
crouton-generate rollback-bulk --config=./crouton.config.js

# Force bulk removal
crouton-generate rollback-bulk --layer=shop --force

Interactive Rollback

Use an interactive UI to select what to remove:

crouton-generate rollback-interactive [options]

Options:

OptionDescription
--dry-runPreview what will be removed
--keep-filesOnly clean configs, keep files

Interactive Flow:

$ crouton-generate rollback-interactive

═══════════════════════════════════════════════════════════
  INTERACTIVE ROLLBACK
═══════════════════════════════════════════════════════════

Found 3 layers:

 shop (5 collections)
 blog (3 collections)
 admin (2 collections)

? What would you like to rollback?
 Entire layer (all collections)
    Specific collections
    Cancel

? Select layer:
 shop (5 collections)
    blog (3 collections)
    admin (2 collections)

? Are you sure you want to remove layer "shop"? (Y/n)
Warning: Rollback operations are destructive. Always use --dry-run first to preview changes. The rollback command removes:
  • Generated files in layers/[layer]/collections/[collection]/
  • Schema exports from server/database/schema/index.ts
  • Collection registrations from app.config.ts
  • Layer references from root nuxt.config.ts (for bulk operations)

install

Check and install required Nuxt modules (mainly for development).

crouton-generate install

This command checks for and installs:

  • @fyit/crouton (core package)
  • Required Drizzle ORM packages
  • Other dependencies

Configuration File

The configuration file provides a declarative way to define all generation settings.

Basic Structure

// crouton.config.js
export default {
  // Path to JSON schema files directory
  schemaPath: './schemas/',

  // Database dialect
  dialect: 'sqlite',  // or 'pg'

  // Target layers and collections
  targets: [
    {
      layer: 'shop',
      collections: [
        // Simple string for basic collections
        'products',
        // Or object with per-collection options
        {
          name: 'orders',
          fieldsFile: './schemas/order.json',
          seed: true,
          hierarchy: false
        }
      ]
    }
  ],

  // Seed configuration (optional)
  seed: {
    defaultCount: 25,
    defaultTeamId: 'seed-team'
  },

  // Generation flags
  flags: {}
}

Configuration Options

schemaPath

Type: string

Path to your JSON schema file(s). Can be:

  • Single file: './product-schema.json'
  • Directory: './schemas/' (uses convention [collection]-schema.json)
export default {
  schemaPath: './schemas/',  // Looks for products-schema.json, etc.
  targets: [
    {
      layer: 'shop',
      collections: ['products', 'categories']  // Uses products-schema.json, categories-schema.json
    }
  ]
}

dialect

Type: 'pg' | 'sqlite'
Default: 'sqlite'

Database dialect for generated schemas and queries.

export default {
  dialect: 'pg',  // PostgreSQL
  // Or
  dialect: 'sqlite'  // SQLite (default)
}

targets

Type: Array<{ layer: string, collections: (string | CollectionConfig)[] }>

Defines which collections to generate in which layers. Collections can be:

  • String: Simple collection name (uses schema from schemaPath/[name]-schema.json)
  • Object: Collection with per-collection options
export default {
  targets: [
    {
      layer: 'shop',
      collections: [
        'products',           // Simple: uses schemas/products-schema.json
        'categories',         // Simple: uses schemas/categories-schema.json
        {                     // With options
          name: 'orders',
          fieldsFile: './schemas/order.json',
          seed: { count: 50 },
          hierarchy: true
        }
      ]
    },
    {
      layer: 'blog',
      collections: [
        { name: 'posts', seed: true },
        { name: 'authors', seed: { count: 10 } }
      ]
    }
  ]
}

Per-collection options:

OptionTypeDescription
namestringCollection name (required)
fieldsFilestringPath to schema file (overrides schemaPath)
seedboolean | { count: number }Generate seed data
hierarchybooleanEnable tree/hierarchy support

flags

Type: object

Generation behavior flags.

Team-Scoped by Default: All generated collections are team-scoped. The generator automatically adds teamId and owner fields and uses @fyit/crouton-auth/server for authentication. Do NOT define these fields in your schemas.
useMetadata

Type: boolean
Default: true

Automatically add timestamp and audit fields:

  • createdAt - Timestamp when record was created
  • updatedAt - Timestamp when record was last modified
  • createdBy - User ID who created the record
  • updatedBy - User ID who last modified the record
export default {
  flags: {
    useMetadata: true  // Add timestamps (default)
  }
}
When useMetadata: true, do NOT define createdAt, updatedAt, or updatedBy in your schemas.
autoRelations

Type: boolean
Default: false

Add relation helper comments to generated schemas.

export default {
  flags: {
    autoRelations: true
  }
}
noTranslations

Type: boolean
Default: false

Skip translation field generation.

export default {
  flags: {
    noTranslations: true  // Don't generate translation fields
  }
}
force

Type: boolean
Default: false

Overwrite existing files without prompting.

export default {
  flags: {
    force: true  // Overwrite files
  }
}
noDb

Type: boolean
Default: false

Skip database table creation (generate code only).

export default {
  flags: {
    noDb: true  // Skip database operations
  }
}
dryRun

Type: boolean
Default: false

Preview what will be generated without creating files.

export default {
  flags: {
    dryRun: true  // Preview only
  }
}

Complete Configuration Example

// crouton.config.js
export default {
  // Schema location
  schemaPath: './schemas/',

  // Database
  dialect: 'sqlite',

  // Target layers and collections
  targets: [
    {
      layer: 'shop',
      collections: [
        { name: 'products', seed: true },
        { name: 'categories', seed: { count: 10 } },
        { name: 'orders', seed: { count: 100 } }
      ]
    },
    {
      layer: 'content',
      collections: [
        { name: 'pages', hierarchy: true },
        { name: 'posts', seed: true },
        'authors'  // Simple string also works
      ]
    }
  ],

  // Seed configuration
  seed: {
    defaultCount: 25,
    defaultTeamId: 'seed-team'
  },

  // Generation flags
  flags: {
    // Timestamps
    useMetadata: true,

    // Relations
    autoRelations: false,

    // Translation fields
    noTranslations: false,

    // Database
    noDb: false,

    // Behavior
    force: false,
    dryRun: false
  }
}

Common Workflows

Create a New Project from Scratch

# 1. Scaffold a full app (runs scaffold-app → generate → doctor → summary)
crouton-generate init my-app

# 2. Customize the generated schemas and crouton.config.js

# 3. Regenerate collections if needed
crouton-generate config

# 4. Start dev server
cd my-app
pnpm dev

Generate Multiple Collections

# 1. Create config file
cat > crouton.config.js << 'CONF'
export default {
  schemaPath: './schemas/',
  dialect: 'sqlite',
  targets: [
    {
      layer: 'shop',
      collections: ['products', 'categories', 'orders']
    }
  ],
  flags: {
    useMetadata: true,
    force: false
  }
}
CONF

# 2. Create schema files
mkdir -p schemas
# (Create products-schema.json, categories-schema.json, orders-schema.json)

# 3. Generate all at once
crouton-generate config

# 4. Export schemas
echo "export * from '~/layers/shop/collections/products/server/database/schema'" >> server/database/schema/index.ts
echo "export * from '~/layers/shop/collections/categories/server/database/schema'" >> server/database/schema/index.ts
echo "export * from '~/layers/shop/collections/orders/server/database/schema'" >> server/database/schema/index.ts

Preview Changes Before Generating

# Use --dry-run to see what would be generated
crouton-generate shop products \
  --fields-file=schemas/product.json \
  --dry-run

# Output shows:
# - Files that would be created
# - Directories that would be created
# - Schemas that would be registered

Safely Remove a Collection

# 1. Preview removal
crouton-generate rollback shop products --dry-run

# 2. Review what will be removed

# 3. Execute removal
crouton-generate rollback shop products

# 4. Remove schema export manually from server/database/schema/index.ts

Clean Up an Entire Layer

# Use interactive mode for safety
crouton-generate rollback-interactive

# Select "Entire layer"
# Select the layer to remove
# Confirm removal

Integration with Extraction Notes

The generator incorporates fixes and improvements documented in /docs/extraction-notes.md:

Authorization Middleware

Generated API endpoints include team-based authorization by default:

// Generated: server/api/teams/[id]/products/index.get.ts
import { resolveTeamAndCheckMembership } from '@fyit/crouton-auth/server/utils/team'

export default defineEventHandler(async (event) => {
  const { team, user } = await resolveTeamAndCheckMembership(event)
  // team is automatically resolved and verified
  // All queries automatically scoped to team.id
  const products = await getProducts({ teamId: team.id })
  return products
})
Note: The auth package is automatically included when using @fyit/crouton. You don't need to install it separately.

Date Handling

All date fields use proper UTC storage and timezone handling:

{
  "publishedAt": {
    "type": "date"
  }
}

Generated code includes:

  • UTC storage in database
  • Local timezone display in UI
  • Proper date parsing and validation
  • ISO 8601 format for portability

Connector Integration

External references (:users, :teams) trigger automatic connector setup with proper type safety and composables.

Troubleshooting

Command Not Found

Problem: crouton-generate: command not found

Solutions:

# Option 1: Install globally
npm install -g @fyit/crouton-cli

# Option 2: Use npx
npx @fyit/crouton-cli <command>

# Option 3: Add to project and use npx
pnpm add -D @fyit/crouton-cli
npx crouton-generate <command>

Duplicate Key Errors

Problem: Build fails with duplicate key errors (e.g., userId, teamId)

Cause: You defined auto-generated fields in your schema

Solution: Remove auto-generated fields from schema:

  • Remove id (always auto-generated)
  • Remove teamId, owner (always auto-generated for team-scoped collections)
  • Remove createdAt, updatedAt, updatedBy (when useMetadata: true)

Config File Not Found

Problem: Error: Config file not found: ./crouton.config.js

Solutions:

# Use correct path
crouton-generate config ./path/to/config.js

# Or use --config flag
crouton-generate --config ./path/to/config.js

# Or ensure default location exists
ls crouton.config.js

Schema File Not Found

Problem: Error: Schema file not found

Solutions:

# Use absolute path
crouton-generate shop products --fields-file=/full/path/to/schema.json

# Or use relative path from project root
crouton-generate shop products --fields-file=./schemas/product.json

# Verify file exists
ls ./schemas/product.json

TypeScript Errors After Generation

Problem: Type errors in generated code

Solutions:

# 1. Ensure Nuxt Crouton is installed
pnpm add @fyit/crouton

# 2. Run Nuxt prepare to regenerate types
npx nuxt prepare

# 3. Run typecheck
npx nuxt typecheck

# 4. Restart TypeScript server in your editor

Rollback Doesn't Remove Everything

Problem: Some files remain after rollback

Explanation: Rollback only removes generated files, not manual modifications or schema exports.

Manual cleanup needed:

  1. Remove schema exports from server/database/schema/index.ts
  2. Remove any manual modifications to generated files
  3. Remove database migrations if created

Permission Errors

Problem: EACCES: permission denied

Solutions:

# Check file permissions
ls -la layers/

# Fix permissions
chmod -R u+w layers/

# Or run with sudo (not recommended)
sudo crouton-generate ...

Best Practices

Schema Design

  1. Start simple - Add fields incrementally
  2. Use metadata - Enable useMetadata: true for audit trails
  3. Reference external collections - Use :prefix for external refs
  4. Validate in schema - Use meta.required, meta.maxLength, etc.

Configuration

  1. Use config files for multi-collection projects
  2. Version control your crouton.config.js
  3. Document connectors in config comments
  4. Use dryRun before actual generation

Development Workflow

  1. Generate collection
  2. Export schema in server/database/schema/index.ts
  3. Run typecheck (npx nuxt typecheck)
  4. Test in dev mode
  5. Commit generated files (they're your code now!)

Rollback Strategy

  1. Always --dry-run first
  2. Use interactive mode for bulk operations
  3. Backup before major rollbacks
  4. Clean manually if needed

Version History

  • v0.1.0 (Current) - Package @fyit/crouton-cli
    • Package renamed from nuxt-crouton-collection-generator
    • Both crouton and crouton-generate commands available
    • Enhanced MCP server integration
    • Full pipeline: init, add, doctor, scaffold-app, seed-translations, db-pull, deploy-setup, deploy-check
    • Enhanced rollback commands (single, bulk, interactive)
    • Improved connector detection and setup
    • Better error messages and validation
    • Date handling improvements
    • Authorization middleware generation

Support