Skip to content

Conversation

@knoan
Copy link

@knoan knoan commented Dec 12, 2025

Summary

Add support for file arguments as an alternative to --input directory in typia generate CLI.

# New: file arguments
typia generate src/**/*.typia.ts --output src/generated --project tsconfig.json

# Existing: directory mode (unchanged)
typia generate --input src/templates --output src/generated --project tsconfig.json

Changes

  • ArgumentParser.ts: Use program.opts() for reliable option extraction, capture positional file arguments
  • TypiaGenerateWizard.ts: Add [files...] argument definition, skip --input prompt when files provided
  • TypiaProgrammer.ts: Handle file list mode - use files directly instead of gather(), output to --output with basename

CLI Interface

Usage: typia generate [options] [files...]

Arguments:
  files                 input .ts files (alternative to --input)

Options:
  --input [path]        input directory
  --output [directory]  output directory
  --project [project]   tsconfig.json file location

Testing

  • CLI help shows new [files...] argument
  • Options before files: typia generate --output dir file.ts works
  • Files before options: typia generate file.ts --output dir works
  • Transformation produces correct output

Closes #1700

CLI now accepts .ts files as positional arguments:
  typia generate file1.ts file2.ts --output dir --project tsconfig.json

Changes:
- ArgumentParser.ts: use program.opts() for reliable option extraction,
  capture positional file arguments
- TypiaGenerateWizard.ts: add [files...] argument definition,
  skip --input prompt when files provided
- TypiaProgrammer.ts: handle file list mode - use files directly
  instead of gather(), output to --output with basename

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for accepting file arguments as an alternative to --input directory in the typia generate CLI command. This allows users to specify individual .ts files for transformation using shell glob patterns, which is useful when template files are spread across multiple subdirectories.

Key changes:

  • File arguments are captured as variadic arguments via Commander.js and passed through the option pipeline
  • The transformation logic branches based on whether files or a directory is provided
  • When using files, output goes directly to the output directory using basenames instead of preserving directory structure

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
src/executable/setup/ArgumentParser.ts Modified action handler to capture variadic file arguments from Commander.js and attach them to options
src/executable/TypiaGenerateWizard.ts Added [files...] argument definition and conditional logic to skip --input prompt when files are provided
src/programmers/TypiaProgrammer.ts Implemented dual-mode logic to handle file lists vs directories, including path resolution, TypeScript program creation, filtering, and output path generation

Comment on lines +151 to +153
const to: string = hasFiles
? path.join(location.output, path.basename(file.fileName))
: path.resolve(file.fileName).replace(location.input, location.output);
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using file arguments mode, the output path can collide if multiple input files have the same basename. For example, src/users/user.typia.ts and src/orders/user.typia.ts would both write to output/user.typia.ts, with the second overwriting the first. Consider adding validation to detect duplicate basenames or implement a conflict resolution strategy.

Copilot uses AI. Check for mistakes.
const resolvedFiles = hasFiles
? location.files!.map((f) => path.resolve(f))
: [];

Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing validation for file existence and accessibility. When files are provided as arguments, there's no check that they exist or are readable before attempting to create the TypeScript program. This could lead to unclear error messages later in the process. Consider adding validation similar to the directory validation for input paths.

Suggested change
// Validate provided files (when using explicit file list)
if (hasFiles) {
for (const file of resolvedFiles) {
try {
const stat = await fs.promises.stat(file);
if (stat.isFile() === false) {
throw new URIError(
"Error on TypiaGenerator.generate(): input file path is not a file: " +
file,
);
}
await fs.promises.access(file, fs.constants.R_OK);
} catch {
throw new URIError(
"Error on TypiaGenerator.generate(): input file does not exist or is not readable: " +
file,
);
}
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +100
// Skip import transformation when processing individual files
...(hasFiles
? []
: [
ImportTransformer.transform({
from: location.input,
to: location.output,
}),
]),
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "Skip import transformation when processing individual files" but doesn't explain why this is necessary. The ImportTransformer appears to rewrite import paths from the input directory structure to the output directory structure. Skipping this for individual files may cause import paths to break if the generated files have different relative paths. This needs clarification or a more robust solution.

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +34
commander.program.action(async (...args: unknown[]) => {
try {
// Commander passes: (positionalArgs..., options, command)
// Use program.opts() for reliable option extraction
const options = commander.program.opts() as Partial<T>;
// If there are positional arguments (files), attach them to options
if (args.length > 0 && Array.isArray(args[0])) {
(options as Partial<T> & { files?: string[] }).files = args[0];
}
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new file arguments feature in the CLI lacks automated test coverage. While the repository has comprehensive testing for transformation features, there are no tests for CLI functionality like the ArgumentParser or TypiaGenerateWizard. Consider adding integration tests that verify file argument parsing, validation, and correct handling of both directory and file modes.

Copilot uses AI. Check for mistakes.
@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 23, 2025

Open in StackBlitz

npm i https://pkg.pr.new/typia@1702

commit: 43c3fc5

Copy link
Owner

@samchon samchon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can I test this logic?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request good first issue Good for newcomers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Accept file arguments in typia generate CLI

2 participants