constructive-graphql-codegen

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Constructive GraphQL Codegen

Constructive GraphQL 代码生成器

Generate type-safe React Query hooks, Prisma-like ORM client, or inquirerer-based CLI from GraphQL schema files, endpoints, databases, or PGPM modules. Also generates documentation in multiple formats.
从GraphQL Schema文件、端点、数据库或PGPM模块生成类型安全的React Query hooks、类Prisma的ORM客户端,或基于inquirerer的CLI。同时支持生成多种格式的文档。

When to Apply

适用场景

Use this skill when:
  • Setting up GraphQL code generation for a PostGraphile backend
  • User asks to generate hooks, ORM, CLI, or type-safe GraphQL client
  • Exporting a GraphQL schema from a database or endpoint
  • Generating documentation (README, AGENTS.md, skill files, MCP tool definitions)
  • Implementing features that need to fetch or mutate data
  • Using previously generated hooks, ORM, or CLI code
  • Regenerating code after schema changes
Important: Always prefer generated code over raw GraphQL queries or SQL.
以下场景适用本工具:
  • 为PostGraphile后端配置GraphQL代码生成
  • 需要生成hooks、ORM、CLI或类型安全的GraphQL客户端
  • 从数据库或端点导出GraphQL Schema
  • 生成文档(README、AGENTS.md、技能文件、MCP工具定义)
  • 实现需要获取或修改数据的功能
  • 使用已生成的hooks、ORM或CLI代码
  • Schema变更后重新生成代码
重要提示:优先使用生成的代码,而非原生GraphQL查询或SQL语句。

Recommended Workflow: Schema Export + Schema Directory

推荐工作流:Schema导出 + Schema目录

The recommended approach is a two-step workflow using schema export followed by
schemaDir
. This is the most deterministic and portable way to use codegen:
推荐方案是分两步的工作流:先导出Schema,再使用
schemaDir
。这是使用代码生成器最具确定性和可移植性的方式:

Step 1: Export schema(s) to
.graphql
files

步骤1:将Schema导出为.graphql文件

Export your schema from any source (database, PGPM module, endpoint) into a directory of
.graphql
files:
bash
undefined
从任意源(数据库、PGPM模块、端点)将Schema导出为.graphql文件目录:
bash
undefined

Export from database

从数据库导出

npx @constructive-io/graphql-codegen --schema-only --schemas public --schema-only-output ./schemas --schema-only-filename public.graphql
npx @constructive-io/graphql-codegen --schema-only --schemas public --schema-only-output ./schemas --schema-only-filename public.graphql

Export from PGPM module (via config)

从PGPM模块导出(通过配置)

npx @constructive-io/graphql-codegen --schema-only -c graphql-codegen.config.ts
npx @constructive-io/graphql-codegen --schema-only -c graphql-codegen.config.ts

Export from endpoint

从端点导出

npx @constructive-io/graphql-codegen --schema-only -e https://api.example.com/graphql --schema-only-output ./schemas

Or programmatically:

```typescript
import { generate } from '@constructive-io/graphql-codegen';

// Export from database
await generate({
  db: { schemas: ['public'] },
  schemaOnly: true,
  schemaOnlyOutput: './schemas',
  schemaOnlyFilename: 'public.graphql',
});

// Export from PGPM module
await generate({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['app_public'],
  },
  schemaOnly: true,
  schemaOnlyOutput: './schemas',
  schemaOnlyFilename: 'app_public.graphql',
});
npx @constructive-io/graphql-codegen --schema-only -e https://api.example.com/graphql --schema-only-output ./schemas

或通过编程方式导出:

```typescript
import { generate } from '@constructive-io/graphql-codegen';

// 从数据库导出
await generate({
  db: { schemas: ['public'] },
  schemaOnly: true,
  schemaOnlyOutput: './schemas',
  schemaOnlyFilename: 'public.graphql',
});

// 从PGPM模块导出
await generate({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['app_public'],
  },
  schemaOnly: true,
  schemaOnlyOutput: './schemas',
  schemaOnlyFilename: 'app_public.graphql',
});

Step 2: Generate code from the schema directory

步骤2:从Schema目录生成代码

Point
schemaDir
at the directory containing your
.graphql
files. Each file automatically becomes a separate target:
typescript
// graphql-codegen.config.ts
import { defineConfig } from '@constructive-io/graphql-codegen';

export default defineConfig({
  schemaDir: './schemas',   // Directory of .graphql files
  output: './generated',    // Each file becomes ./generated/{name}/
  reactQuery: true,
  orm: true,
});
bash
npx @constructive-io/graphql-codegen -c graphql-codegen.config.ts
Given
schemas/public.graphql
and
schemas/admin.graphql
, this produces:
generated/
  public/          # Generated from public.graphql
    hooks/
    orm/
  admin/           # Generated from admin.graphql
    hooks/
    orm/
Why this approach is best:
  • Deterministic
    .graphql
    files are static, version-controllable artifacts
  • Portable — no live database or endpoint needed at code generation time
  • Fast — no network requests or ephemeral database creation during codegen
  • Reviewable — schema changes show up as clear diffs in version control
schemaDir
指向包含.graphql文件的目录,每个文件会自动成为一个独立的目标:
typescript
// graphql-codegen.config.ts
import { defineConfig } from '@constructive-io/graphql-codegen';

export default defineConfig({
  schemaDir: './schemas',   // .graphql文件所在目录
  output: './generated',    // 每个文件会生成到./generated/{name}/目录下
  reactQuery: true,
  orm: true,
});
bash
npx @constructive-io/graphql-codegen -c graphql-codegen.config.ts
如果存在
schemas/public.graphql
schemas/admin.graphql
,将生成如下结构:
generated/
  public/          # 从public.graphql生成
    hooks/
    orm/
  admin/           # 从admin.graphql生成
    hooks/
    orm/
该方案的优势
  • 确定性 — .graphql文件是静态的、可版本控制的产物
  • 可移植性 — 代码生成时无需依赖实时数据库或端点
  • 高效性 — 代码生成过程中无需网络请求或临时数据库创建
  • 可评审性 — Schema变更会在版本控制系统中显示为清晰的差异

Quick Start

快速开始

Installation

安装

bash
pnpm add @constructive-io/graphql-codegen
bash
pnpm add @constructive-io/graphql-codegen

Generate React Query Hooks

生成React Query Hooks

bash
npx @constructive-io/graphql-codegen --react-query -s ./schemas/public.graphql -o ./generated
bash
npx @constructive-io/graphql-codegen --react-query -s ./schemas/public.graphql -o ./generated

Generate ORM Client

生成ORM客户端

bash
npx @constructive-io/graphql-codegen --orm -s ./schemas/public.graphql -o ./generated
bash
npx @constructive-io/graphql-codegen --orm -s ./schemas/public.graphql -o ./generated

Generate CLI

生成CLI

bash
npx @constructive-io/graphql-codegen --cli -s ./schemas/public.graphql -o ./generated
bash
npx @constructive-io/graphql-codegen --cli -s ./schemas/public.graphql -o ./generated

Generate from Endpoint

从端点生成

bash
npx @constructive-io/graphql-codegen --react-query -e https://api.example.com/graphql -o ./generated
bash
npx @constructive-io/graphql-codegen --react-query -e https://api.example.com/graphql -o ./generated

Generate from Database

从数据库生成

bash
npx @constructive-io/graphql-codegen --react-query --schemas public,app_public -o ./generated
bash
npx @constructive-io/graphql-codegen --react-query --schemas public,app_public -o ./generated

Programmatic API

编程式API

Use the
generate()
function to integrate codegen into your build scripts or tools.
使用
generate()
函数将代码生成集成到构建脚本或工具中。

Import and Basic Usage

导入与基础用法

typescript
import { generate } from '@constructive-io/graphql-codegen';

// Generate from endpoint
await generate({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  reactQuery: true,
  orm: true,
});

// Node.js with undici dispatcher (fixes localhost DNS issues)
await generate({
  endpoint: 'http://api.localhost:3000/graphql',
  output: './generated',
  reactQuery: true,
  browserCompatible: false,  // Use undici with custom dispatcher
});
typescript
import { generate } from '@constructive-io/graphql-codegen';

// 从端点生成
await generate({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  reactQuery: true,
  orm: true,
});

// Node.js环境使用undici调度器(解决localhost DNS问题)
await generate({
  endpoint: 'http://api.localhost:3000/graphql',
  output: './generated',
  reactQuery: true,
  browserCompatible: false,  // 使用带自定义调度器的undici
});

Schema Sources

Schema源

typescript
// From GraphQL endpoint
await generate({
  endpoint: 'https://api.example.com/graphql',
  headers: { Authorization: 'Bearer token' },
  reactQuery: true,
});

// From schema file
await generate({
  schemaFile: './schema.graphql',
  output: './generated',
  orm: true,
});

// From database (explicit schemas)
await generate({
  db: { schemas: ['public', 'app_public'] },
  reactQuery: true,
});

// From database (auto-discover via API names)
await generate({
  db: { apiNames: ['my_api'] },
  orm: true,
});

// From PGPM module
await generate({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['public'],
  },
  reactQuery: true,
});
typescript
// 从GraphQL端点
await generate({
  endpoint: 'https://api.example.com/graphql',
  headers: { Authorization: 'Bearer token' },
  reactQuery: true,
});

// 从Schema文件
await generate({
  schemaFile: './schema.graphql',
  output: './generated',
  orm: true,
});

// 从数据库(指定Schema)
await generate({
  db: { schemas: ['public', 'app_public'] },
  reactQuery: true,
});

// 从数据库(通过API名称自动发现)
await generate({
  db: { apiNames: ['my_api'] },
  orm: true,
});

// 从PGPM模块
await generate({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['public'],
  },
  reactQuery: true,
});

Generate Options

生成选项

typescript
interface GenerateOptions {
  // Schema source (choose one)
  endpoint?: string;
  schemaFile?: string;
  schemaDir?: string;       // Directory of .graphql files — auto-expands to multi-target
  db?: {
    config?: { host, port, database, user, password };
    schemas?: string[];
    apiNames?: string[];    // Auto-discover schemas from services_public.api_schemas
    pgpm?: { modulePath, workspacePath, moduleName };
    keepDb?: boolean;       // Keep ephemeral DB after introspection (debugging)
  };
  
  // Output
  output?: string;  // Default: './generated/graphql'
  
  // Generators
  reactQuery?: boolean;  // Default: false
  orm?: boolean;         // Default: false
  cli?: CliConfig | boolean; // Default: false — generate inquirerer CLI
  
  // Schema export (instead of code generation)
  schemaOnly?: boolean;          // Export schema to .graphql file, skip codegen
  schemaOnlyOutput?: string;     // Output directory for exported schema
  schemaOnlyFilename?: string;   // Filename (default: 'schema.graphql')
  
  // Documentation (generated alongside code)
  docs?: DocsConfig | boolean; // Default: { readme: true, agents: true, mcp: false, skills: false }
  
  // Node.js HTTP adapter (auto-enabled when cli is true)
  nodeHttpAdapter?: boolean; // Default: false
  
  // Filtering
  tables?: { include?, exclude?, systemExclude? };
  queries?: { include?, exclude?, systemExclude? };
  mutations?: { include?, exclude?, systemExclude? };
  excludeFields?: string[];
  
  // Authentication
  headers?: Record<string, string>;
  authorization?: string;  // Convenience for Authorization header
  
  // Options
  verbose?: boolean;
  dryRun?: boolean;
  skipCustomOperations?: boolean;
}
typescript
interface GenerateOptions {
  // Schema源(选其一)
  endpoint?: string;
  schemaFile?: string;
  schemaDir?: string;       // .graphql文件目录 — 自动扩展为多目标
  db?: {
    config?: { host, port, database, user, password };
    schemas?: string[];
    apiNames?: string[];    // 从services_public.api_schemas自动发现Schema
    pgpm?: { modulePath, workspacePath, moduleName };
    keepDb?: boolean;       // 自省后保留临时数据库(用于调试)
  };
  
  // 输出
  output?: string;  // 默认值: './generated/graphql'
  
  // 生成器
  reactQuery?: boolean;  // 默认值: false
  orm?: boolean;         // 默认值: false
  cli?: CliConfig | boolean; // 默认值: false — 生成inquirerer CLI
  
  // Schema导出(替代代码生成)
  schemaOnly?: boolean;          // 将Schema导出为.graphql文件,跳过代码生成
  schemaOnlyOutput?: string;     // 导出Schema的输出目录
  schemaOnlyFilename?: string;   // 文件名(默认: 'schema.graphql')
  
  // 文档(与代码同时生成)
  docs?: DocsConfig | boolean; // 默认值: { readme: true, agents: true, mcp: false, skills: false }
  
  // Node.js HTTP适配器(启用CLI时自动开启)
  nodeHttpAdapter?: boolean; // 默认值: false
  
  // 过滤
  tables?: { include?, exclude?, systemExclude? };
  queries?: { include?, exclude?, systemExclude? };
  mutations?: { include?, exclude?, systemExclude? };
  excludeFields?: string[];
  
  // 认证
  headers?: Record<string, string>;
  authorization?: string;  // 便捷设置Authorization头
  
  // 其他选项
  verbose?: boolean;
  dryRun?: boolean;
  skipCustomOperations?: boolean;
}

Build Script Example

构建脚本示例

typescript
// scripts/codegen.ts
import { generate } from '@constructive-io/graphql-codegen';

async function main() {
  console.log('Generating GraphQL code...');
  
  const result = await generate({
    endpoint: process.env.GRAPHQL_ENDPOINT!,
    headers: {
      Authorization: `Bearer ${process.env.API_TOKEN}`,
    },
    output: './src/generated',
    reactQuery: true,
    orm: true,
    tables: {
      include: ['User', 'Post', 'Comment'],
    },
  });
  
  if (!result.success) {
    console.error('Codegen failed:', result.error);
    process.exit(1);
  }
  
  console.log('✓ Code generated successfully');
}

main();
typescript
// scripts/codegen.ts
import { generate } from '@constructive-io/graphql-codegen';

async function main() {
  console.log('生成GraphQL代码...');
  
  const result = await generate({
    endpoint: process.env.GRAPHQL_ENDPOINT!,
    headers: {
      Authorization: `Bearer ${process.env.API_TOKEN}`,
    },
    output: './src/generated',
    reactQuery: true,
    orm: true,
    tables: {
      include: ['User', 'Post', 'Comment'],
    },
  });
  
  if (!result.success) {
    console.error('代码生成失败:', result.error);
    process.exit(1);
  }
  
  console.log('✓ 代码生成成功');
}

main();

CLI Commands

CLI命令

Note: The CLI does not use subcommands. All options are passed directly to
graphql-codegen
.
CommandPurpose
npx @constructive-io/graphql-codegen
Generate code (use
--react-query
,
--orm
, and/or
--cli
flags)
npx @constructive-io/graphql-codegen --react-query
Generate React Query hooks
npx @constructive-io/graphql-codegen --orm
Generate ORM client
npx @constructive-io/graphql-codegen --cli
Generate inquirerer-based CLI
npx @constructive-io/graphql-codegen --react-query --orm --cli
Generate all three
注意:CLI不使用子命令,所有选项直接传递给
graphql-codegen
命令用途
npx @constructive-io/graphql-codegen
生成代码(使用
--react-query
--orm
和/或
--cli
标志)
npx @constructive-io/graphql-codegen --react-query
生成React Query hooks
npx @constructive-io/graphql-codegen --orm
生成ORM客户端
npx @constructive-io/graphql-codegen --cli
生成基于inquirerer的CLI
npx @constructive-io/graphql-codegen --react-query --orm --cli
同时生成以上三种产物

Common Options

常用选项

OptionDescription
-e, --endpoint <url>
GraphQL endpoint URL
-s, --schema-file <path>
Path to GraphQL schema file
--schema-dir <path>
Directory of
.graphql
files (auto multi-target)
--schemas <list>
PostgreSQL schemas (comma-separated)
--api-names <list>
API names for auto schema discovery
-o, --output <dir>
Output directory (default:
./generated/graphql
)
-c, --config <path>
Config file path
--react-query
Generate React Query hooks
--orm
Generate ORM client
--cli
Generate inquirerer-based CLI
--schema-only
Export schema to
.graphql
file (no code generation)
--schema-only-output <dir>
Output directory for schema export
--schema-only-filename <name>
Filename for exported schema (default:
schema.graphql
)
-a, --authorization <token>
Authorization header
-t, --target <name>
Target name in multi-target config
--dry-run
Preview without writing
-v, --verbose
Show detailed output
选项说明
-e, --endpoint <url>
GraphQL端点URL
-s, --schema-file <path>
GraphQL Schema文件路径
--schema-dir <path>
.graphql文件目录(自动多目标)
--schemas <list>
PostgreSQL Schema(逗号分隔)
--api-names <list>
用于自动发现Schema的API名称
-o, --output <dir>
输出目录(默认:
./generated/graphql
-c, --config <path>
配置文件路径
--react-query
生成React Query hooks
--orm
生成ORM客户端
--cli
生成基于inquirerer的CLI
--schema-only
将Schema导出为.graphql文件(不生成代码)
--schema-only-output <dir>
Schema导出的输出目录
--schema-only-filename <name>
导出Schema的文件名(默认:
schema.graphql
-a, --authorization <token>
Authorization头
-t, --target <name>
多目标配置中的目标名称
--dry-run
预览生成结果,不写入文件
-v, --verbose
显示详细输出

Configuration File

配置文件

Create a configuration file manually:
File:
graphql-codegen.config.ts
typescript
import { defineConfig } from '@constructive-io/graphql-codegen';

// RECOMMENDED: From a directory of .graphql schema files
export default defineConfig({
  schemaDir: './schemas',
  output: './generated',
  reactQuery: true,
  orm: true,
});

// From a single schema file
export default defineConfig({
  schemaFile: './schemas/public.graphql',
  output: './generated',
  reactQuery: true,
  orm: true,
});

// From GraphQL endpoint
export default defineConfig({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  reactQuery: true,
  orm: true,
  headers: {
    Authorization: `Bearer ${process.env.API_TOKEN}`,
  },
});

// From database
export default defineConfig({
  db: {
    schemas: ['public', 'app_public'],  // Explicit schemas
    // OR
    apiNames: ['my_api'],  // Auto-discover schemas from API
  },
  output: './generated',
  reactQuery: true,
});

// From PGPM module
export default defineConfig({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['public'],
  },
  output: './generated',
  orm: true,
});
手动创建配置文件:
文件:
graphql-codegen.config.ts
typescript
import { defineConfig } from '@constructive-io/graphql-codegen';

// 推荐:从.graphql Schema文件目录生成
export default defineConfig({
  schemaDir: './schemas',
  output: './generated',
  reactQuery: true,
  orm: true,
});

// 从单个Schema文件生成
export default defineConfig({
  schemaFile: './schemas/public.graphql',
  output: './generated',
  reactQuery: true,
  orm: true,
});

// 从GraphQL端点生成
export default defineConfig({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  reactQuery: true,
  orm: true,
  headers: {
    Authorization: `Bearer ${process.env.API_TOKEN}`,
  },
});

// 从数据库生成
export default defineConfig({
  db: {
    schemas: ['public', 'app_public'],  // 指定Schema
    // 或
    apiNames: ['my_api'],  // 从API自动发现Schema
  },
  output: './generated',
  reactQuery: true,
});

// 从PGPM模块生成
export default defineConfig({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['public'],
  },
  output: './generated',
  orm: true,
});

CLI Generation

CLI生成配置

typescript
export default defineConfig({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  cli: true,  // Generate CLI with default tool name
  // OR with options:
  cli: {
    toolName: 'myapp',      // Config stored at ~/.myapp/
    entryPoint: true,        // Generate runnable index.ts
    builtinNames: {          // Override infra command names
      auth: 'credentials',
      context: 'env',
    },
  },
});
When
cli: true
,
nodeHttpAdapter
is auto-enabled (Node.js HTTP adapter for localhost subdomain resolution).
typescript
export default defineConfig({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  cli: true,  // 使用默认工具名称生成CLI
  // 或自定义选项:
  cli: {
    toolName: 'myapp',      // 配置存储在~/.myapp/
    entryPoint: true,        // 生成可执行的index.ts
    builtinNames: {          // 覆盖基础命令名称
      auth: 'credentials',
      context: 'env',
    },
  },
});
当设置
cli: true
时,
nodeHttpAdapter
会自动启用(用于localhost子域名解析的Node.js HTTP适配器)。

Documentation Generation

文档生成配置

typescript
export default defineConfig({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  orm: true,
  docs: true,  // Enable all doc formats
  // OR configure individually:
  docs: {
    readme: true,   // README.md — human-readable overview
    agents: true,   // AGENTS.md — structured for LLM consumption
    mcp: false,     // mcp.json — MCP tool definitions
    skills: true,   // skills/ — per-command .md skill files (Devin-compatible)
  },
});
docs.skills
: Generates a
skills/
directory with individual
.md
files for each command. Compatible with Devin and similar agent skill systems. Each skill file contains description, usage, and examples.
docs.agents
: Generates an
AGENTS.md
with tool definitions, exact signatures, input/output schemas, workflow recipes, and machine-parseable sections.
docs.mcp
: Generates an
mcp.json
with MCP (Model Context Protocol) tool definitions. Each CLI command becomes a tool with typed JSON Schema
inputSchema
.
typescript
export default defineConfig({
  endpoint: 'https://api.example.com/graphql',
  output: './generated',
  orm: true,
  docs: true,  // 启用所有文档格式
  // 或单独配置:
  docs: {
    readme: true,   // README.md — 人类可读的概览文档
    agents: true,   // AGENTS.md — 为LLM设计的结构化文档
    mcp: false,     // mcp.json — MCP工具定义
    skills: true,   // skills/ — 每个命令对应一个.md技能文件(兼容Devin)
  },
});
docs.skills
:生成
skills/
目录,每个命令对应一个.md文件,兼容Devin及类似Agent技能系统。每个技能文件包含描述、用法和示例。
docs.agents
:生成
AGENTS.md
,包含工具定义、精确签名、输入输出Schema、工作流示例和机器可解析的章节。
docs.mcp
:生成
mcp.json
,包含MCP(模型上下文协议)工具定义。每个CLI命令会成为一个带有类型化JSON Schema
inputSchema
的工具。

Node.js HTTP Adapter

Node.js HTTP适配器

typescript
export default defineConfig({
  endpoint: 'http://api.localhost:3000/graphql',
  output: './generated',
  orm: true,
  nodeHttpAdapter: true,  // Generates node-fetch.ts with NodeHttpAdapter
});
The
NodeHttpAdapter
uses
node:http
/
node:https
for requests, enabling local development with subdomain-based routing (e.g.,
auth.localhost:3000
). No global patching required.
typescript
import { NodeHttpAdapter } from './orm/node-fetch';
import { createClient } from './orm';

const db = createClient({
  adapter: new NodeHttpAdapter(endpoint, headers),
});
typescript
export default defineConfig({
  endpoint: 'http://api.localhost:3000/graphql',
  output: './generated',
  orm: true,
  nodeHttpAdapter: true,  // 生成带有NodeHttpAdapter的node-fetch.ts
});
NodeHttpAdapter
使用
node:http
/
node:https
发送请求,支持基于子域名的本地开发路由(如
auth.localhost:3000
),无需全局补丁。
typescript
import { NodeHttpAdapter } from './orm/node-fetch';
import { createClient } from './orm';

const db = createClient({
  adapter: new NodeHttpAdapter(endpoint, headers),
});

Multi-Target Configuration

多目标配置

There are three ways to get multi-target generation:
有三种方式实现多目标生成:

1. Schema directory (recommended)

1. Schema目录(推荐)

schemaDir
automatically creates one target per
.graphql
file in the directory:
typescript
export default defineConfig({
  schemaDir: './schemas',   // Contains public.graphql, admin.graphql, etc.
  output: './generated',    // Produces ./generated/public/, ./generated/admin/, etc.
  reactQuery: true,
  orm: true,
});
schemaDir
会自动为目录中的每个.graphql文件创建一个目标:
typescript
export default defineConfig({
  schemaDir: './schemas',   // 包含public.graphql、admin.graphql等
  output: './generated',    // 生成./generated/public/、./generated/admin/等
  reactQuery: true,
  orm: true,
});

2. Explicit multi-target

2. 显式多目标

Define each target explicitly when they have different sources or options:
typescript
export default defineConfig({
  public: {
    schemaFile: './schemas/public.graphql',
    output: './generated/public',
    reactQuery: true,
  },
  admin: {
    schemaFile: './schemas/admin.graphql',
    output: './generated/admin',
    orm: true,
    cli: true,
  },
});
当目标有不同的源或选项时,可显式定义每个目标:
typescript
export default defineConfig({
  public: {
    schemaFile: './schemas/public.graphql',
    output: './generated/public',
    reactQuery: true,
  },
  admin: {
    schemaFile: './schemas/admin.graphql',
    output: './generated/admin',
    orm: true,
    cli: true,
  },
});

3. Auto-expand from multiple API names

3. 从多个API名称自动扩展

When
db.apiNames
contains multiple entries, each API name automatically becomes a separate target:
typescript
export default defineConfig({
  db: { apiNames: ['public', 'admin'] },
  output: './generated',  // Produces ./generated/public/, ./generated/admin/
  orm: true,
});
This queries
services_public.api_schemas
for each API name to resolve the corresponding PostgreSQL schemas, then generates each target independently.
db.apiNames
包含多个条目时,每个API名称会自动成为一个独立目标:
typescript
export default defineConfig({
  db: { apiNames: ['public', 'admin'] },
  output: './generated',  // 生成./generated/public/、./generated/admin/
  orm: true,
});
这会为每个API名称查询
services_public.api_schemas
以解析对应的PostgreSQL Schema,然后独立生成每个目标。

Shared PGPM sources in multi-target

多目标中的共享PGPM源

When multiple targets share the same PGPM module, the codegen automatically deduplicates ephemeral database creation. One ephemeral database is created and reused across all targets that reference the same module, avoiding redundant deploys.
当多个目标共享同一个PGPM模块时,代码生成器会自动去重临时数据库创建。同一个模块对应的所有目标会复用一个临时数据库,避免重复部署。

Using Generated Hooks

使用生成的Hooks

Configure Client (once at app startup)

配置客户端(应用启动时执行一次)

typescript
import { configure } from '@/generated/hooks';

configure({
  endpoint: process.env.NEXT_PUBLIC_GRAPHQL_URL!,
  headers: { Authorization: `Bearer ${getToken()}` },
});
typescript
import { configure } from '@/generated/hooks';

configure({
  endpoint: process.env.NEXT_PUBLIC_GRAPHQL_URL!,
  headers: { Authorization: `Bearer ${getToken()}` },
});

Query Data

查询数据

typescript
import { useUsersQuery } from '@/generated/hooks';

function UserList() {
  const { data, isLoading } = useUsersQuery({
    first: 10,
    filter: { role: { eq: 'ADMIN' } },
  });

  if (isLoading) return <Spinner />;
  return <ul>{data?.users?.nodes.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
typescript
import { useUsersQuery } from '@/generated/hooks';

function UserList() {
  const { data, isLoading } = useUsersQuery({
    first: 10,
    filter: { role: { eq: 'ADMIN' } },
  });

  if (isLoading) return <Spinner />;
  return <ul>{data?.users?.nodes.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}

Mutate Data

修改数据

typescript
import { useCreateUserMutation } from '@/generated/hooks';

function CreateUser() {
  const createUser = useCreateUserMutation();

  return (
    <button onClick={() => createUser.mutate({ input: { name: 'John' } })}>
      Create
    </button>
  );
}
typescript
import { useCreateUserMutation } from '@/generated/hooks';

function CreateUser() {
  const createUser = useCreateUserMutation();

  return (
    <button onClick={() => createUser.mutate({ input: { name: 'John' } })}>
      创建用户
    </button>
  );
}

Using Generated CLI

使用生成的CLI

When
cli: true
is set, codegen generates inquirerer-based CLI commands to
{output}/cli/
.
当设置
cli: true
时,代码生成器会在
{output}/cli/
目录下生成基于inquirerer的CLI命令。

Generated Structure

生成的结构

generated/cli/
  commands/           # One file per table + custom operations
    users.ts          # CRUD commands for users table
    posts.ts          # CRUD commands for posts table
    my-query.ts       # Custom query command
  command-map.ts      # Maps command names to handlers
  executor.ts         # Command executor with auth context
  utils.ts            # Shared utilities
  node-fetch.ts       # NodeHttpAdapter for localhost
  index.ts            # Entry point (if entryPoint: true)
generated/cli/
  commands/           # 每个表和自定义操作对应一个文件
    users.ts          # 用户表的CRUD命令
    posts.ts          # 帖子表的CRUD命令
    my-query.ts       # 自定义查询命令
  command-map.ts      # 命令名称到处理器的映射
  executor.ts         # 带认证上下文的命令执行器
  utils.ts            # 共享工具函数
  node-fetch.ts       # 用于localhost的NodeHttpAdapter
  index.ts            # 入口文件(如果entryPoint: true)

Running the CLI

运行CLI

If
entryPoint: true
is set:
bash
npx ts-node generated/cli/index.ts
Or integrate the command map into your own CLI:
typescript
import { commands } from './generated/cli/command-map';
import { Inquirerer } from 'inquirerer';

const prompter = new Inquirerer();
await commands.users.list(argv, prompter);
如果设置了
entryPoint: true
bash
npx ts-node generated/cli/index.ts
或将命令映射集成到自己的CLI中:
typescript
import { commands } from './generated/cli/command-map';
import { Inquirerer } from 'inquirerer';

const prompter = new Inquirerer();
await commands.users.list(argv, prompter);

Built-in Infrastructure Commands

内置基础命令

The CLI includes infrastructure commands:
  • auth (or
    credentials
    if name collides) — manage API credentials stored via appstash
  • context (or
    env
    if name collides) — manage endpoint and auth context
CLI包含以下基础命令:
  • auth(如果名称冲突则为
    credentials
    ) — 管理存储在appstash中的API凭证
  • context(如果名称冲突则为
    env
    ) — 管理端点和认证上下文

Using Generated ORM

使用生成的ORM

Create Client

创建客户端

typescript
import { createClient } from '@/generated/orm';

export const db = createClient({
  endpoint: process.env.GRAPHQL_URL!,
  headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
});
typescript
import { createClient } from '@/generated/orm';

export const db = createClient({
  endpoint: process.env.GRAPHQL_URL!,
  headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
});

Query Data

查询数据

typescript
const users = await db.user.findMany({
  select: { id: true, name: true, email: true },
  filter: { role: { eq: 'ADMIN' } },
  first: 10,
}).execute().unwrap();
typescript
const users = await db.user.findMany({
  select: { id: true, name: true, email: true },
  filter: { role: { eq: 'ADMIN' } },
  first: 10,
}).execute().unwrap();

Relations

关联查询

typescript
const posts = await db.post.findMany({
  select: {
    id: true,
    title: true,
    author: { select: { id: true, name: true } },
  },
}).execute().unwrap();

// posts[0].author.name is fully typed
typescript
const posts = await db.post.findMany({
  select: {
    id: true,
    title: true,
    author: { select: { id: true, name: true } },
  },
}).execute().unwrap();

// posts[0].author.name是完全类型化的

Error Handling

错误处理

typescript
const result = await db.user.findOne({ id: '123' }).execute();

if (result.ok) {
  console.log(result.value.name);
} else {
  console.error(result.error.message);
}

// Or use helpers
const user = await db.user.findOne({ id }).execute().unwrap(); // throws on error
const user = await db.user.findOne({ id }).execute().unwrapOr(defaultUser);
typescript
const result = await db.user.findOne({ id: '123' }).execute();

if (result.ok) {
  console.log(result.value.name);
} else {
  console.error(result.error.message);
}

// 或使用辅助函数
const user = await db.user.findOne({ id }).execute().unwrap(); // 错误时抛出异常
const user = await db.user.findOne({ id }).execute().unwrapOr(defaultUser);

Schema Sources

Schema源优先级

The codegen supports 6 schema source modes. The recommended approach is schema export +
schemaDir
(see top of this document).
PrioritySourceConfig KeyBest For
1 (recommended)Schema directory
schemaDir: './schemas'
Deterministic, portable, multi-target
2Schema file
schemaFile: './schema.graphql'
Single schema, simple projects
3PGPM module (path)
db.pgpm.modulePath
Schema export from a pgpm module
4PGPM workspace
db.pgpm.workspacePath + moduleName
Schema export from a pgpm workspace
5Database
db.schemas
or
db.apiNames
Schema export from a live database
6Endpoint
endpoint
Schema export from a running server
代码生成器支持6种Schema源模式。推荐使用Schema导出 +
schemaDir
的方式(见本文档开头)。
优先级配置键最佳适用场景
1(推荐)Schema目录
schemaDir: './schemas'
确定性、可移植性、多目标场景
2Schema文件
schemaFile: './schema.graphql'
单一Schema、简单项目
3PGPM模块(路径)
db.pgpm.modulePath
从pgpm模块导出Schema
4PGPM工作区
db.pgpm.workspacePath + moduleName
从pgpm工作区导出Schema
5数据库
db.schemas
db.apiNames
从实时数据库导出Schema
6端点
endpoint
从运行中的服务器导出Schema

From Schema Directory (recommended)

从Schema目录生成(推荐)

bash
npx @constructive-io/graphql-codegen --react-query --orm --schema-dir ./schemas -o ./generated
bash
npx @constructive-io/graphql-codegen --react-query --orm --schema-dir ./schemas -o ./generated

From Schema File

从Schema文件生成

bash
npx @constructive-io/graphql-codegen --react-query -s ./schemas/public.graphql -o ./generated
bash
npx @constructive-io/graphql-codegen --react-query -s ./schemas/public.graphql -o ./generated

From GraphQL Endpoint

从GraphQL端点生成

bash
npx @constructive-io/graphql-codegen --react-query -e https://api.example.com/graphql
bash
npx @constructive-io/graphql-codegen --react-query -e https://api.example.com/graphql

From Database

从数据库生成

bash
undefined
bash
undefined

Explicit schemas

指定Schema

npx @constructive-io/graphql-codegen --orm --schemas public,app_public
npx @constructive-io/graphql-codegen --orm --schemas public,app_public

Auto-discover from API names

通过API名称自动发现

npx @constructive-io/graphql-codegen --react-query --api-names my_api
undefined
npx @constructive-io/graphql-codegen --react-query --api-names my_api
undefined

From PGPM Module

从PGPM模块生成

typescript
// In config file — direct path
export default defineConfig({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['public'],
  },
  reactQuery: true,
});

// In config file — workspace + module name
export default defineConfig({
  db: {
    pgpm: {
      workspacePath: '.',
      moduleName: 'my-module',
    },
    schemas: ['app_public'],
  },
  orm: true,
});
PGPM module sources create an ephemeral database, deploy the module, introspect the schema via PostGraphile, then tear down the database (unless
keepDb: true
for debugging).
typescript
// 配置文件中 — 直接路径
export default defineConfig({
  db: {
    pgpm: { modulePath: './packages/my-module' },
    schemas: ['public'],
  },
  reactQuery: true,
});

// 配置文件中 — 工作区 + 模块名称
export default defineConfig({
    db: {
        pgpm: {
            workspacePath: '.',
            moduleName: 'my-module',
        },
        schemas: ['app_public'],
    },
    orm: true,
});
PGPM模块源会创建一个临时数据库,部署模块,通过PostGraphile自省Schema,然后销毁数据库(调试时可设置
keepDb: true
保留数据库)。

Schema Export

Schema导出

Schema export (
schemaOnly: true
) fetches a schema from any source and writes it as a
.graphql
SDL file without generating any code. This is the recommended first step in the two-step workflow.
Schema导出模式(
schemaOnly: true
)会从任意源获取Schema,并将其保存为.graphql SDL文件,不生成任何代码。这是两步工作流中推荐的第一步。

CLI

CLI方式

bash
undefined
bash
undefined

Export from database

从数据库导出

npx @constructive-io/graphql-codegen --schema-only --schemas public --schema-only-output ./schemas --schema-only-filename public.graphql
npx @constructive-io/graphql-codegen --schema-only --schemas public --schema-only-output ./schemas --schema-only-filename public.graphql

Export from endpoint

从端点导出

npx @constructive-io/graphql-codegen --schema-only -e https://api.example.com/graphql --schema-only-output ./schemas
npx @constructive-io/graphql-codegen --schema-only -e https://api.example.com/graphql --schema-only-output ./schemas

Export from PGPM module (via config)

从PGPM模块导出(通过配置)

npx @constructive-io/graphql-codegen --schema-only -c codegen.config.ts
undefined
npx @constructive-io/graphql-codegen --schema-only -c codegen.config.ts
undefined

Programmatic

编程式方式

typescript
import { generate } from '@constructive-io/graphql-codegen';

const result = await generate({
  db: { schemas: ['public'] },
  schemaOnly: true,
  schemaOnlyOutput: './schemas',
  schemaOnlyFilename: 'public.graphql',
});

console.log(result.message); // "Schema exported to ./schemas/public.graphql"
typescript
import { generate } from '@constructive-io/graphql-codegen';

const result = await generate({
  db: { schemas: ['public'] },
  schemaOnly: true,
  schemaOnlyOutput: './schemas',
  schemaOnlyFilename: 'public.graphql',
});

console.log(result.message); // "Schema已导出到./schemas/public.graphql"

Options

选项

OptionDescriptionDefault
schemaOnly
Enable schema export mode (no code generation)
false
schemaOnlyOutput
Output directory for the exported schemaSame as
output
schemaOnlyFilename
Filename for the exported schema
schema.graphql
选项说明默认值
schemaOnly
启用Schema导出模式(不生成代码)
false
schemaOnlyOutput
导出Schema的输出目录
output
相同
schemaOnlyFilename
导出Schema的文件名
schema.graphql

Query Key Factory (React Query)

Query Key工厂(React Query)

Generated hooks include a centralized query key factory for type-safe cache management:
typescript
import { userKeys, invalidate, remove } from '@/generated/hooks';
import { useQueryClient } from '@tanstack/react-query';

const queryClient = useQueryClient();

// Invalidate queries (triggers refetch)
invalidate.user.all(queryClient);        // All user queries
invalidate.user.lists(queryClient);      // All list queries
invalidate.user.detail(queryClient, id); // Specific user

// Remove from cache (for delete operations)
remove.user(queryClient, userId);

// Track in-flight mutations
import { userMutationKeys } from '@/generated/hooks';
import { useIsMutating } from '@tanstack/react-query';

const isMutating = useIsMutating({ mutationKey: userMutationKeys.all });
See
references/query-keys.md
for details.
生成的Hooks包含一个集中式的Query Key工厂,用于类型安全的缓存管理:
typescript
import { userKeys, invalidate, remove } from '@/generated/hooks';
import { useQueryClient } from '@tanstack/react-query';

const queryClient = useQueryClient();

// 使查询失效(触发重新获取)
invalidate.user.all(queryClient);        // 所有用户相关查询
invalidate.user.lists(queryClient);      // 所有列表查询
invalidate.user.detail(queryClient, id); // 特定用户查询

// 从缓存中移除(用于删除操作)
remove.user(queryClient, userId);

// 跟踪进行中的修改操作
import { userMutationKeys } from '@/generated/hooks';
import { useIsMutating } from '@tanstack/react-query';

const isMutating = useIsMutating({ mutationKey: userMutationKeys.all });
详情请参考
references/query-keys.md

Filter Syntax

过滤语法

typescript
// Comparison
filter: { age: { eq: 25 } }
filter: { age: { gte: 18, lt: 65 } }
filter: { status: { in: ['ACTIVE', 'PENDING'] } }

// String
filter: { name: { contains: 'john' } }
filter: { email: { endsWith: '.com' } }

// Logical
filter: {
  OR: [
    { role: { eq: 'ADMIN' } },
    { role: { eq: 'MODERATOR' } },
  ],
}
typescript
// 比较操作
filter: { age: { eq: 25 } }
filter: { age: { gte: 18, lt: 65 } }
filter: { status: { in: ['ACTIVE', 'PENDING'] } }

// 字符串操作
filter: { name: { contains: 'john' } }
filter: { email: { endsWith: '.com' } }

// 逻辑操作
filter: {
  OR: [
    { role: { eq: 'ADMIN' } },
    { role: { eq: 'MODERATOR' } },
  ],
}

Troubleshooting

故障排除

IssueSolution
No hooks generatedAdd
reactQuery: true
to config
No CLI generatedAdd
cli: true
to config
Schema not accessibleVerify endpoint URL and auth headers
Missing
_meta
query
Ensure PostGraphile v5+ with Meta plugin
Type errors after regenerationDelete output directory and regenerate
Import errorsVerify generated code exists and paths match
Auth errors at runtimeCheck
configure()
headers are set
Localhost fetch errors (Node.js)Enable
nodeHttpAdapter: true
for localhost subdomain resolution
No skill files generatedSet
docs: { skills: true }
in config
Schema export produces empty fileVerify database/endpoint has tables in the specified schemas
schemaDir
generates nothing
Ensure directory contains
.graphql
files (not
.gql
or other extensions)
问题解决方案
未生成Hooks在配置中添加
reactQuery: true
未生成CLI在配置中添加
cli: true
Schema无法访问验证端点URL和认证头
缺少
_meta
查询
确保使用PostGraphile v5+并启用Meta插件
重新生成后出现类型错误删除输出目录并重新生成
导入错误验证生成的代码是否存在,路径是否匹配
运行时认证错误检查
configure()
中的头信息是否正确设置
Node.js环境下localhost请求错误启用
nodeHttpAdapter: true
以支持localhost子域名解析
未生成技能文件在配置中设置
docs: { skills: true }
Schema导出后文件为空验证数据库/端点的指定Schema中是否包含表
schemaDir
未生成任何内容
确保目录中包含.graphql文件(不支持.gql或其他扩展名)

References

参考文档

For detailed documentation on specific topics only when needed, see references/:
  • CLI options and configuration:
    cli-reference.md
    ,
    config-reference.md
  • Advanced usage patterns:
    hooks-patterns.md
    ,
    orm-patterns.md
  • Error handling and relations:
    error-handling.md
    ,
    relations.md
  • Query key factory and cache management:
    query-keys.md
  • Generated output structure:
    hooks-output.md
    ,
    orm-output.md
如需特定主题的详细文档,请查看references/目录:
  • CLI选项与配置:
    cli-reference.md
    ,
    config-reference.md
  • 高级使用模式:
    hooks-patterns.md
    ,
    orm-patterns.md
  • 错误处理与关联查询:
    error-handling.md
    ,
    relations.md
  • Query Key工厂与缓存管理:
    query-keys.md
  • 生成输出结构:
    hooks-output.md
    ,
    orm-output.md