Generated Client
Overview of the auto-generated TypeScript client, ManagementClient setup, and how to query content programmatically.
Generated Client
The Laizy CLI generates a fully typed TypeScript client from your schema. This client provides a Prisma-like API for querying content, with full autocomplete and type safety out of the box.
How It Works
When you run pnpm laizy generate, the CLI reads your .laizy schema file and produces three files:
| File | Purpose |
|---|---|
types.ts | TypeScript interfaces for each model (BlogPost, CreateBlogPostInput, etc.) |
client.ts | Runtime client class with findMany(), findById(), and count() methods |
index.ts | Re-exports everything for clean imports |
These files are written to your configured output directory (default: generated/laizy/).
Setup
The generated LaizyClient requires a ManagementClient instance for making authenticated API calls:
import { LaizyClient } from './generated/laizy';
import { ManagementClient } from '@/lib/management-client';
const managementClient = new ManagementClient({
baseUrl: process.env.NEXT_PUBLIC_LAIZY_BASE_URL!,
apiToken: process.env.NEXT_PUBLIC_LAIZY_TOKEN!,
projectId: 'your-project-id',
});
const client = new LaizyClient(managementClient);ManagementClient Options
The ManagementClient constructor accepts these options:
interface ManagementClientOptions {
baseUrl: string; // Laizy CMS API URL
apiToken?: string; // JWT token (admin or frontend)
projectId?: string; // Project ID for scoping requests
}| Option | Required | Description |
|---|---|---|
baseUrl | Yes | The URL of your Laizy CMS instance |
apiToken | Yes | A laizy_ prefixed JWT token |
projectId | Yes | The project to query content from |
The ManagementClient automatically sets the Authorization and x-laizy-project headers on every request.
Client Architecture
The generated client follows a simple pattern. Each model in your schema gets its own client class, and the LaizyClient composes them all:
// Each model gets a dedicated client
class BlogPostClient {
async findMany(options?: FindManyOptions<BlogPost>): Promise<BlogPost[]>
async findById(id: string): Promise<BlogPost | null>
async count(): Promise<number>
}
class AuthorClient {
async findMany(options?: FindManyOptions<Author>): Promise<Author[]>
async findById(id: string): Promise<Author | null>
async count(): Promise<number>
}
// The LaizyClient composes all model clients
class LaizyClient {
blogPost: BlogPostClient
author: AuthorClient
constructor(managementClient: ManagementClient)
}The model property names are the camelCase version of the model names from your schema:
| Schema Model | Client Property |
|---|---|
BlogPost | client.blogPost |
Author | client.author |
HeroSection | client.heroSection |
FooterContent | client.footerContent |
Token Types
The ManagementClient works with two token types, each providing different access levels:
Admin Tokens
Full read/write access. Use these in server-side code and the CLI.
const managementClient = new ManagementClient({
baseUrl: 'https://laizycms.com',
apiToken: process.env.LAIZY_API_TOKEN!, // admin token
projectId: 'your-project-id',
});Frontend Tokens
Read-only access to published content. Safe for client-side use.
const managementClient = new ManagementClient({
baseUrl: 'https://laizycms.com',
apiToken: process.env.NEXT_PUBLIC_LAIZY_TOKEN!, // frontend token
projectId: 'your-project-id',
});Never expose admin tokens in client-side code. Use frontend tokens (scope: content:read) for any code that runs in the browser. Admin tokens are for server-side code, CLI tools, and API routes only.
Quick Example
import { LaizyClient } from './generated/laizy';
import { ManagementClient } from '@/lib/management-client';
const managementClient = new ManagementClient({
baseUrl: process.env.NEXT_PUBLIC_LAIZY_BASE_URL!,
apiToken: process.env.NEXT_PUBLIC_LAIZY_TOKEN!,
projectId: 'your-project-id',
});
const client = new LaizyClient(managementClient);
// Fetch all blog posts
const posts = await client.blogPost.findMany();
// Fetch a single post by ID
const post = await client.blogPost.findById('abc123');
// Count all authors
const authorCount = await client.author.count();The ManagementClient Under the Hood
The ManagementClient is a thin wrapper around a tRPC client that:
- Sends authenticated requests with the
Authorization: Bearer <token>header - Includes the project context via the
x-laizy-projectheader - Uses
superjsonas the transformer for proper Date serialization - Provides methods for content CRUD, model management, and schema operations
The generated LaizyClient delegates all API calls to the ManagementClient, which handles serialization, authentication, and error handling transparently.
Regenerating
Run pnpm laizy generate whenever you change your schema. The generated files are fully overwritten each time, so do not edit them manually. Instead, extend the LaizyClient in your own code if you need custom behavior.
Next Steps
- TypeScript Types -- Understanding the generated type system
- Queries --
findMany(),findById(), andcount()reference - Next.js Integration -- Using the client in a Next.js app