cli-nano 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,14 +8,19 @@
8
8
 
9
9
  ## cli-nano
10
10
 
11
- Super small custom CLI similar to `Yargs` but much smaller, it uses a similar approach to NodeJS `parseArgs()` to create command-line tool (aka CLI). It is much more complete than NodeJS `parseArgs()` since it supports Positional Arguments, negated flags and also accepts both syntax `--camelCase` and/or `--kebab-case`.
11
+ Simple library to create command-line tool (aka CLI) which is quite similar to [`Yargs`](https://github.com/yargs/yargs), it is as configurable as Yargs but is a fraction of its size. The library is also inspired by NodeJS `parseArgs()` but is again more configurable so that we really get what we would expect from a more complete CLI builder.
12
12
 
13
13
  ### Features
14
14
  - Parses arguments
15
- - Converts flags to camelCase
15
+ - Supports defining Positional arguments
16
+ - Supports Variadic args (1 or more positional args)
17
+ - Automatically converts flags to camelCase
18
+ - accepts both `--camelCase` and `--kebab-case`
16
19
  - Negates flags when using the `--no-` prefix
17
- - Outputs version when `--version`
18
- - Outputs description and supplied help text when `--help`
20
+ - Outputs version, when defined, when using `--version`
21
+ - Outputs description and supplied help text when using `--help`
22
+ - Supports defining `required` options
23
+ - Supports `default` values
19
24
  - No dependencies!
20
25
 
21
26
  ### Install
@@ -32,29 +37,31 @@ import { type Config, parseArgs } from 'cli-nano';
32
37
 
33
38
  const config: Config = {
34
39
  command: {
35
- name: 'unicorns',
36
- description: 'Show a list of unicorns',
40
+ name: 'serve',
41
+ description: 'Start a server with the given options',
37
42
  positional: [
38
43
  {
39
- name: 'inputs',
40
- description: 'unicorn inputs',
44
+ name: 'input',
45
+ description: 'serving files or directory',
41
46
  type: 'string',
42
- variadic: true, // one or more inputs could be provided
47
+ variadic: true, // 1 or more
43
48
  required: true,
44
49
  },
45
50
  {
46
- name: 'output',
47
- description: 'output directory',
48
- type: 'string',
51
+ name: 'port',
52
+ type: 'number',
53
+ description: 'port to bind on',
49
54
  required: false,
50
- },
55
+ default: 5000, // optional default value
56
+ },
51
57
  ],
52
58
  },
53
59
  options: {
54
60
  dryRun: {
55
61
  alias: 'd',
56
62
  type: 'boolean',
57
- description: 'Show what would be copied, but do not actually copy any files',
63
+ description: 'Show what would be done, but do not actually start the server',
64
+ default: false, // optional default value
58
65
  },
59
66
  exclude: {
60
67
  alias: 'e',
@@ -65,6 +72,7 @@ const config: Config = {
65
72
  type: 'boolean',
66
73
  alias: 'r',
67
74
  description: 'Enable rainbow mode',
75
+ default: true,
68
76
  },
69
77
  verbose: {
70
78
  alias: 'V',
@@ -74,51 +82,61 @@ const config: Config = {
74
82
  up: {
75
83
  type: 'number',
76
84
  description: 'slice a path off the bottom of the paths',
85
+ default: 1,
77
86
  },
78
- bar: {
79
- alias: 'b',
87
+ display: {
88
+ alias: 'D',
80
89
  required: true,
81
- description: 'a required bar option',
90
+ description: 'a required display option',
82
91
  }
83
92
  },
84
93
  version: '0.1.6',
85
94
  };
86
95
 
87
- const argv = parseArgs(config);
88
- console.log(argv);
96
+ const args = parseArgs(config);
97
+ console.log(args);
98
+
99
+ // do something with parse arguments, for example
100
+ // startServer(args);
89
101
  ```
90
102
 
91
103
  #### Example CLI Calls
92
104
 
93
105
  ```sh
94
- # Show help
95
- unicorns --help
106
+ # Show help guide (created by reading CLI config)
107
+ serve --help
108
+
109
+ # Show version (when defined)
110
+ serve --version
96
111
 
97
- # Show version
98
- unicorns --version
112
+ # Uses default port 5000
113
+ serve dist/index.html
99
114
 
100
115
  # With required and optional positionals
101
- unicorns file1.txt file2.txt output/ -b value
116
+ serve index1.html index2.html 8080 -D value
102
117
 
103
118
  # With boolean and array options
104
- unicorns file1.txt output/ --dryRun --exclude pattern1 --exclude pattern2 -b value
119
+ serve index.html 7000 --dryRun --exclude pattern1 --exclude pattern2 -D value
105
120
 
106
121
  # With negated boolean
107
- unicorns file1.txt output/ --no-dryRun -b value
122
+ serve index.html 7000 --no-dryRun -D value
108
123
 
109
124
  # With short aliases
110
- unicorns file1.txt output/ -d -e pattern1 -e pattern2 -b value
125
+ serve index.html 7000 -d -e pattern1 -e pattern2 -D value
111
126
 
112
127
  # With number option
113
- unicorns file1.txt output/ --up 2 -b value
128
+ serve index.html 7000 --up 2 -D value
114
129
  ```
115
130
 
116
131
  #### Notes
117
132
 
133
+ - **Default values**: Use the `default` property in an option or positional argument to specify a value if the user does not provide one.
134
+ - Example for option: `{ type: 'boolean', default: false }`
135
+ - Example for positional: `{ name: 'port', type: 'number', default: 5000 }`
118
136
  - **Variadic positionals**: Use `variadic: true` for arguments that accept multiple values.
119
137
  - **Required options**: Add `required: true` to enforce presence of an option.
120
138
  - **Negated booleans**: Use `--no-flag` to set a boolean option to `false`.
121
139
  - **Array options**: Repeat the flag to collect multiple values (e.g., `--exclude a --exclude b`).
122
140
  - **Aliases**: Use `alias` for short flags (e.g., `-d` for `--dryRun`).
123
141
 
124
- See [examples/](examples/) for more usage patterns.
142
+ See [examples/](examples/) for more usage patterns.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import type { Config } from './interfaces.js';
2
+ export type * from './interfaces.js';
2
3
  export declare function parseArgs(config: Config): Record<string, any>;
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAG/D,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqM7D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAG/D,mBAAmB,iBAAiB,CAAC;AAErC,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA0N7D"}
package/dist/index.js CHANGED
@@ -19,13 +19,23 @@ export function parseArgs(config) {
19
19
  printHelp(config);
20
20
  process.exit(0);
21
21
  }
22
- if (args.includes('--version') || args.includes('-v')) {
23
- console.log(version);
22
+ if ((version && args.includes('--version')) || args.includes('-v')) {
23
+ console.log(version || 'No version specified');
24
24
  process.exit(0);
25
25
  }
26
+ // Validate: required positionals must come before optional ones
27
+ const positionals = command.positional ?? [];
28
+ let foundOptional = false;
29
+ for (const pos of positionals) {
30
+ if (!pos.required) {
31
+ foundOptional = true;
32
+ }
33
+ if (foundOptional && pos.required) {
34
+ throw new Error(`Invalid positional argument configuration: required positional "${pos.name}" cannot follow optional positional(s).`);
35
+ }
36
+ }
26
37
  // Handle positional arguments
27
38
  let argIndex = 0;
28
- const positionals = command.positional ?? [];
29
39
  const nonOptionArgs = [];
30
40
  while (argIndex < args.length && !args[argIndex].startsWith('-')) {
31
41
  nonOptionArgs.push(args[argIndex]);
@@ -41,16 +51,25 @@ export function parseArgs(config) {
41
51
  const usagePositionals = positionals.map(posArg => `<${posArg.name}>`).join(' ');
42
52
  throw new Error(`Missing required positional argument, i.e.: "${command.name} ${usagePositionals}"`);
43
53
  }
44
- result[pos.name] = values;
54
+ result[pos.name] = !pos.required && values.length === 0 && pos.default !== undefined ? pos.default : values;
45
55
  nonOptionIndex += values.length;
46
56
  }
47
57
  else {
48
- const value = nonOptionArgs[nonOptionIndex++];
49
- if (!value) {
58
+ const value = nonOptionArgs[nonOptionIndex];
59
+ // Check if there are enough args left for required positionals
60
+ const requiredLeft = positionals.slice(i).filter(p => p.required).length;
61
+ const argsLeft = nonOptionArgs.length - nonOptionIndex;
62
+ if (value !== undefined && (argsLeft > requiredLeft - (pos.required ? 1 : 0) || pos.required)) {
63
+ result[pos.name] = value;
64
+ nonOptionIndex++;
65
+ }
66
+ else if (!pos.required && pos.default !== undefined) {
67
+ result[pos.name] = pos.default;
68
+ }
69
+ else if (pos.required) {
50
70
  const usagePositionals = positionals.map(posArg => `<${posArg.name}>`).join(' ');
51
71
  throw new Error(`Missing required positional argument, i.e.: "${command.name} ${usagePositionals}"`);
52
72
  }
53
- result[pos.name] = value;
54
73
  }
55
74
  }
56
75
  // Handle options
@@ -101,9 +120,7 @@ export function parseArgs(config) {
101
120
  // Try matching aliases in all forms
102
121
  for (const key of Object.keys(options)) {
103
122
  const opt = options[key];
104
- if (!opt.alias)
105
- continue;
106
- if (opt.alias.includes(arg) || opt.alias.includes(kebabToCamel(arg)) || opt.alias.includes(camelToKebab(arg))) {
123
+ if (opt.alias && (opt.alias.includes(arg) || opt.alias.includes(kebabToCamel(arg)) || opt.alias.includes(camelToKebab(arg)))) {
107
124
  option = opt;
108
125
  configKey = key;
109
126
  break;
@@ -118,9 +135,7 @@ export function parseArgs(config) {
118
135
  const optionKeys = Object.keys(options);
119
136
  for (let j = 0; j < optionKeys.length; j++) {
120
137
  const opt = options[optionKeys[j]];
121
- if (!opt.alias)
122
- continue;
123
- if (opt.alias === arg || opt.alias === kebabToCamel(arg) || opt.alias === camelToKebab(arg)) {
138
+ if (opt.alias && (opt.alias === arg || opt.alias === kebabToCamel(arg) || opt.alias === camelToKebab(arg))) {
124
139
  option = opt;
125
140
  configKey = optionKeys[j];
126
141
  break;
@@ -147,19 +162,13 @@ export function parseArgs(config) {
147
162
  if (!option || !configKey) {
148
163
  throw new Error(`Unknown option: ${arg}`);
149
164
  }
150
- switch (option.type || 'string') {
165
+ switch (option.type) {
151
166
  case 'boolean':
152
167
  if (result[configKey] !== undefined) {
153
168
  throw new Error('Providing same negated and truthy argument are not allowed');
154
169
  }
155
170
  result[configKey] = !argOrg.startsWith('--no-') && !argOrg.startsWith('-no-');
156
171
  break;
157
- case 'string':
158
- if (args[argIndex + 1] === undefined || args[argIndex + 1].startsWith('-')) {
159
- throw new Error(`Missing value for option: ${configKey}`);
160
- }
161
- result[configKey] = args[++argIndex];
162
- break;
163
172
  case 'number':
164
173
  if (args[argIndex + 1] === undefined || args[argIndex + 1].startsWith('-')) {
165
174
  throw new Error(`Missing value for option: ${configKey}`);
@@ -176,6 +185,13 @@ export function parseArgs(config) {
176
185
  result[configKey].push(arrayValue);
177
186
  break;
178
187
  }
188
+ case 'string':
189
+ default:
190
+ if (args[argIndex + 1] === undefined || args[argIndex + 1].startsWith('-')) {
191
+ throw new Error(`Missing value for option: ${configKey}`);
192
+ }
193
+ result[configKey] = args[++argIndex];
194
+ break;
179
195
  }
180
196
  }
181
197
  else {
@@ -183,8 +199,12 @@ export function parseArgs(config) {
183
199
  }
184
200
  argIndex++;
185
201
  }
186
- // After all parsing, check for required options
202
+ // After all parsing, assign any `default` CLI options when undefined
203
+ // and check for any missing `required` CLI options
187
204
  Object.entries(options).forEach(([key, opt]) => {
205
+ if (result[key] === undefined && opt.default !== undefined) {
206
+ result[key] = opt.default;
207
+ }
188
208
  if (opt.required && result[key] === undefined) {
189
209
  const aliasStr = opt.alias ? `-${opt.alias}, ` : '';
190
210
  throw new Error(`Missing required option: ${aliasStr}--${key}`);
@@ -192,8 +212,9 @@ export function parseArgs(config) {
192
212
  });
193
213
  return result;
194
214
  }
215
+ /** print CLI help documentation to the screen */
195
216
  function printHelp(config) {
196
- const { command, options } = config;
217
+ const { command, options, version } = config;
197
218
  // Build usage string for positionals
198
219
  const usagePositionals = (command.positional ?? [])
199
220
  .map(p => {
@@ -210,6 +231,7 @@ function printHelp(config) {
210
231
  command.positional?.forEach(arg => {
211
232
  console.log(` ${arg.name.padEnd(20)}${arg.description.slice(0, 65).padEnd(65)}[${arg.type || 'string'}]`);
212
233
  });
234
+ // Build usage string for options
213
235
  console.log('\nOptions:');
214
236
  Object.keys(options).forEach(key => {
215
237
  const option = options[key];
@@ -217,9 +239,12 @@ function printHelp(config) {
217
239
  const aliasStr = option.alias ? `-${option.alias}, ` : '';
218
240
  console.log(` ${aliasStr.padEnd(4)}--${key.padEnd(14)}${(option.description || '').slice(0, 65).padEnd(65)}[${option.type || 'string'}]${requiredStr}`);
219
241
  });
242
+ // Print default options (help and version)
220
243
  console.log('\nDefault options:');
221
244
  console.log(`${padString(' -h, --help', 21)} ${padString('Show help', 64)} [boolean]`);
222
- console.log(`${padString(' -v, --version', 21)} ${padString('Show version number', 64)} [boolean]`);
245
+ if (version) {
246
+ console.log(`${padString(' -v, --version', 21)} ${padString('Show version number', 64)} [boolean]`);
247
+ }
223
248
  console.log('\n');
224
249
  }
225
250
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -5,29 +5,34 @@ export interface ArgumentOptions {
5
5
  description: string;
6
6
  /** defaults to undefined, provide shorter aliases as command options */
7
7
  alias?: string | string[];
8
+ /** default value for the option if not provided */
9
+ default?: any;
8
10
  /** defaults to false, is the option required? */
9
11
  required?: boolean;
10
12
  }
13
+ export interface PositionalArgument {
14
+ /** positional argument name (it will be displayed in the help docs) */
15
+ name: string;
16
+ /** positional argument description */
17
+ description: string;
18
+ /** postional argument type */
19
+ type?: 'string' | 'boolean' | 'number' | 'array';
20
+ /** defaults to false, allows multiple values for this positional argument */
21
+ variadic?: boolean;
22
+ /** default value for the option if not provided */
23
+ default?: any;
24
+ /** defaults to false, is the positional argument required? */
25
+ required?: boolean;
26
+ }
11
27
  export interface CommandOptions {
12
28
  /** CLI command name, used in the help docs */
13
29
  name: string;
14
30
  description: string;
15
- positional?: {
16
- /** positional argument name (it will be displayed in the help docs) */
17
- name: string;
18
- /** positional argument description */
19
- description: string;
20
- /** postional argument type */
21
- type?: 'string';
22
- /** defaults to false, allows multiple values for this positional argument */
23
- variadic?: boolean;
24
- /** defaults to false, is the positional argument required? */
25
- required?: boolean;
26
- }[];
31
+ positional?: PositionalArgument[];
27
32
  }
28
33
  export interface Config {
29
34
  command: CommandOptions;
30
35
  options: Record<string, ArgumentOptions>;
31
- version: string;
36
+ version?: string;
32
37
  }
33
38
  //# sourceMappingURL=interfaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IACjD,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE;QACX,uEAAuE;QACvE,IAAI,EAAE,MAAM,CAAC;QACb,sCAAsC;QACtC,WAAW,EAAE,MAAM,CAAC;QACpB,8BAA8B;QAC9B,IAAI,CAAC,EAAE,QAAQ,CAAC;QAChB,6EAA6E;QAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,8DAA8D;QAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,EAAE,CAAC;CACL;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IACjD,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,mDAAmD;IACnD,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mDAAmD;IACnD,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cli-nano",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Mini command-line tool similar to `yargs` or `parseArgs` from Node.js that accepts positional arguments, flags and options.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -258,6 +258,11 @@ describe('parseArgs', () => {
258
258
  name: 'test',
259
259
  description: 'Test optional variadic',
260
260
  positional: [
261
+ {
262
+ name: 'outDir',
263
+ description: 'output directory',
264
+ required: true,
265
+ },
261
266
  {
262
267
  name: 'inputs',
263
268
  description: 'input files',
@@ -265,11 +270,6 @@ describe('parseArgs', () => {
265
270
  variadic: true,
266
271
  required: false,
267
272
  },
268
- {
269
- name: 'outDir',
270
- description: 'output directory',
271
- required: true,
272
- },
273
273
  ],
274
274
  },
275
275
  options: {},
@@ -279,15 +279,14 @@ describe('parseArgs', () => {
279
279
  let args = ['dist'];
280
280
  vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
281
281
  let result = parseArgs(config);
282
- expect(result.inputs).toEqual([]);
283
282
  expect(result.outDir).toBe('dist');
284
-
283
+ expect(result.inputs).toEqual([]);
285
284
  // Multiple inputs
286
- args = ['file1', 'file2', 'dist'];
285
+ args = ['dist', 'file1', 'file2'];
287
286
  vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
288
287
  result = parseArgs(config);
289
- expect(result.inputs).toEqual(['file1', 'file2']);
290
288
  expect(result.outDir).toBe('dist');
289
+ expect(result.inputs).toEqual(['file1', 'file2']);
291
290
  });
292
291
 
293
292
  it('should parse a single optional variadic positional arguments (zero or more)', () => {
@@ -499,4 +498,250 @@ describe('parseArgs', () => {
499
498
  expect(spy).toHaveBeenCalledWith(expect.stringContaining('[inFile]'));
500
499
  spy.mockRestore();
501
500
  });
501
+
502
+ it('should use default value for optional positional argument when not provided', () => {
503
+ const configWithDefaultPositional: Config = {
504
+ command: {
505
+ name: 'test',
506
+ description: 'Test default positional',
507
+ positional: [
508
+ {
509
+ name: 'outDir',
510
+ description: 'output directory',
511
+ required: true,
512
+ },
513
+ {
514
+ name: 'input',
515
+ description: 'input file',
516
+ type: 'string',
517
+ required: false,
518
+ default: 'default.txt',
519
+ },
520
+ ],
521
+ },
522
+ options: {},
523
+ version: '1.0.0',
524
+ };
525
+ const args = ['dist'];
526
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
527
+ const result = parseArgs(configWithDefaultPositional);
528
+ expect(result.outDir).toBe('dist');
529
+ expect(result.input).toBe('default.txt');
530
+ });
531
+
532
+ it('should throw if required positional comes after optional positional', () => {
533
+ const configInvalid: Config = {
534
+ command: {
535
+ name: 'badcli',
536
+ description: 'Invalid CLI',
537
+ positional: [
538
+ { name: 'foo', description: '', required: false },
539
+ { name: 'bar', description: '', required: true },
540
+ ],
541
+ },
542
+ options: {},
543
+ version: '1.0.0',
544
+ };
545
+ expect(() => parseArgs(configInvalid)).toThrow(
546
+ 'Invalid positional argument configuration: required positional "bar" cannot follow optional positional(s).',
547
+ );
548
+ });
549
+
550
+ it('should use default value for optional variadic positional argument when not provided', () => {
551
+ const configWithDefaultVariadic: Config = {
552
+ command: {
553
+ name: 'test',
554
+ description: 'Test default variadic positional',
555
+ positional: [
556
+ {
557
+ name: 'outDir',
558
+ description: 'output directory',
559
+ required: true,
560
+ },
561
+ {
562
+ name: 'inputs',
563
+ description: 'input files',
564
+ type: 'string',
565
+ variadic: true,
566
+ required: false,
567
+ default: ['default1.txt', 'default2.txt'],
568
+ },
569
+ ],
570
+ },
571
+ options: {},
572
+ version: '1.0.0',
573
+ };
574
+ const args = ['dist'];
575
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
576
+ const result = parseArgs(configWithDefaultVariadic);
577
+ expect(result.outDir).toBe('dist');
578
+ expect(result.inputs).toEqual(['default1.txt', 'default2.txt']);
579
+ });
580
+
581
+ it('should not use default value for option if value is provided', () => {
582
+ const configWithDefault: Config = {
583
+ ...config,
584
+ options: {
585
+ ...config.options,
586
+ file: {
587
+ alias: 'f',
588
+ type: 'string',
589
+ description: 'File path',
590
+ default: '/etc/passwd',
591
+ },
592
+ bar: {
593
+ alias: 'b',
594
+ required: true,
595
+ description: 'a required bar option',
596
+ },
597
+ },
598
+ };
599
+ const args = ['file1.txt', 'output/', '--file', '/tmp/override', '-b', 'value'];
600
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
601
+ const result = parseArgs(configWithDefault);
602
+ expect(result.file).toBe('/tmp/override');
603
+ });
604
+
605
+ it('should use default value for option with alias when not provided', () => {
606
+ const configWithDefault: Config = {
607
+ ...config,
608
+ options: {
609
+ ...config.options,
610
+ verbose: {
611
+ alias: 'V',
612
+ type: 'boolean',
613
+ description: 'Print more information',
614
+ default: true,
615
+ },
616
+ bar: {
617
+ alias: 'b',
618
+ required: true,
619
+ description: 'a required bar option',
620
+ },
621
+ },
622
+ };
623
+ const args = ['file1.txt', 'output/', '-b', 'value'];
624
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
625
+ const result = parseArgs(configWithDefault);
626
+ expect(result.verbose).toBe(true);
627
+ });
628
+
629
+ it('should use default value for boolean option when not provided', () => {
630
+ const configWithDefault: Config = {
631
+ ...config,
632
+ options: {
633
+ ...config.options,
634
+ follow: {
635
+ alias: 'F',
636
+ type: 'boolean',
637
+ description: 'Follow symbolic links',
638
+ default: true,
639
+ },
640
+ bar: {
641
+ alias: 'b',
642
+ required: true,
643
+ description: 'a required bar option',
644
+ },
645
+ },
646
+ };
647
+ const args = ['file1.txt', 'output/', '-b', 'value'];
648
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
649
+ const result = parseArgs(configWithDefault);
650
+ expect(result.follow).toBe(true);
651
+ });
652
+
653
+ it('should use default value for string option when not provided', () => {
654
+ const configWithDefault: Config = {
655
+ ...config,
656
+ options: {
657
+ ...config.options,
658
+ file: {
659
+ alias: 'f',
660
+ type: 'string',
661
+ description: 'File path',
662
+ default: '/etc/passwd',
663
+ },
664
+ bar: {
665
+ alias: 'b',
666
+ required: true,
667
+ description: 'a required bar option',
668
+ },
669
+ },
670
+ };
671
+ const args = ['file1.txt', 'output/', '-b', 'value'];
672
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
673
+ const result = parseArgs(configWithDefault);
674
+ expect(result.file).toBe('/etc/passwd');
675
+ });
676
+
677
+ it('should use default value for number option when not provided', () => {
678
+ const configWithDefault: Config = {
679
+ ...config,
680
+ options: {
681
+ ...config.options,
682
+ up: {
683
+ type: 'number',
684
+ description: 'slice a path off the bottom of the paths',
685
+ default: 5,
686
+ },
687
+ bar: {
688
+ alias: 'b',
689
+ required: true,
690
+ description: 'a required bar option',
691
+ },
692
+ },
693
+ };
694
+ const args = ['file1.txt', 'output/', '-b', 'value'];
695
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
696
+ const result = parseArgs(configWithDefault);
697
+ expect(result.up).toBe(5);
698
+ });
699
+
700
+ it('should use default value for array option when not provided', () => {
701
+ const configWithDefault: Config = {
702
+ ...config,
703
+ options: {
704
+ ...config.options,
705
+ exclude: {
706
+ alias: 'e',
707
+ type: 'array',
708
+ description: 'pattern or glob to exclude',
709
+ default: ['node_modules', 'dist'],
710
+ },
711
+ bar: {
712
+ alias: 'b',
713
+ required: true,
714
+ description: 'a required bar option',
715
+ },
716
+ },
717
+ };
718
+ const args = ['file1.txt', 'output/', '-b', 'value'];
719
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
720
+ const result = parseArgs(configWithDefault);
721
+ expect(result.exclude).toEqual(['node_modules', 'dist']);
722
+ });
723
+
724
+ it('should override default value when option is provided', () => {
725
+ const configWithDefault: Config = {
726
+ ...config,
727
+ options: {
728
+ ...config.options,
729
+ follow: {
730
+ alias: 'F',
731
+ type: 'boolean',
732
+ description: 'Follow symbolic links',
733
+ default: false,
734
+ },
735
+ bar: {
736
+ alias: 'b',
737
+ required: true,
738
+ description: 'a required bar option',
739
+ },
740
+ },
741
+ };
742
+ const args = ['file1.txt', 'output/', '--follow', '-b', 'value'];
743
+ vi.spyOn(process, 'argv', 'get').mockReturnValue(['node', 'cli.js', ...args]);
744
+ const result = parseArgs(configWithDefault);
745
+ expect(result.follow).toBe(true);
746
+ });
502
747
  });
package/src/index.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { ArgumentOptions, Config } from './interfaces.js';
2
2
  import { camelToKebab, kebabToCamel, padString } from './utils.js';
3
3
 
4
+ export type * from './interfaces.js';
5
+
4
6
  export function parseArgs(config: Config): Record<string, any> {
5
7
  const { command, options, version } = config;
6
8
  const args = process.argv.slice(2);
@@ -23,21 +25,32 @@ export function parseArgs(config: Config): Record<string, any> {
23
25
  printHelp(config);
24
26
  process.exit(0);
25
27
  }
26
- if (args.includes('--version') || args.includes('-v')) {
27
- console.log(version);
28
+ if ((version && args.includes('--version')) || args.includes('-v')) {
29
+ console.log(version || 'No version specified');
28
30
  process.exit(0);
29
31
  }
30
32
 
33
+ // Validate: required positionals must come before optional ones
34
+ const positionals = command.positional ?? [];
35
+ let foundOptional = false;
36
+ for (const pos of positionals) {
37
+ if (!pos.required) {
38
+ foundOptional = true;
39
+ }
40
+ if (foundOptional && pos.required) {
41
+ throw new Error(`Invalid positional argument configuration: required positional "${pos.name}" cannot follow optional positional(s).`);
42
+ }
43
+ }
44
+
31
45
  // Handle positional arguments
32
46
  let argIndex = 0;
33
- const positionals = command.positional ?? [];
34
47
  const nonOptionArgs: string[] = [];
35
48
  while (argIndex < args.length && !args[argIndex].startsWith('-')) {
36
49
  nonOptionArgs.push(args[argIndex]);
37
50
  argIndex++;
38
51
  }
39
- let nonOptionIndex = 0;
40
52
 
53
+ let nonOptionIndex = 0;
41
54
  for (let i = 0; i < positionals.length; i++) {
42
55
  const pos = positionals[i];
43
56
  if (pos.variadic) {
@@ -47,15 +60,22 @@ export function parseArgs(config: Config): Record<string, any> {
47
60
  const usagePositionals = positionals.map(posArg => `<${posArg.name}>`).join(' ');
48
61
  throw new Error(`Missing required positional argument, i.e.: "${command.name} ${usagePositionals}"`);
49
62
  }
50
- result[pos.name] = values;
63
+ result[pos.name] = !pos.required && values.length === 0 && pos.default !== undefined ? pos.default : values;
51
64
  nonOptionIndex += values.length;
52
65
  } else {
53
- const value = nonOptionArgs[nonOptionIndex++];
54
- if (!value) {
66
+ const value = nonOptionArgs[nonOptionIndex];
67
+ // Check if there are enough args left for required positionals
68
+ const requiredLeft = positionals.slice(i).filter(p => p.required).length;
69
+ const argsLeft = nonOptionArgs.length - nonOptionIndex;
70
+ if (value !== undefined && (argsLeft > requiredLeft - (pos.required ? 1 : 0) || pos.required)) {
71
+ result[pos.name] = value;
72
+ nonOptionIndex++;
73
+ } else if (!pos.required && pos.default !== undefined) {
74
+ result[pos.name] = pos.default;
75
+ } else if (pos.required) {
55
76
  const usagePositionals = positionals.map(posArg => `<${posArg.name}>`).join(' ');
56
77
  throw new Error(`Missing required positional argument, i.e.: "${command.name} ${usagePositionals}"`);
57
78
  }
58
- result[pos.name] = value;
59
79
  }
60
80
  }
61
81
 
@@ -108,8 +128,7 @@ export function parseArgs(config: Config): Record<string, any> {
108
128
  // Try matching aliases in all forms
109
129
  for (const key of Object.keys(options)) {
110
130
  const opt = options[key];
111
- if (!opt.alias) continue;
112
- if (opt.alias.includes(arg) || opt.alias.includes(kebabToCamel(arg)) || opt.alias.includes(camelToKebab(arg))) {
131
+ if (opt.alias && (opt.alias.includes(arg) || opt.alias.includes(kebabToCamel(arg)) || opt.alias.includes(camelToKebab(arg)))) {
113
132
  option = opt;
114
133
  configKey = key;
115
134
  break;
@@ -123,8 +142,7 @@ export function parseArgs(config: Config): Record<string, any> {
123
142
  const optionKeys = Object.keys(options);
124
143
  for (let j = 0; j < optionKeys.length; j++) {
125
144
  const opt = options[optionKeys[j]];
126
- if (!opt.alias) continue;
127
- if (opt.alias === arg || opt.alias === kebabToCamel(arg) || opt.alias === camelToKebab(arg)) {
145
+ if (opt.alias && (opt.alias === arg || opt.alias === kebabToCamel(arg) || opt.alias === camelToKebab(arg))) {
128
146
  option = opt;
129
147
  configKey = optionKeys[j];
130
148
  break;
@@ -154,19 +172,13 @@ export function parseArgs(config: Config): Record<string, any> {
154
172
  throw new Error(`Unknown option: ${arg}`);
155
173
  }
156
174
 
157
- switch (option.type || 'string') {
175
+ switch (option.type) {
158
176
  case 'boolean':
159
177
  if (result[configKey] !== undefined) {
160
178
  throw new Error('Providing same negated and truthy argument are not allowed');
161
179
  }
162
180
  result[configKey] = !argOrg.startsWith('--no-') && !argOrg.startsWith('-no-');
163
181
  break;
164
- case 'string':
165
- if (args[argIndex + 1] === undefined || args[argIndex + 1].startsWith('-')) {
166
- throw new Error(`Missing value for option: ${configKey}`);
167
- }
168
- result[configKey] = args[++argIndex];
169
- break;
170
182
  case 'number':
171
183
  if (args[argIndex + 1] === undefined || args[argIndex + 1].startsWith('-')) {
172
184
  throw new Error(`Missing value for option: ${configKey}`);
@@ -182,6 +194,13 @@ export function parseArgs(config: Config): Record<string, any> {
182
194
  result[configKey].push(arrayValue);
183
195
  break;
184
196
  }
197
+ case 'string':
198
+ default:
199
+ if (args[argIndex + 1] === undefined || args[argIndex + 1].startsWith('-')) {
200
+ throw new Error(`Missing value for option: ${configKey}`);
201
+ }
202
+ result[configKey] = args[++argIndex];
203
+ break;
185
204
  }
186
205
  } else {
187
206
  throw new Error(`Unknown argument: ${arg}`);
@@ -189,8 +208,12 @@ export function parseArgs(config: Config): Record<string, any> {
189
208
  argIndex++;
190
209
  }
191
210
 
192
- // After all parsing, check for required options
211
+ // After all parsing, assign any `default` CLI options when undefined
212
+ // and check for any missing `required` CLI options
193
213
  Object.entries(options).forEach(([key, opt]) => {
214
+ if (result[key] === undefined && opt.default !== undefined) {
215
+ result[key] = opt.default;
216
+ }
194
217
  if (opt.required && result[key] === undefined) {
195
218
  const aliasStr = opt.alias ? `-${opt.alias}, ` : '';
196
219
  throw new Error(`Missing required option: ${aliasStr}--${key}`);
@@ -200,8 +223,9 @@ export function parseArgs(config: Config): Record<string, any> {
200
223
  return result;
201
224
  }
202
225
 
226
+ /** print CLI help documentation to the screen */
203
227
  function printHelp(config: Config) {
204
- const { command, options } = config;
228
+ const { command, options, version } = config;
205
229
 
206
230
  // Build usage string for positionals
207
231
  const usagePositionals = (command.positional ?? [])
@@ -219,6 +243,8 @@ function printHelp(config: Config) {
219
243
  command.positional?.forEach(arg => {
220
244
  console.log(` ${arg.name.padEnd(20)}${arg.description.slice(0, 65).padEnd(65)}[${arg.type || 'string'}]`);
221
245
  });
246
+
247
+ // Build usage string for options
222
248
  console.log('\nOptions:');
223
249
  Object.keys(options).forEach(key => {
224
250
  const option = options[key];
@@ -228,8 +254,12 @@ function printHelp(config: Config) {
228
254
  ` ${aliasStr.padEnd(4)}--${key.padEnd(14)}${(option.description || '').slice(0, 65).padEnd(65)}[${option.type || 'string'}]${requiredStr}`,
229
255
  );
230
256
  });
257
+
258
+ // Print default options (help and version)
231
259
  console.log('\nDefault options:');
232
260
  console.log(`${padString(' -h, --help', 21)} ${padString('Show help', 64)} [boolean]`);
233
- console.log(`${padString(' -v, --version', 21)} ${padString('Show version number', 64)} [boolean]`);
261
+ if (version) {
262
+ console.log(`${padString(' -v, --version', 21)} ${padString('Show version number', 64)} [boolean]`);
263
+ }
234
264
  console.log('\n');
235
265
  }
package/src/interfaces.ts CHANGED
@@ -5,30 +5,36 @@ export interface ArgumentOptions {
5
5
  description: string;
6
6
  /** defaults to undefined, provide shorter aliases as command options */
7
7
  alias?: string | string[];
8
+ /** default value for the option if not provided */
9
+ default?: any;
8
10
  /** defaults to false, is the option required? */
9
11
  required?: boolean;
10
12
  }
11
13
 
14
+ export interface PositionalArgument {
15
+ /** positional argument name (it will be displayed in the help docs) */
16
+ name: string;
17
+ /** positional argument description */
18
+ description: string;
19
+ /** postional argument type */
20
+ type?: 'string' | 'boolean' | 'number' | 'array';
21
+ /** defaults to false, allows multiple values for this positional argument */
22
+ variadic?: boolean;
23
+ /** default value for the option if not provided */
24
+ default?: any;
25
+ /** defaults to false, is the positional argument required? */
26
+ required?: boolean;
27
+ }
28
+
12
29
  export interface CommandOptions {
13
30
  /** CLI command name, used in the help docs */
14
31
  name: string;
15
32
  description: string;
16
- positional?: {
17
- /** positional argument name (it will be displayed in the help docs) */
18
- name: string;
19
- /** positional argument description */
20
- description: string;
21
- /** postional argument type */
22
- type?: 'string';
23
- /** defaults to false, allows multiple values for this positional argument */
24
- variadic?: boolean;
25
- /** defaults to false, is the positional argument required? */
26
- required?: boolean;
27
- }[];
33
+ positional?: PositionalArgument[];
28
34
  }
29
35
 
30
36
  export interface Config {
31
37
  command: CommandOptions;
32
38
  options: Record<string, ArgumentOptions>;
33
- version: string;
39
+ version?: string;
34
40
  }