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 generateNo 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/):
| File | Purpose |
|---|---|
types.ts | TypeScript interfaces for each model, plus Create and Update input types |
client.ts | Runtime client with query methods for each model |
index.ts | Re-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:
| Setting | Default | Description |
|---|---|---|
schemaPath | ./laizy/schema.laizy | Path to your schema file |
outputPath | ./generated/laizy | Directory 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/laizyThe 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 Model | Client Property |
|---|---|
BlogPost | client.blogPost |
Author | client.author |
HeroSection | client.heroSection |
FeatureBentoCard | client.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 syntaxThe 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:
- Edit
laizy/schema.laizy - Run
pnpm laizy syncto update the database - Run
pnpm laizy generateto 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
- Client Overview -- How to use the generated client in your application
- Queries --
findMany(),findById(), andcount()reference - TypeScript Types -- Understanding the generated type system