Skip to content

Commit 9050181

Browse files
committed
feat(inquirerer): add parseArgv helper and tests
- Add parseArgv() to wrap minimist so developers don't need to import it - Add succinct tests for CLI utilities (parseArgv, extractFirst, package helpers) - Update README to use parseArgv instead of importing minimist directly - Update @inquirerer/utils to re-export parseArgv
1 parent fe21073 commit 9050181

5 files changed

Lines changed: 70 additions & 10 deletions

File tree

packages/inquirerer-utils/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// Re-export core CLI utilities from inquirerer
22
export {
3+
parseArgv,
34
extractFirst,
45
cliExitWithError,
56
getPackageJson,
67
getPackageVersion,
78
getPackageName
89
} from 'inquirerer';
9-
export type { ParsedArgs, CliExitOptions, PackageJson } from 'inquirerer';
10+
export type { ParsedArgs, ParseArgvOptions, CliExitOptions, PackageJson } from 'inquirerer';
1011

1112
// Update checking (requires appstash, not available in inquirerer)
1213
export { checkForUpdates, shouldSkipUpdateCheck } from './update-check';

packages/inquirerer/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,13 +1279,12 @@ console.log(`Welcome to ${toolName}!`);
12791279

12801280
### Argument Parsing
12811281

1282-
Extract the first positional argument for command routing:
1282+
Parse command-line arguments and extract subcommands:
12831283

12841284
```typescript
1285-
import { extractFirst, ParsedArgs } from 'inquirerer';
1286-
import minimist from 'minimist';
1285+
import { parseArgv, extractFirst } from 'inquirerer';
12871286

1288-
const argv = minimist(process.argv.slice(2));
1287+
const argv = parseArgv(process.argv);
12891288
const { first, newArgv } = extractFirst(argv);
12901289

12911290
// Running: mycli generate --output ./dist
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { parseArgv, extractFirst, getPackageJson, getPackageVersion, getPackageName } from '../src';
2+
3+
describe('CLI utilities', () => {
4+
describe('parseArgv', () => {
5+
it('parses flags and positional args', () => {
6+
const argv = parseArgv(['node', 'cli', 'generate', '--config', 'test.json', '-v']);
7+
expect(argv._).toEqual(['generate']);
8+
expect(argv['config']).toBe('test.json');
9+
expect(argv['v']).toBe(true);
10+
});
11+
});
12+
13+
describe('extractFirst', () => {
14+
it('extracts first positional argument', () => {
15+
const { first, newArgv } = extractFirst({ _: ['init', 'myproject'], config: 'test.json' } as any);
16+
expect(first).toBe('init');
17+
expect(newArgv._).toEqual(['myproject']);
18+
expect((newArgv as any).config).toBe('test.json');
19+
});
20+
21+
it('handles empty positional args', () => {
22+
const { first, newArgv } = extractFirst({ _: [] });
23+
expect(first).toBeUndefined();
24+
expect(newArgv._).toEqual([]);
25+
});
26+
});
27+
28+
describe('package helpers', () => {
29+
it('gets package.json from __dirname', () => {
30+
const pkg = getPackageJson(__dirname);
31+
expect(pkg.name).toBe('inquirerer');
32+
expect(pkg.version).toBeDefined();
33+
});
34+
35+
it('getPackageVersion returns version string', () => {
36+
const version = getPackageVersion(__dirname);
37+
expect(typeof version).toBe('string');
38+
expect(version).toMatch(/^\d+\.\d+\.\d+/);
39+
});
40+
41+
it('getPackageName returns name string', () => {
42+
const name = getPackageName(__dirname);
43+
expect(name).toBe('inquirerer');
44+
});
45+
});
46+
});

packages/inquirerer/src/cli/argv.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1-
import { ParsedArgs } from 'minimist';
1+
import minimist, { Opts, ParsedArgs } from 'minimist';
2+
3+
/**
4+
* Parse command-line arguments using minimist.
5+
* Wrapper around minimist so you don't need to import it directly.
6+
*
7+
* @example
8+
* ```typescript
9+
* const argv = parseArgv(process.argv);
10+
* console.log(argv.config); // --config value
11+
* ```
12+
*/
13+
export const parseArgv = (args: string[] = process.argv, opts?: Opts): ParsedArgs => {
14+
return minimist(args.slice(2), opts);
15+
};
216

317
/**
418
* Extracts the first positional argument from argv and returns it along with the remaining argv.
5-
* This is useful for command routing in CLI applications where the first argument is a subcommand.
19+
* Useful for command routing where the first argument is a subcommand.
620
*
721
* @example
822
* ```typescript
@@ -21,4 +35,4 @@ export const extractFirst = (argv: Partial<ParsedArgs>) => {
2135
return { first, newArgv };
2236
};
2337

24-
export type { ParsedArgs } from 'minimist';
38+
export type { ParsedArgs, Opts as ParseArgvOptions } from 'minimist';

packages/inquirerer/src/cli/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
export { extractFirst } from './argv';
2-
export type { ParsedArgs } from './argv';
1+
export { parseArgv, extractFirst } from './argv';
2+
export type { ParsedArgs, ParseArgvOptions } from './argv';
33

44
export { cliExitWithError } from './error';
55
export type { CliExitOptions } from './error';

0 commit comments

Comments
 (0)