Laizy CMS
CLI

laizy generate

Generate a type-safe TypeScript client from your Laizy schema with full autocomplete support.

laizy generate

The generate command reads your .laizy schema file and creates a fully typed TypeScript client. The generated code gives you a Prisma-like API with findMany(), findById(), and count() methods for each content model.

Usage

pnpm laizy generate

No flags are required. The command reads configuration from ~/.laizyrc for the schema path and output directory.

What It Generates

The command produces three files in your configured output directory (default: generated/laizy/):

FilePurpose
types.tsTypeScript interfaces for each model, plus Create and Update input types
client.tsRuntime client with query methods for each model
index.tsRe-exports everything for clean imports

types.ts

Contains a full set of TypeScript interfaces for each content model:

// Generated TypeScript types for CMS schema
// DO NOT EDIT - This file is auto-generated

export interface BlogPost {
  title: string
  content: string
  status: string
  slug: string
  // System fields
  id: string
  createdAt: Date
  updatedAt: Date
}

export interface CreateBlogPostInput {
  title: string      // required fields are non-optional
  content: string
  slug: string
}

export interface UpdateBlogPostInput {
  title?: string     // all fields optional for partial updates
  content?: string
  status?: string
  slug?: string
}

// Utility type for query options
export interface FindManyOptions<T> {
  where?: Partial<T>
  select?: Partial<Record<keyof T, boolean>>
  limit?: number
  offset?: number
}

Fields with a default constraint are excluded from CreateInput since they have a fallback value. All fields are optional in UpdateInput to support partial updates.

client.ts

Contains the runtime client implementation with one class per model:

// Generated CMS client implementation
// DO NOT EDIT - This file is auto-generated

import type { BlogPost, FindManyOptions } from './types'
import type { ManagementClient } from '@/lib/management-client'

class BlogPostClient {
  private managementClient!: ManagementClient

  async findMany(options: FindManyOptions<BlogPost> = {}): Promise<BlogPost[]> {
    const result = await this.managementClient.listContentData({
      modelName: 'BlogPost',
      limit: options.limit,
      offset: options.offset,
    })

    return result.map(item => ({
      ...item.data,
      id: item.id,
      createdAt: item.createdAt,
      updatedAt: item.updatedAt,
    })) as BlogPost[]
  }

  async findById(id: string): Promise<BlogPost | null> {
    const result = await this.managementClient.getContentData(id)
    if (!result) return null
    return {
      ...result.data,
      id: result.id,
      createdAt: result.createdAt,
      updatedAt: result.updatedAt,
    } as BlogPost
  }

  async count(): Promise<number> {
    return this.managementClient.countContentData({
      modelName: 'BlogPost',
    })
  }
}

// Main CMS client
export class LaizyClient {
  blogPost = new BlogPostClient()
  author = new AuthorClient()

  constructor(managementClient: ManagementClient) {
    this.blogPost.setManagementClient(managementClient)
    this.author.setManagementClient(managementClient)
  }
}

index.ts

A simple re-export file for clean imports:

// Generated CMS client entry point
// DO NOT EDIT - This file is auto-generated

export * from './types'
export { LaizyClient } from './client'

Example Output

Generating TypeScript client...

Parsing schema...
Found 3 models, generating client...
Generated client with 3 models

TypeScript client generated successfully!
Output directory: ./generated/laizy
  - types.ts - Type definitions
  - client.ts - Runtime client
  - index.ts - Main exports

Usage example:
import { LaizyClient } from './generated/laizy';
import { ManagementClient } from '@/lib/management-client';

const managementClient = new ManagementClient({
  baseUrl: 'http://localhost:3000',
  apiToken: 'your-api-token',
});

const client = new LaizyClient(managementClient);
const blogposts = await client.blogPost.findMany();

Generated models:
  - BlogPost (4 fields)
  - Author (3 fields)
  - HeroSection (6 fields)

Configuration

The generate command uses two settings from ~/.laizyrc:

SettingDefaultDescription
schemaPath./laizy/schema.laizyPath to your schema file
outputPath./generated/laizyDirectory for generated files

You can change these with laizy config set:

pnpm laizy config set schemaPath ./content/schema.laizy
pnpm laizy config set outputPath ./src/generated/laizy

The generated files include a "DO NOT EDIT" header. They are fully regenerated each time you run the command, so any manual edits will be overwritten. If you need to customize behavior, extend the LaizyClient class in your own code.

Model Naming Convention

Model names in your schema are converted to camelCase for the client properties:

Schema ModelClient Property
BlogPostclient.blogPost
Authorclient.author
HeroSectionclient.heroSection
FeatureBentoCardclient.featureBentoCard

The first letter is lowercased while preserving the rest of the casing.

Error Handling

No models found

No models found in schema
Please add some model definitions to your schema file.

Your schema file is empty or contains no valid model blocks.

Syntax errors

Client generation failed
Error: Line 3: Expected ":" after field name

Schema syntax error. Please check your .laizy file for:
  - Proper model syntax
  - Correct field definitions
  - Valid constraint syntax

The parser reports the exact line number where the error occurred.

When to Regenerate

Run laizy generate whenever you change your schema file. The typical workflow is:

  1. Edit laizy/schema.laizy
  2. Run pnpm laizy sync to update the database
  3. Run pnpm laizy generate to regenerate the client

The generated client reflects whatever is in your local schema file, independent of what is synced to the database. This means you can generate before syncing if you want to see the types, but the client will only work at runtime after the models are synced.

Next Steps

On this page