Generation

CLI Reference

Complete reference for all crouton-generate CLI commands and options

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

Installation

npm install -g @friendlyinternet/nuxt-crouton-collection-generator

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 @friendlyinternet/nuxt-crouton-collection-generator <command>

# Or add to project devDependencies
pnpm add -D @friendlyinternet/nuxt-crouton-collection-generator
npx crouton-generate <command>

Command Overview

The CLI provides five main commands:

CommandPurposeUsage
generateGenerate collectionsSingle collection or from config file
addAdd featuresAdd pre-built features like event tracking
initCreate example schemaQuick start helper
configUse config fileAlternative syntax for config-based generation
rollbackRemove collectionsSingle, bulk, or interactive removal

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)
-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
├── 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.

init

Create an example schema file to help you get started.

Syntax

crouton-generate init [options]

Options

OptionTypeDefaultDescription
-o, --output <path>string./crouton-schema.jsonOutput path for schema file

Example

# Create example schema
crouton-generate init

# Custom output path
crouton-generate init --output ./schemas/example.json

Generated Schema

The init command creates a complete example schema showing all field types:

{
  "id": {
    "type": "string",
    "meta": {
      "primaryKey": true
    }
  },
  "name": {
    "type": "string",
    "meta": {
      "required": true,
      "maxLength": 255
    }
  },
  "description": {
    "type": "text"
  },
  "price": {
    "type": "decimal",
    "meta": {
      "precision": 10,
      "scale": 2
    }
  },
  "inStock": {
    "type": "boolean"
  },
  "createdAt": {
    "type": "date"
  }
}
Tip: After running init, edit the generated schema file to match your needs, then use it with crouton-generate.

add

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

Syntax

crouton-generate add <feature> [options]

Arguments

  • <feature> - Feature to add (currently: events)

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 @friendlyinternet/nuxt-crouton-events

# 3. Add to nuxt.config.ts extends
# '@friendlyinternet/nuxt-crouton-events'
Note: The add events command creates the server-side storage layer. To enable automatic event tracking for all collection mutations, also install @friendlyinternet/nuxt-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.js
  2. crouton.config.mjs
  3. crouton.config.cjs
  4. crouton.config.ts

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.mjs --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:

  • @friendlyinternet/nuxt-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 file(s)
  schemaPath: './schemas/product.json',

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

  // Target layers and collections
  targets: [
    {
      layer: 'shop',
      collections: ['products', 'categories']
    }
  ],

  // External connectors (optional)
  connectors: {},

  // 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[] }>

Defines which collections to generate in which layers.

export default {
  targets: [
    {
      layer: 'shop',
      collections: ['products', 'categories', 'orders']
    },
    {
      layer: 'blog',
      collections: ['posts', 'authors']
    }
  ]
}

connectors

Type: Record<string, ConnectorConfig>

Configure external connectors for :referenced collections (e.g., :users, :teams).

export default {
  connectors: {
    users: {
      type: 'supersaas',      // Connector type
      autoInstall: true,       // Install package automatically
      copyFiles: true,         // Copy connector files to project
      updateAppConfig: true    // Register in app.config.ts
    },
    teams: {
      type: 'supersaas',
      autoInstall: true,
      copyFiles: true,
      updateAppConfig: true
    }
  }
}

Connector Types:

  • 'supersaas' - SuperSaaS team-based authentication
  • 'supabase' - Supabase auth.users
  • 'clerk' - Clerk authentication

See External References for more details.

flags

Type: object

Generation behavior flags.

useTeamUtility

Type: boolean
Default: false

Enable team-based multi-tenancy. Automatically adds:

  • teamId field (required, text)
  • userId field (required, text)
  • Team-scoped API endpoints with authentication middleware
export default {
  flags: {
    useTeamUtility: true  // Enable multi-tenancy
  }
}
When useTeamUtility: true, do NOT define teamId or userId in your schemas. The generator adds them automatically.
useMetadata

Type: boolean
Default: true

Automatically add timestamp and audit fields:

  • createdAt - Timestamp when record was created
  • updatedAt - Timestamp when record was last modified
  • 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
  }
}
autoConnectors

Type: boolean
Default: false

Auto-configure connectors without prompting (uses connectors config).

export default {
  connectors: {
    users: {
      type: 'supersaas',
      autoInstall: true
    }
  },
  flags: {
    autoConnectors: true  // Don't prompt, use config above
  }
}

Complete Configuration Example

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

  // Database
  dialect: 'pg',

  // Target layers and collections
  targets: [
    {
      layer: 'shop',
      collections: ['products', 'categories', 'orders']
    },
    {
      layer: 'blog',
      collections: ['posts', 'authors', 'tags']
    }
  ],

  // External connectors
  connectors: {
    users: {
      type: 'supersaas',
      autoInstall: true,
      copyFiles: true,
      updateAppConfig: true
    }
  },

  // Generation flags
  flags: {
    // Multi-tenancy
    useTeamUtility: true,

    // Timestamps
    useMetadata: true,

    // Relations
    autoRelations: false,

    // Translation fields
    noTranslations: false,

    // Database
    noDb: false,

    // Behavior
    force: false,
    dryRun: false,
    retries: 3,

    // Connectors
    autoConnectors: true
  }
}

External References

When you reference collections outside your layer or from external systems, use the : prefix in refTarget:

{
  "authorId": {
    "type": "string",
    "refTarget": ":users",  // External reference
    "meta": {
      "required": true
    }
  }
}

Connector Detection Flow

  1. Generator scans schemas for :referenced collections
  2. Checks config for connector definitions
  3. Prompts interactively (if autoConnectors: false) or auto-configures (if autoConnectors: true)
  4. Installs package (if autoInstall: true)
  5. Copies files to project (if copyFiles: true)
  6. Registers in app.config.ts (if updateAppConfig: true)

Interactive Connector Setup

Without autoConnectors, the generator prompts:

 Analyzed 5 schemas
 Found external reference: :users (used in 3 collections)

Configure connector for 'users'? (Y/n)
> Y

Which auth system?
  1. SuperSaaS (team-based)
  2. Supabase (auth.users)
  3. Clerk
  4. Skip (configure manually)
> 1

 Installing @friendlyinternet/nuxt-crouton-supersaas
 Copied app/composables/useUsers.ts
 Copied server/api/teams/[id]/users/index.get.ts
 Updated app.config.ts

Manual Connector Configuration

Skip automatic setup and configure manually:

export default {
  connectors: {
    users: {
      type: 'supersaas',
      autoInstall: false,  // Don't install package
      copyFiles: false,     // Don't copy files
      updateAppConfig: false  // Don't update config
    }
  },
  flags: {
    autoConnectors: true  // Use config but don't auto-setup
  }
}

Then manually:

  1. Install connector package
  2. Copy/create connector files
  3. Register in app.config.ts

Common Workflows

Create a New Project from Scratch

# 1. Create example schema
crouton-generate init

# 2. Edit schema file
# (Edit crouton-schema.json to match your needs)

# 3. Generate collection
crouton-generate shop products --fields-file=crouton-schema.json

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

# 5. Run migrations and start dev server
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 when useTeamUtility: true:

// Generated: server/api/teams/[id]/products/index.get.ts
import { requireTeamAuth } from '~/server/utils/team-auth'

export default defineEventHandler(requireTeamAuth(async (event, team) => {
  // team is automatically resolved and verified
  // All queries automatically scoped to team.id
  const products = await getProducts({ teamId: team.id })
  return products
}))

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 @friendlyinternet/nuxt-crouton-collection-generator

# Option 2: Use npx
npx @friendlyinternet/nuxt-crouton-collection-generator <command>

# Option 3: Add to project and use npx
pnpm add -D @friendlyinternet/nuxt-crouton-collection-generator
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, userId (when useTeamUtility: true)
  • 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 @friendlyinternet/nuxt-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

  • v1.4.3 (Current) - Latest stable release
    • Enhanced rollback commands (single, bulk, interactive)
    • Improved connector detection and setup
    • Better error messages and validation
    • Date handling improvements
    • Authorization middleware generation

Support