Skip to content

Commit 64cb55d

Browse files
author
unknown
committed
feat(codegen): add CLI entry point generation option (cli.entryPoint)
- Add cli-entry.ts template with CLI bootstrap code (inquirerer, --version, --tty) - Add generateEntryPointFile() to utils-generator.ts (template-copy pattern) - Add entryPoint option to CliConfig interface (default: false) - Wire up in generateCli() and generateMultiTargetCli() - Pass entryPoint through generateMulti() for unified CLI - When enabled, generates index.ts in cli/ output directory This removes the last remaining hack from the constructive-hub CLI e2e test script (manual index.ts generation at test time).
1 parent b758178 commit 64cb55d

5 files changed

Lines changed: 76 additions & 2 deletions

File tree

graphql/codegen/src/core/codegen/cli/index.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
generateMultiTargetContextCommand,
1212
} from './infra-generator';
1313
import { generateTableCommand } from './table-command-generator';
14-
import { generateUtilsFile, generateNodeFetchFile } from './utils-generator';
14+
import { generateUtilsFile, generateNodeFetchFile, generateEntryPointFile } from './utils-generator';
1515

1616
export interface GenerateCliOptions {
1717
tables: CleanTable[];
@@ -91,6 +91,13 @@ export function generateCli(options: GenerateCliOptions): GenerateCliResult {
9191
);
9292
files.push(commandMapFile);
9393

94+
// Generate entry point if configured
95+
const generateEntryPoint =
96+
typeof cliConfig === 'object' && !!cliConfig.entryPoint;
97+
if (generateEntryPoint) {
98+
files.push(generateEntryPointFile());
99+
}
100+
94101
return {
95102
files,
96103
stats: {
@@ -123,6 +130,8 @@ export interface GenerateMultiTargetCliOptions {
123130
targets: MultiTargetCliTarget[];
124131
/** Enable NodeHttpAdapter for *.localhost subdomain routing */
125132
nodeHttpAdapter?: boolean;
133+
/** Generate a runnable index.ts entry point */
134+
entryPoint?: boolean;
126135
}
127136

128137
export function resolveBuiltinNames(
@@ -232,6 +241,11 @@ export function generateMultiTargetCli(
232241
});
233242
files.push(commandMapFile);
234243

244+
// Generate entry point if configured
245+
if (options.entryPoint) {
246+
files.push(generateEntryPointFile());
247+
}
248+
235249
return {
236250
files,
237251
stats: {
@@ -267,5 +281,5 @@ export {
267281
export type { MultiTargetDocsInput } from './docs-generator';
268282
export { resolveDocsConfig } from '../docs-utils';
269283
export type { GeneratedDocFile, McpTool } from '../docs-utils';
270-
export { generateUtilsFile } from './utils-generator';
284+
export { generateUtilsFile, generateEntryPointFile } from './utils-generator';
271285
export type { GeneratedFile, MultiTargetExecutorInput } from './executor-generator';

graphql/codegen/src/core/codegen/cli/utils-generator.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,21 @@ export function generateNodeFetchFile(): GeneratedFile {
7676
),
7777
};
7878
}
79+
80+
/**
81+
* Generate an index.ts entry point file for the CLI.
82+
*
83+
* Creates a runnable entry point that imports the command map,
84+
* handles --version and --tty flags, and starts the CLI.
85+
* This is off by default (cliEntryPoint: false) since many projects
86+
* provide their own entry point with custom configuration.
87+
*/
88+
export function generateEntryPointFile(): GeneratedFile {
89+
return {
90+
fileName: 'index.ts',
91+
content: readTemplateFile(
92+
'cli-entry.ts',
93+
'CLI entry point',
94+
),
95+
};
96+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* CLI entry point for running the generated CLI application.
3+
*
4+
* Creates an inquirerer CLI instance with the generated command map,
5+
* handles --version and --tty flags, and runs the CLI.
6+
*
7+
* NOTE: This file is read at codegen time and written to output.
8+
* Any changes here will affect all generated CLI entry points.
9+
*/
10+
11+
import { CLI, CLIOptions } from 'inquirerer';
12+
import { commands } from './commands';
13+
14+
if (process.argv.includes('--version') || process.argv.includes('-v')) {
15+
console.log('0.0.1');
16+
process.exit(0);
17+
}
18+
19+
// Check for --tty false to enable non-interactive mode (noTty)
20+
const ttyIdx = process.argv.indexOf('--tty');
21+
const noTty = ttyIdx !== -1 && process.argv[ttyIdx + 1] === 'false';
22+
23+
const options: Partial<CLIOptions> = {
24+
noTty,
25+
minimistOpts: { alias: { v: 'version', h: 'help' } },
26+
};
27+
28+
const app = new CLI(commands, options);
29+
app.run().catch((e) => {
30+
console.error('Unexpected error:', e);
31+
process.exit(1);
32+
});

graphql/codegen/src/core/generate.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ export async function generateMulti(
696696
builtinNames: cliConfig.builtinNames,
697697
targets: cliTargets,
698698
nodeHttpAdapter: multiNodeHttpAdapter,
699+
entryPoint: cliConfig.entryPoint,
699700
});
700701

701702
const cliFilesToWrite = files.map((file) => ({

graphql/codegen/src/types/config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,15 @@ export interface CliConfig {
199199
* context -> 'context' (renamed to 'env' on collision)
200200
*/
201201
builtinNames?: BuiltinNames;
202+
203+
/**
204+
* Generate a runnable index.ts entry point for the CLI.
205+
* When true, generates an index.ts that imports the command map,
206+
* handles --version and --tty flags, and starts the inquirerer CLI.
207+
* Useful for projects that want a ready-to-run CLI without a custom entry point.
208+
* @default false
209+
*/
210+
entryPoint?: boolean;
202211
}
203212

204213
/**

0 commit comments

Comments
 (0)