Skip to content

Commit 04cf6be

Browse files
AgentEnderclaude
andcommitted
feat(cli-forge): enhance makeComposableBuilder to track children types
Updates makeComposableBuilder to properly track child commands added by the builder function via a new TChildren2 type parameter. Adds new exported types: - ComposableBuilder<TArgs2, TAddedChildren>: Type for composable builder functions - ExtractChildren<T>: Extracts TChildren from a CLI type - ExtractArgs<T>: Extracts TArgs from a CLI type The enhanced type tracking allows chain() to properly accumulate child command types when composing multiple builders together. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent d9ed677 commit 04cf6be

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

packages/cli-forge/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,10 @@ export * from './lib/public-api';
33
export { default } from './lib/public-api';
44
export { chain } from '@cli-forge/parser';
55
export { makeComposableBuilder } from './lib/composable-builder';
6+
export type {
7+
ComposableBuilder,
8+
ExtractArgs,
9+
ExtractChildren,
10+
} from './lib/composable-builder';
611
export type { ArgumentsOf } from './lib/utils';
712
export { ConfigurationProviders } from './lib/configuration-providers';
Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,57 @@
11
import { ParsedArgs } from '@cli-forge/parser';
22
import { CLI } from './public-api';
33

4-
export function makeComposableBuilder<T2 extends ParsedArgs>(
5-
fn: (init: CLI<ParsedArgs>) => CLI<T2>
4+
/**
5+
* Extracts the TChildren type parameter from a CLI type.
6+
*/
7+
export type ExtractChildren<T> = T extends CLI<any, any, infer C, any>
8+
? C
9+
: never;
10+
11+
/**
12+
* Extracts the TArgs type parameter from a CLI type.
13+
*/
14+
export type ExtractArgs<T> = T extends CLI<infer A, any, any, any> ? A : never;
15+
16+
/**
17+
* Type for a composable builder function that transforms a CLI.
18+
* Used with `chain` to compose multiple builders.
19+
*/
20+
export type ComposableBuilder<
21+
TArgs2 extends ParsedArgs,
22+
// eslint-disable-next-line @typescript-eslint/ban-types
23+
TAddedChildren = {}
24+
> = <TInit extends ParsedArgs, THandlerReturn, TChildren, TParent>(
25+
init: CLI<TInit, THandlerReturn, TChildren, TParent>
26+
) => CLI<TInit & TArgs2, THandlerReturn, TChildren & TAddedChildren, TParent>;
27+
28+
/**
29+
* Creates a composable builder function that can be used with `chain`.
30+
* Can be used to add options, commands, or any other CLI modifications.
31+
* Children added by the builder function are properly tracked in the type.
32+
*
33+
* @typeParam TArgs2 - The args type after the builder runs
34+
* @typeParam TChildren2 - The children type added by the builder
35+
*/
36+
export function makeComposableBuilder<
37+
TArgs2 extends ParsedArgs,
38+
// eslint-disable-next-line @typescript-eslint/ban-types
39+
TChildren2 = {}
40+
>(
41+
fn: (
42+
// eslint-disable-next-line @typescript-eslint/ban-types
43+
init: CLI<ParsedArgs, any, {}, any>
44+
) => CLI<TArgs2, any, TChildren2, any>
645
) {
7-
return <TInit extends ParsedArgs>(init: CLI<TInit>) =>
8-
fn(init) as CLI<TInit & T2>;
46+
return <TInit extends ParsedArgs, THandlerReturn, TChildren, TParent>(
47+
init: CLI<TInit, THandlerReturn, TChildren, TParent>
48+
) =>
49+
// eslint-disable-next-line @typescript-eslint/ban-types
50+
fn(init as unknown as CLI<ParsedArgs, any, {}, any>) as unknown as CLI<
51+
TInit & TArgs2,
52+
THandlerReturn,
53+
TChildren & TChildren2,
54+
TParent
55+
>;
956
}
57+

0 commit comments

Comments
 (0)