argue-cli 2.1.0 → 3.1.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
@@ -1,11 +1,15 @@
1
1
  # argue-cli
2
2
 
3
+ [![ESM-only package][package]][package-url]
3
4
  [![NPM version][npm]][npm-url]
4
5
  [![Node version][node]][node-url]
5
6
  [![Dependencies status][deps]][deps-url]
7
+ [![Install size][size]][size-url]
6
8
  [![Build status][build]][build-url]
7
9
  [![Coverage status][coverage]][coverage-url]
8
- [![Bundle size][size]][size-url]
10
+
11
+ [package]: https://img.shields.io/badge/package-ESM--only-ffe536.svg
12
+ [package-url]: https://nodejs.org/api/esm.html
9
13
 
10
14
  [npm]: https://img.shields.io/npm/v/argue-cli.svg
11
15
  [npm-url]: https://www.npmjs.com/package/argue-cli
@@ -14,17 +18,17 @@
14
18
  [node-url]: https://nodejs.org
15
19
 
16
20
  [deps]: https://img.shields.io/librariesio/release/npm/argue-cli
17
- [deps-url]: https://libraries.io/npm/argue-cli/tree
21
+ [deps-url]: https://libraries.io/npm/argue-cli
22
+
23
+ [size]: https://packagephobia.com/badge?p=argue-cli
24
+ [size-url]: https://packagephobia.com/result?p=argue-cli
18
25
 
19
- [build]: https://img.shields.io/github/workflow/status/TrigenSoftware/Argue/CI.svg
26
+ [build]: https://img.shields.io/github/actions/workflow/status/TrigenSoftware/Argue/tests.yml?branch=master
20
27
  [build-url]: https://github.com/TrigenSoftware/Argue/actions
21
28
 
22
29
  [coverage]: https://img.shields.io/codecov/c/github/TrigenSoftware/Argue.svg
23
30
  [coverage-url]: https://app.codecov.io/gh/TrigenSoftware/Argue
24
31
 
25
- [size]: https://img.shields.io/bundlephobia/minzip/argue-cli
26
- [size-url]: https://bundlephobia.com/package/argue-cli
27
-
28
32
  A thin and strongly typed CLI arguments parser for Node.js.
29
33
 
30
34
  ## Usage
@@ -32,10 +36,10 @@ A thin and strongly typed CLI arguments parser for Node.js.
32
36
  1. Install
33
37
 
34
38
  ```bash
35
- # yarn
36
- yarn add argue-cli
37
39
  # pnpm
38
40
  pnpm add argue-cli
41
+ # yarn
42
+ yarn add argue-cli
39
43
  # npm
40
44
  npm i argue-cli
41
45
  ```
@@ -80,89 +84,155 @@ end()
80
84
 
81
85
  ## API
82
86
 
83
- <table>
84
- <thead>
85
- <tr>
86
- <th>Method</th>
87
- <th>Description</th>
88
- </tr>
89
- </thead>
90
- <tbody>
91
- <tr>
92
- <td>
87
+ Argue reads arguments sequentially from an internal state, which is initialized with `process.argv`. Every call consumes the arguments it reads, so you describe your CLI step by step: expect a command, read its options, read positional arguments, and finally assert the end.
88
+
89
+ > [!TIP]
90
+ > The internal state can be controlled manually with `setArgs(...args)` and `resetArgs()` — handy in tests.
91
+
92
+ ### read
93
93
 
94
94
  ```ts
95
95
  function read(): string
96
96
  ```
97
97
 
98
- </td>
99
- <td>
100
- Read next argument. Throws error if no next argument.
101
- </td>
102
- </tr>
103
- <tr>
104
- <td>
98
+ Reads the next argument and returns it. Throws an error if there are no arguments left.
99
+
100
+ ```ts
101
+ // my-cli sort-imports
102
+ const fileName = read() // 'sort-imports'
103
+ ```
104
+
105
+ ### rest
106
+
107
+ ```ts
108
+ function rest(): string[]
109
+ ```
110
+
111
+ Reads all remaining arguments and returns them. Returns an empty array if there are none — unlike [`read`](#read), it never throws.
112
+
113
+ ```ts
114
+ // my-cli format a.js b.js c.js
115
+ expect('format')
116
+
117
+ const files = rest() // ['a.js', 'b.js', 'c.js']
118
+
119
+ end() // always passes after rest()
120
+ ```
121
+
122
+ ### end
105
123
 
106
124
  ```ts
107
125
  function end(): void
108
126
  ```
109
127
 
110
- </td>
111
- <td>
112
- Expectation of the end. Throws an error if there are more arguments left.
113
- </td>
114
- </tr>
115
- <tr>
116
- <td>
128
+ Asserts that all arguments were consumed. Throws an error if there are any arguments left — useful to catch typos and unexpected input.
129
+
130
+ ```ts
131
+ // my-cli install --sav
132
+ expect('install')
133
+ readOptions(
134
+ option(alias('save', 'S'), Boolean)
135
+ )
136
+ end() // throws: Unexpected argument "--sav"
137
+ ```
138
+
139
+ ### expect
117
140
 
118
141
  ```ts
119
142
  function expect(...argRefs: ArgRef[]): string
120
143
  ```
121
144
 
122
- </td>
123
- <td>
124
- Expect one of the given arguments.
125
- </td>
126
- </tr>
127
- <tr>
128
- <td>
145
+ Expects the next argument to be one of the given ones and returns the matched name. If an [alias](#alias) matches, the main name is returned. Throws an error on any other input.
146
+
147
+ The return type is inferred as a union of the given names:
148
+
149
+ ```ts
150
+ // my-cli i
151
+ const command = expect(alias('install', 'i'), 'remove')
152
+ // typeof command: 'install' | 'remove'
153
+ // command === 'install'
154
+ ```
155
+
156
+ ### alias
129
157
 
130
158
  ```ts
131
159
  function alias(name: string, ...aliases: string[]): AliasArgRef
132
160
  ```
133
161
 
134
- </td>
135
- <td>
136
- Describe argument with aliases.
137
- </td>
138
- </tr>
139
- <tr>
140
- <td>
162
+ Describes an argument that has alternative names. Use it anywhere an argument name is expected — in [`expect`](#expect) and [`option`](#option).
163
+
164
+ ```ts
165
+ alias('install', 'i')
166
+ alias('saveDev', 'save-dev', 'D')
167
+ ```
168
+
169
+ ### autocase
170
+
171
+ ```ts
172
+ function autocase(argRef: ArgRef): ArgRef
173
+ ```
174
+
175
+ Describes an argument that matches both camelCase and kebab-case forms. The name can be given in either form — the twin form is added as an alias. Aliases longer than one character are autocased too. Use it anywhere an argument name is expected.
176
+
177
+ ```ts
178
+ autocase('firstRelease')
179
+ // --firstRelease and --first-release are both accepted
180
+
181
+ autocase(alias('save-dev', 'D'))
182
+ // --save-dev, --saveDev and -D
183
+ ```
184
+
185
+ ### option
141
186
 
142
187
  ```ts
143
188
  function option(argRef: ArgRef, type: PrimitiveConstructor): OptionReader
144
189
  ```
145
190
 
146
- </td>
147
- <td>
148
- Describe option with value.
149
- </td>
150
- </tr>
151
- <tr>
152
- <td>
191
+ Describes an option with a value of the given type, to be read by [`readOptions`](#readoptions):
192
+
193
+ - `String` takes the next argument as a value: `--workspace packages/app`
194
+ - `Number` — parses the next argument as a number: `--port 8080`
195
+ - `Boolean` — a flag without a value, `true` when present: `--verbose`
196
+ - `Array` — splits the next argument by commas; repeated options are merged: `--plugins eslint,swc --plugins tsc` → `['eslint', 'swc', 'tsc']`
197
+
198
+ ### flag
199
+
200
+ ```ts
201
+ function flag(argRef: ArgRef): OptionReader
202
+ ```
203
+
204
+ Describes a boolean flag with `--no-*` negation support, to be read by [`readOptions`](#readoptions): `--verbose` sets `true`, `--no-verbose` sets `false`. Use `option(argRef, Boolean)` when negation is not wanted.
205
+
206
+ ```ts
207
+ const options = readOptions(
208
+ flag(autocase('firstRelease'))
209
+ )
210
+ // --first-release → { firstRelease: true }
211
+ // --no-first-release, --no-firstRelease → { firstRelease: false }
212
+ ```
213
+
214
+ ### readOptions
153
215
 
154
216
  ```ts
155
217
  function readOptions(...optionReaders: OptionReader[]): OptionResult
156
218
  ```
157
219
 
158
- </td>
159
- <td>
160
- Read options from arguments.
161
- </td>
162
- </tr>
163
- </tbody>
164
- </table>
220
+ Scans the arguments and reads all described options. Both `--option` and `-o` prefixes are accepted, and a value can be passed either as the next argument or inline: `--workspace packages/app` and `--workspace=packages/app` are equivalent. Arguments that don't match any described option are left untouched, so you can continue reading them afterwards.
221
+
222
+ The result is a strongly typed object, where every property is optional — an option simply may not be passed:
223
+
224
+ ```ts
225
+ // my-cli --save-dev --workspace packages/app my-package
226
+ const options = readOptions(
227
+ option(alias('saveDev', 'save-dev', 'D'), Boolean),
228
+ option('workspace', String)
229
+ )
230
+ // typeof options: { saveDev?: boolean, workspace?: string }
231
+ // options: { saveDev: true, workspace: 'packages/app' }
232
+
233
+ const packageName = read() // 'my-package'
234
+ ```
165
235
 
166
236
  ## TypeScript
167
237
 
168
- In [API section](#API) types are described in a simplified way. Detailed example of the types you can see [here](test/argue.test-d.ts).
238
+ In the [API section](#api) types are described in a simplified way. A detailed example of the inferred types you can see in [type tests](src/types.spec.ts).
package/dist/args.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AliasArgRef, ArgRef, PrimitiveConstructor, OptionsReaderState, OptionsReaderRead, OptionResult } from './types.js';
1
+ import type { AliasArgRef, ArgRef, PrimitiveConstructor, OptionsReaderState, OptionsReaderRead, OptionResult } from './types.js';
2
2
  /**
3
3
  * Describe argument with aliases.
4
4
  * @param name - Main name.
@@ -7,6 +7,13 @@ import { AliasArgRef, ArgRef, PrimitiveConstructor, OptionsReaderState, OptionsR
7
7
  * @returns Description of argument with aliases..
8
8
  */
9
9
  export declare function alias<T extends string>(name: T, alias: string, ...restAliases: string[]): AliasArgRef<T>;
10
+ /**
11
+ * Describe argument that matches both camelCase and kebab-case forms.
12
+ * Name and every alias longer than one character get the twin form as an alias.
13
+ * @param argRef - Argument name in either form.
14
+ * @returns Description of argument with the twin forms as aliases.
15
+ */
16
+ export declare function autocase<T extends string>(argRef: ArgRef<T>): ArgRef<T>;
10
17
  /**
11
18
  * Describe option with value.
12
19
  * @param argRef - Option name.
@@ -14,4 +21,10 @@ export declare function alias<T extends string>(name: T, alias: string, ...restA
14
21
  * @returns Option reader.
15
22
  */
16
23
  export declare function option<T extends string, K extends PrimitiveConstructor>(argRef: ArgRef<T>, type: K): (option: string, read: OptionsReaderRead, options: OptionsReaderState) => OptionResult<T, K> | null;
24
+ /**
25
+ * Describe boolean flag with `--no-*` negation support.
26
+ * @param argRef - Flag name.
27
+ * @returns Option reader.
28
+ */
29
+ export declare function flag<T extends string>(argRef: ArgRef<T>): (option: string) => OptionResult<T, BooleanConstructor> | null;
17
30
  //# sourceMappingURL=args.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,MAAM,EACN,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAA;AAGnB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAKxG;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,oBAAoB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,YA8B/E,MAAM,QAAQ,iBAAiB,WAAW,kBAAkB,+BA6B/E"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAA;AAGnB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAKxG;AAUD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAuBvE;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,oBAAoB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,YA8B/E,MAAM,QAAQ,iBAAiB,WAAW,kBAAkB,+BA6B/E;AAID;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,YACtC,MAAM,gDAiBvB"}
package/dist/core.d.ts CHANGED
@@ -1,10 +1,15 @@
1
- import { ArgRef } from './types.js';
1
+ import type { ArgRef } from './types.js';
2
2
  /**
3
3
  * Read next argument.
4
4
  * Throws error if no next argument.
5
5
  * @returns Next argument.
6
6
  */
7
7
  export declare function read(): string;
8
+ /**
9
+ * Read all remaining arguments.
10
+ * @returns Remaining arguments, empty array if none.
11
+ */
12
+ export declare function rest(): string[];
8
13
  /**
9
14
  * Expectation of the end.
10
15
  * Throws an error if there are more arguments left.
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGnC;;;;GAIG;AACH,wBAAgB,IAAI,WAQnB;AAED;;;GAGG;AACH,wBAAgB,GAAG,SAIlB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KASpE"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAIxC;;;;GAIG;AACH,wBAAgB,IAAI,WAQnB;AAED;;;GAGG;AACH,wBAAgB,IAAI,aAEnB;AAED;;;GAGG;AACH,wBAAgB,GAAG,SAIlB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KASpE"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './types.js';
1
+ export type * from './types.js';
2
2
  export * from './argv.js';
3
3
  export * from './core.js';
4
4
  export * from './args.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA"}
package/dist/index.js CHANGED
@@ -1,209 +1,245 @@
1
+ //#region src/argv.ts
1
2
  const ARGV_START_INDEX = 2;
2
3
  /**
3
- * Internal state of arguments.
4
- */ const argv = process.argv.slice(ARGV_START_INDEX);
4
+ * Internal state of arguments.
5
+ */
6
+ const argv = process.argv.slice(ARGV_START_INDEX);
5
7
  /**
6
- * Reset arguments state.
7
- */ function resetArgs() {
8
- argv.splice(0, argv.length);
9
- argv.push(...process.argv.slice(ARGV_START_INDEX));
8
+ * Reset arguments state.
9
+ */
10
+ function resetArgs() {
11
+ argv.splice(0, argv.length);
12
+ argv.push(...process.argv.slice(ARGV_START_INDEX));
10
13
  }
11
14
  /**
12
- * Set arguments state.
13
- * @param args
14
- */ function setArgs(...args) {
15
- argv.splice(0, argv.length);
16
- argv.push(...args);
15
+ * Set arguments state.
16
+ * @param args
17
+ */
18
+ function setArgs(...args) {
19
+ argv.splice(0, argv.length);
20
+ argv.push(...args);
17
21
  }
18
-
22
+ //#endregion
23
+ //#region src/utils.ts
19
24
  /**
20
- * Match reference with argument.
21
- * @param argRef
22
- * @param arg
23
- * @returns Full name or null.
24
- */ function matchArgName(argRef, arg) {
25
- if (typeof argRef === "string") {
26
- return argRef === arg ? argRef : null;
27
- }
28
- if (argRef.name === arg) {
29
- return argRef.name;
30
- }
31
- return argRef.aliases.includes(arg) ? argRef.name : null;
25
+ * Match reference with argument.
26
+ * @param argRef
27
+ * @param arg
28
+ * @returns Full name or null.
29
+ */
30
+ function matchArgName(argRef, arg) {
31
+ if (typeof argRef === "string") return argRef === arg ? argRef : null;
32
+ if (argRef.name === arg) return argRef.name;
33
+ return argRef.aliases.includes(arg) ? argRef.name : null;
32
34
  }
33
35
  /**
34
- * Find full argument name in references.
35
- * @param argRefs
36
- * @param arg
37
- * @returns Found argument's full name or null.
38
- */ function findArgName(argRefs, arg) {
39
- let argRef;
40
- let argName;
41
- for (argRef of argRefs){
42
- argName = matchArgName(argRef, arg);
43
- if (argName) {
44
- return argName;
45
- }
46
- }
47
- return null;
36
+ * Find full argument name in references.
37
+ * @param argRefs
38
+ * @param arg
39
+ * @returns Found argument's full name or null.
40
+ */
41
+ function findArgName(argRefs, arg) {
42
+ let argRef;
43
+ let argName;
44
+ for (argRef of argRefs) {
45
+ argName = matchArgName(argRef, arg);
46
+ if (argName) return argName;
47
+ }
48
+ return null;
48
49
  }
49
-
50
+ //#endregion
51
+ //#region src/core.ts
50
52
  /**
51
- * Read next argument.
52
- * Throws error if no next argument.
53
- * @returns Next argument.
54
- */ function read() {
55
- const value = argv.shift();
56
- if (!value) {
57
- throw new Error("Unexpected end of arguments");
58
- }
59
- return value;
53
+ * Read next argument.
54
+ * Throws error if no next argument.
55
+ * @returns Next argument.
56
+ */
57
+ function read() {
58
+ const value = argv.shift();
59
+ if (!value) throw new Error("Unexpected end of arguments");
60
+ return value;
60
61
  }
61
62
  /**
62
- * Expectation of the end.
63
- * Throws an error if there are more arguments left.
64
- */ function end() {
65
- if (argv.length) {
66
- throw new Error(`Unexpected argument "${argv[0]}"`);
67
- }
63
+ * Read all remaining arguments.
64
+ * @returns Remaining arguments, empty array if none.
65
+ */
66
+ function rest() {
67
+ return argv.splice(0, argv.length);
68
68
  }
69
69
  /**
70
- * Expect one of the given arguments.
71
- * @param argRefs
72
- * @returns Expected full argument name.
73
- */ function expect(...argRefs) {
74
- const arg = read();
75
- const argName = findArgName(argRefs, arg);
76
- if (!argName) {
77
- throw new Error(`Unexpected argument "${arg}"`);
78
- }
79
- return argName;
70
+ * Expectation of the end.
71
+ * Throws an error if there are more arguments left.
72
+ */
73
+ function end() {
74
+ if (argv.length) throw new Error(`Unexpected argument "${argv[0]}"`);
80
75
  }
81
-
82
76
  /**
83
- * Describe argument with aliases.
84
- * @param name - Main name.
85
- * @param alias - Alias name.
86
- * @param restAliases - Rest aliases.
87
- * @returns Description of argument with aliases..
88
- */ function alias(name, alias, ...restAliases) {
89
- return {
90
- name,
91
- aliases: [
92
- alias,
93
- ...restAliases
94
- ]
95
- };
77
+ * Expect one of the given arguments.
78
+ * @param argRefs
79
+ * @returns Expected full argument name.
80
+ */
81
+ function expect(...argRefs) {
82
+ const arg = read();
83
+ const argName = findArgName(argRefs, arg);
84
+ if (!argName) throw new Error(`Unexpected argument "${arg}"`);
85
+ return argName;
96
86
  }
87
+ //#endregion
88
+ //#region src/args.ts
97
89
  /**
98
- * Describe option with value.
99
- * @param argRef - Option name.
100
- * @param type - Value type.
101
- * @returns Option reader.
102
- */ function option(argRef, type) {
103
- if (type === String) {
104
- return (option, read)=>{
105
- const argName = matchArgName(argRef, option);
106
- if (argName) {
107
- return {
108
- [argName]: read()
109
- };
110
- }
111
- return null;
112
- };
113
- }
114
- if (type === Number) {
115
- return (option, read)=>{
116
- const argName = matchArgName(argRef, option);
117
- if (argName) {
118
- return {
119
- [argName]: parseFloat(read())
120
- };
121
- }
122
- return null;
123
- };
124
- }
125
- if (type === Array) {
126
- return (option, read, options)=>{
127
- const argName = matchArgName(argRef, option);
128
- if (argName) {
129
- const prevValues = options[argName];
130
- const values = read().split(",");
131
- return {
132
- [argName]: Array.isArray(prevValues) ? prevValues.concat(values) : values
133
- };
134
- }
135
- return null;
136
- };
137
- }
138
- return (option)=>{
139
- const argName = matchArgName(argRef, option);
140
- if (argName) {
141
- return {
142
- [argName]: true
143
- };
144
- }
145
- return null;
146
- };
90
+ * Describe argument with aliases.
91
+ * @param name - Main name.
92
+ * @param alias - Alias name.
93
+ * @param restAliases - Rest aliases.
94
+ * @returns Description of argument with aliases..
95
+ */
96
+ function alias(name, alias, ...restAliases) {
97
+ return {
98
+ name,
99
+ aliases: [alias, ...restAliases]
100
+ };
147
101
  }
148
-
102
+ function caseTwin(name) {
103
+ return name.length > 1 ? name.includes("-") ? name.replace(/-+(.)/g, (_, char) => char.toUpperCase()) : name.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`) : name;
104
+ }
105
+ /**
106
+ * Describe argument that matches both camelCase and kebab-case forms.
107
+ * Name and every alias longer than one character get the twin form as an alias.
108
+ * @param argRef - Argument name in either form.
109
+ * @returns Description of argument with the twin forms as aliases.
110
+ */
111
+ function autocase(argRef) {
112
+ let name;
113
+ let aliases;
114
+ if (typeof argRef === "string") {
115
+ name = argRef;
116
+ aliases = /* @__PURE__ */ new Set();
117
+ } else {
118
+ name = argRef.name;
119
+ aliases = new Set(argRef.aliases.concat(argRef.aliases.map(caseTwin)));
120
+ }
121
+ aliases.add(caseTwin(name));
122
+ aliases.delete(name);
123
+ if (!aliases.size) return argRef;
124
+ return {
125
+ name,
126
+ aliases: [...aliases]
127
+ };
128
+ }
129
+ /**
130
+ * Describe option with value.
131
+ * @param argRef - Option name.
132
+ * @param type - Value type.
133
+ * @returns Option reader.
134
+ */
135
+ function option(argRef, type) {
136
+ if (type === String) return (option, read) => {
137
+ const argName = matchArgName(argRef, option);
138
+ if (argName) return { [argName]: read() };
139
+ return null;
140
+ };
141
+ if (type === Number) return (option, read) => {
142
+ const argName = matchArgName(argRef, option);
143
+ if (argName) return { [argName]: parseFloat(read()) };
144
+ return null;
145
+ };
146
+ if (type === Array) return (option, read, options) => {
147
+ const argName = matchArgName(argRef, option);
148
+ if (argName) {
149
+ const prevValues = options[argName];
150
+ const values = read().split(",");
151
+ return { [argName]: Array.isArray(prevValues) ? prevValues.concat(values) : values };
152
+ }
153
+ return null;
154
+ };
155
+ return (option) => {
156
+ const argName = matchArgName(argRef, option);
157
+ if (argName) return { [argName]: true };
158
+ return null;
159
+ };
160
+ }
161
+ const NEGATION_PREFIX = "no-";
162
+ /**
163
+ * Describe boolean flag with `--no-*` negation support.
164
+ * @param argRef - Flag name.
165
+ * @returns Option reader.
166
+ */
167
+ function flag(argRef) {
168
+ return (option) => {
169
+ let value = true;
170
+ let argName = matchArgName(argRef, option);
171
+ if (!argName && option.startsWith(NEGATION_PREFIX)) {
172
+ value = false;
173
+ argName = matchArgName(argRef, option.slice(3));
174
+ }
175
+ if (argName) return { [argName]: value };
176
+ return null;
177
+ };
178
+ }
179
+ //#endregion
180
+ //#region src/options.ts
149
181
  function isOption(arg) {
150
- return /^--?[^-].*/.test(arg);
182
+ return /^--?[^-].*/.test(arg);
151
183
  }
152
184
  function removePrefix(arg) {
153
- return arg.replace(/^--?/, "");
185
+ return arg.replace(/^--?/, "");
186
+ }
187
+ function splitOption(arg) {
188
+ const eqIndex = arg.indexOf("=");
189
+ return eqIndex === -1 ? [arg] : [arg.slice(0, eqIndex), arg.slice(eqIndex + 1)];
154
190
  }
155
191
  function createOptionReader(optionReaders) {
156
- const optionReader = optionReaders.reduceRight((readNextOption, readOption)=>{
157
- if (!readNextOption) {
158
- return readOption;
159
- }
160
- return (option, read, options)=>readOption(option, read, options) ?? readNextOption(option, read, options);
161
- }, null);
162
- return optionReader;
192
+ return optionReaders.reduceRight((readNextOption, readOption) => {
193
+ if (!readNextOption) return readOption;
194
+ return (option, read, options) => readOption(option, read, options) ?? readNextOption(option, read, options);
195
+ }, null);
163
196
  }
164
197
  /**
165
- * Read options from arguments.
166
- * @param optionReaders
167
- * @returns Options with values.
168
- */ function readOptions(...optionReaders) {
169
- if (!argv.length) {
170
- return {};
171
- }
172
- const readOption = createOptionReader(optionReaders);
173
- if (!readOption) {
174
- return {};
175
- }
176
- const options = {};
177
- let i = 0;
178
- let arg = argv[i];
179
- let optionResult;
180
- const next = ()=>{
181
- arg = argv[++i];
182
- };
183
- const remove = ()=>{
184
- argv.splice(i--, 1);
185
- };
186
- const read = ()=>{
187
- next();
188
- remove();
189
- if (!arg) {
190
- throw new Error("Unexpected end of arguments");
191
- }
192
- return arg;
193
- };
194
- // eslint-disable-next-line no-unmodified-loop-condition
195
- while(arg){
196
- if (isOption(arg)) {
197
- optionResult = readOption(removePrefix(arg), read, options);
198
- if (optionResult) {
199
- remove();
200
- Object.assign(options, optionResult);
201
- }
202
- }
203
- next();
204
- }
205
- return options;
198
+ * Read options from arguments.
199
+ * @param optionReaders
200
+ * @returns Options with values.
201
+ */
202
+ function readOptions(...optionReaders) {
203
+ if (!argv.length) return {};
204
+ const readOption = createOptionReader(optionReaders);
205
+ if (!readOption) return {};
206
+ const options = {};
207
+ let i = 0;
208
+ let arg = argv[i];
209
+ let optionResult;
210
+ let optionEqValue;
211
+ const next = () => {
212
+ arg = argv[++i];
213
+ };
214
+ const remove = () => {
215
+ if (optionEqValue !== void 0) throw new Error(`Unexpected value for "${arg}"`);
216
+ argv.splice(i--, 1);
217
+ };
218
+ const read = () => {
219
+ if (optionEqValue !== void 0) {
220
+ const value = optionEqValue;
221
+ optionEqValue = void 0;
222
+ return value;
223
+ }
224
+ next();
225
+ remove();
226
+ if (!arg) throw new Error("Unexpected end of arguments");
227
+ return arg;
228
+ };
229
+ while (arg) {
230
+ if (isOption(arg)) {
231
+ [arg, optionEqValue] = splitOption(arg);
232
+ optionResult = readOption(removePrefix(arg), read, options);
233
+ if (optionResult) {
234
+ remove();
235
+ Object.assign(options, optionResult);
236
+ }
237
+ }
238
+ next();
239
+ }
240
+ return options;
206
241
  }
242
+ //#endregion
243
+ export { alias, argv, autocase, end, expect, flag, option, read, readOptions, resetArgs, rest, setArgs };
207
244
 
208
- export { alias, argv, end, expect, option, read, readOptions, resetArgs, setArgs };
209
- //# sourceMappingURL=index.js.map
245
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/argv.ts","../src/utils.ts","../src/core.ts","../src/args.ts","../src/options.ts"],"sourcesContent":["\nconst ARGV_START_INDEX = 2\n\n/**\n * Internal state of arguments.\n */\nexport const argv = process.argv.slice(ARGV_START_INDEX)\n\n/**\n * Reset arguments state.\n */\nexport function resetArgs() {\n argv.splice(0, argv.length)\n argv.push(...process.argv.slice(ARGV_START_INDEX))\n}\n\n/**\n * Set arguments state.\n * @param args\n */\nexport function setArgs(...args: string[]) {\n argv.splice(0, argv.length)\n argv.push(...args)\n}\n","\nimport { ArgRef } from './types.js'\n\ntype FlatMerge<T> = T extends infer U ? { [K in keyof U]: U[K] } : never\n\nexport type Merge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R]\n ? FlatMerge<NonNullable<L> & Merge<R>>\n : unknown\n\nexport type UnionMerge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R]\n ? L | Merge<R>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : any\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyFunction = (...args: any[]) => any\n\nexport type ReturnTypes<T extends readonly [...AnyFunction[]]> = T extends [infer L, ...infer R]\n ? L extends AnyFunction\n ? R extends AnyFunction[]\n ? [ReturnType<L>, ...ReturnTypes<R>]\n : []\n : []\n : []\n\n/**\n * Match reference with argument.\n * @param argRef\n * @param arg\n * @returns Full name or null.\n */\nexport function matchArgName<T extends string>(argRef: ArgRef<T>, arg: string) {\n if (typeof argRef === 'string') {\n return argRef === arg\n ? argRef\n : null\n }\n\n if (argRef.name === arg) {\n return argRef.name\n }\n\n return argRef.aliases.includes(arg)\n ? argRef.name\n : null\n}\n\n/**\n * Find full argument name in references.\n * @param argRefs\n * @param arg\n * @returns Found argument's full name or null.\n */\nexport function findArgName<T extends string>(argRefs: [...ArgRef<T>[]], arg: string) {\n let argRef: ArgRef<T>\n let argName: T | null\n\n for (argRef of argRefs) {\n argName = matchArgName(argRef, arg)\n\n if (argName) {\n return argName\n }\n }\n\n return null\n}\n","import { argv } from './argv.js'\nimport { ArgRef } from './types.js'\nimport { findArgName } from './utils.js'\n\n/**\n * Read next argument.\n * Throws error if no next argument.\n * @returns Next argument.\n */\nexport function read() {\n const value = argv.shift()\n\n if (!value) {\n throw new Error('Unexpected end of arguments')\n }\n\n return value\n}\n\n/**\n * Expectation of the end.\n * Throws an error if there are more arguments left.\n */\nexport function end() {\n if (argv.length) {\n throw new Error(`Unexpected argument \"${argv[0]}\"`)\n }\n}\n\n/**\n * Expect one of the given arguments.\n * @param argRefs\n * @returns Expected full argument name.\n */\nexport function expect<T extends string>(...argRefs: [...ArgRef<T>[]]) {\n const arg = read()\n const argName = findArgName(argRefs, arg)\n\n if (!argName) {\n throw new Error(`Unexpected argument \"${arg}\"`)\n }\n\n return argName\n}\n","import {\n AliasArgRef,\n ArgRef,\n PrimitiveConstructor,\n OptionsReaderState,\n OptionsReaderRead,\n OptionResult\n} from './types.js'\nimport { matchArgName } from './utils.js'\n\n/**\n * Describe argument with aliases.\n * @param name - Main name.\n * @param alias - Alias name.\n * @param restAliases - Rest aliases.\n * @returns Description of argument with aliases..\n */\nexport function alias<T extends string>(name: T, alias: string, ...restAliases: string[]): AliasArgRef<T> {\n return {\n name,\n aliases: [alias, ...restAliases]\n }\n}\n\n/**\n * Describe option with value.\n * @param argRef - Option name.\n * @param type - Value type.\n * @returns Option reader.\n */\nexport function option<T extends string, K extends PrimitiveConstructor>(argRef: ArgRef<T>, type: K) {\n if (type === String) {\n return (option: string, read: OptionsReaderRead) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: read()\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n if (type === Number) {\n return (option: string, read: OptionsReaderRead) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: parseFloat(read())\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n if (type === Array) {\n return (option: string, read: OptionsReaderRead, options: OptionsReaderState) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n const prevValues = options[argName]\n const values = read().split(',')\n\n return {\n [argName]: Array.isArray(prevValues)\n ? prevValues.concat(values)\n : values\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n return (option: string) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: true\n } as OptionResult<T, K>\n }\n\n return null\n }\n}\n","import { argv } from './argv.js'\nimport { OptionReader, OptionResult } from './types.js'\nimport { Merge, ReturnTypes, UnionMerge } from './utils.js'\n\nfunction isOption(arg: string) {\n return /^--?[^-].*/.test(arg)\n}\n\nfunction removePrefix(arg: string) {\n return arg.replace(/^--?/, '')\n}\n\nfunction createOptionReader<T extends OptionReader[]>(optionReaders: [...T]) {\n const optionReader = optionReaders.reduceRight<OptionReader | null>(\n (readNextOption, readOption) => {\n if (!readNextOption) {\n return readOption\n }\n\n return (option, read, options) => readOption(option, read, options) ?? readNextOption(option, read, options)\n },\n null\n )\n\n return optionReader as OptionReader<UnionMerge<ReturnTypes<T>>> | null\n}\n\n/**\n * Read options from arguments.\n * @param optionReaders\n * @returns Options with values.\n */\nexport function readOptions<T extends OptionReader[]>(...optionReaders: [...T]): Partial<Merge<ReturnTypes<T>>> {\n if (!argv.length) {\n return {}\n }\n\n const readOption = createOptionReader(optionReaders)\n\n if (!readOption) {\n return {}\n }\n\n const options = {}\n let i = 0\n let arg = argv[i]\n let optionResult: OptionResult | null\n const next = () => {\n arg = argv[++i]\n }\n const remove = () => {\n argv.splice(i--, 1)\n }\n const read = () => {\n next()\n remove()\n\n if (!arg) {\n throw new Error('Unexpected end of arguments')\n }\n\n return arg\n }\n\n // eslint-disable-next-line no-unmodified-loop-condition\n while (arg) {\n if (isOption(arg)) {\n optionResult = readOption(removePrefix(arg), read, options)\n\n if (optionResult) {\n remove()\n Object.assign(options, optionResult)\n }\n }\n\n next()\n }\n\n return options\n}\n"],"names":["ARGV_START_INDEX","argv","process","slice","resetArgs","splice","length","push","setArgs","args","matchArgName","argRef","arg","name","aliases","includes","findArgName","argRefs","argName","read","value","shift","Error","end","expect","alias","restAliases","option","type","String","Number","parseFloat","Array","options","prevValues","values","split","isArray","concat","isOption","test","removePrefix","replace","createOptionReader","optionReaders","optionReader","reduceRight","readNextOption","readOption","readOptions","i","optionResult","next","remove","Object","assign"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/argv.ts","../src/utils.ts","../src/core.ts","../src/args.ts","../src/options.ts"],"sourcesContent":["\nconst ARGV_START_INDEX = 2\n\n/**\n * Internal state of arguments.\n */\nexport const argv = process.argv.slice(ARGV_START_INDEX)\n\n/**\n * Reset arguments state.\n */\nexport function resetArgs() {\n argv.splice(0, argv.length)\n argv.push(...process.argv.slice(ARGV_START_INDEX))\n}\n\n/**\n * Set arguments state.\n * @param args\n */\nexport function setArgs(...args: string[]) {\n argv.splice(0, argv.length)\n argv.push(...args)\n}\n","\nimport type { ArgRef } from './types.js'\n\ntype FlatMerge<T> = T extends infer U ? { [K in keyof U]: U[K] } : never\n\nexport type Merge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R]\n ? FlatMerge<NonNullable<L> & Merge<R>>\n : unknown\n\nexport type UnionMerge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R]\n ? L | Merge<R>\n // oxlint-disable-next-line typescript/no-explicit-any\n : any\n\n// oxlint-disable-next-line typescript/no-explicit-any\ntype AnyFunction = (...args: any[]) => any\n\nexport type ReturnTypes<T extends readonly [...AnyFunction[]]> = T extends [infer L, ...infer R]\n ? L extends AnyFunction\n ? R extends AnyFunction[]\n ? [ReturnType<L>, ...ReturnTypes<R>]\n : []\n : []\n : []\n\n/**\n * Match reference with argument.\n * @param argRef\n * @param arg\n * @returns Full name or null.\n */\nexport function matchArgName<T extends string>(argRef: ArgRef<T>, arg: string) {\n if (typeof argRef === 'string') {\n return argRef === arg\n ? argRef\n : null\n }\n\n if (argRef.name === arg) {\n return argRef.name\n }\n\n return argRef.aliases.includes(arg)\n ? argRef.name\n : null\n}\n\n/**\n * Find full argument name in references.\n * @param argRefs\n * @param arg\n * @returns Found argument's full name or null.\n */\nexport function findArgName<T extends string>(argRefs: [...ArgRef<T>[]], arg: string) {\n let argRef: ArgRef<T>\n let argName: T | null\n\n for (argRef of argRefs) {\n argName = matchArgName(argRef, arg)\n\n if (argName) {\n return argName\n }\n }\n\n return null\n}\n","import type { ArgRef } from './types.js'\nimport { argv } from './argv.js'\nimport { findArgName } from './utils.js'\n\n/**\n * Read next argument.\n * Throws error if no next argument.\n * @returns Next argument.\n */\nexport function read() {\n const value = argv.shift()\n\n if (!value) {\n throw new Error('Unexpected end of arguments')\n }\n\n return value\n}\n\n/**\n * Read all remaining arguments.\n * @returns Remaining arguments, empty array if none.\n */\nexport function rest() {\n return argv.splice(0, argv.length)\n}\n\n/**\n * Expectation of the end.\n * Throws an error if there are more arguments left.\n */\nexport function end() {\n if (argv.length) {\n throw new Error(`Unexpected argument \"${argv[0]}\"`)\n }\n}\n\n/**\n * Expect one of the given arguments.\n * @param argRefs\n * @returns Expected full argument name.\n */\nexport function expect<T extends string>(...argRefs: [...ArgRef<T>[]]) {\n const arg = read()\n const argName = findArgName(argRefs, arg)\n\n if (!argName) {\n throw new Error(`Unexpected argument \"${arg}\"`)\n }\n\n return argName\n}\n","import type {\n AliasArgRef,\n ArgRef,\n PrimitiveConstructor,\n OptionsReaderState,\n OptionsReaderRead,\n OptionResult\n} from './types.js'\nimport { matchArgName } from './utils.js'\n\n/**\n * Describe argument with aliases.\n * @param name - Main name.\n * @param alias - Alias name.\n * @param restAliases - Rest aliases.\n * @returns Description of argument with aliases..\n */\nexport function alias<T extends string>(name: T, alias: string, ...restAliases: string[]): AliasArgRef<T> {\n return {\n name,\n aliases: [alias, ...restAliases]\n }\n}\n\nfunction caseTwin(name: string) {\n return name.length > 1\n ? name.includes('-')\n ? name.replace(/-+(.)/g, (_, char: string) => char.toUpperCase())\n : name.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`)\n : name\n}\n\n/**\n * Describe argument that matches both camelCase and kebab-case forms.\n * Name and every alias longer than one character get the twin form as an alias.\n * @param argRef - Argument name in either form.\n * @returns Description of argument with the twin forms as aliases.\n */\nexport function autocase<T extends string>(argRef: ArgRef<T>): ArgRef<T> {\n let name\n let aliases\n\n if (typeof argRef === 'string') {\n name = argRef\n aliases = new Set<string>()\n } else {\n name = argRef.name\n aliases = new Set(argRef.aliases.concat(argRef.aliases.map(caseTwin)))\n }\n\n aliases.add(caseTwin(name))\n aliases.delete(name)\n\n if (!aliases.size) {\n return argRef\n }\n\n return {\n name,\n aliases: [...aliases]\n }\n}\n\n/**\n * Describe option with value.\n * @param argRef - Option name.\n * @param type - Value type.\n * @returns Option reader.\n */\nexport function option<T extends string, K extends PrimitiveConstructor>(argRef: ArgRef<T>, type: K) {\n if (type === String) {\n return (option: string, read: OptionsReaderRead) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: read()\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n if (type === Number) {\n return (option: string, read: OptionsReaderRead) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: parseFloat(read())\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n if (type === Array) {\n return (option: string, read: OptionsReaderRead, options: OptionsReaderState) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n const prevValues = options[argName]\n const values = read().split(',')\n\n return {\n [argName]: Array.isArray(prevValues)\n ? prevValues.concat(values)\n : values\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n return (option: string) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: true\n } as OptionResult<T, K>\n }\n\n return null\n }\n}\n\nconst NEGATION_PREFIX = 'no-'\n\n/**\n * Describe boolean flag with `--no-*` negation support.\n * @param argRef - Flag name.\n * @returns Option reader.\n */\nexport function flag<T extends string>(argRef: ArgRef<T>) {\n return (option: string) => {\n let value = true\n let argName = matchArgName(argRef, option)\n\n if (!argName && option.startsWith(NEGATION_PREFIX)) {\n value = false\n argName = matchArgName(argRef, option.slice(NEGATION_PREFIX.length))\n }\n\n if (argName) {\n return {\n [argName]: value\n } as OptionResult<T, BooleanConstructor>\n }\n\n return null\n }\n}\n","import type {\n OptionReader,\n OptionResult\n} from './types.js'\nimport type {\n Merge,\n ReturnTypes,\n UnionMerge\n} from './utils.js'\nimport { argv } from './argv.js'\n\nfunction isOption(arg: string) {\n return /^--?[^-].*/.test(arg)\n}\n\nfunction removePrefix(arg: string) {\n return arg.replace(/^--?/, '')\n}\n\nfunction splitOption(arg: string): [name: string, value?: string] {\n const eqIndex = arg.indexOf('=')\n\n return eqIndex === -1\n ? [arg]\n : [arg.slice(0, eqIndex), arg.slice(eqIndex + 1)]\n}\n\nfunction createOptionReader<T extends OptionReader[]>(optionReaders: [...T]) {\n const optionReader = optionReaders.reduceRight<OptionReader | null>(\n (readNextOption, readOption) => {\n if (!readNextOption) {\n return readOption\n }\n\n return (option, read, options) => readOption(option, read, options) ?? readNextOption(option, read, options)\n },\n null\n )\n\n return optionReader as OptionReader<UnionMerge<ReturnTypes<T>>> | null\n}\n\n/**\n * Read options from arguments.\n * @param optionReaders\n * @returns Options with values.\n */\nexport function readOptions<T extends OptionReader[]>(...optionReaders: [...T]): Partial<Merge<ReturnTypes<T>>> {\n if (!argv.length) {\n return {}\n }\n\n const readOption = createOptionReader(optionReaders)\n\n if (!readOption) {\n return {}\n }\n\n const options = {}\n let i = 0\n let arg = argv[i]\n let optionResult: OptionResult | null\n let optionEqValue: string | undefined\n const next = () => {\n arg = argv[++i]\n }\n const remove = () => {\n if (optionEqValue !== undefined) {\n throw new Error(`Unexpected value for \"${arg}\"`)\n }\n\n argv.splice(i--, 1)\n }\n const read = () => {\n if (optionEqValue !== undefined) {\n const value = optionEqValue\n\n optionEqValue = undefined\n\n return value\n }\n\n next()\n remove()\n\n if (!arg) {\n throw new Error('Unexpected end of arguments')\n }\n\n return arg\n }\n\n // oxlint-disable-next-line eslint/no-unmodified-loop-condition\n while (arg) {\n if (isOption(arg)) {\n [arg, optionEqValue] = splitOption(arg)\n optionResult = readOption(removePrefix(arg), read, options)\n\n if (optionResult) {\n remove()\n Object.assign(options, optionResult)\n }\n }\n\n next()\n }\n\n return options\n}\n"],"mappings":"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"}
package/dist/options.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { OptionReader } from './types.js';
2
- import { Merge, ReturnTypes } from './utils.js';
1
+ import type { OptionReader } from './types.js';
2
+ import type { Merge, ReturnTypes } from './utils.js';
3
3
  /**
4
4
  * Read options from arguments.
5
5
  * @param optionReaders
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAA;AACvD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAc,MAAM,YAAY,CAAA;AAyB3D;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAAE,EAAE,GAAG,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CA+C9G"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EAEZ,MAAM,YAAY,CAAA;AAkCnB;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAAE,EAAE,GAAG,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CA6D9G"}
package/dist/types.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- export declare type SimpleArgRef<T extends string> = T;
1
+ export type SimpleArgRef<T extends string> = T;
2
2
  export interface AliasArgRef<T extends string> {
3
3
  name: T;
4
4
  aliases: string[];
5
5
  }
6
- export declare type ArgRef<T extends string> = SimpleArgRef<T> | AliasArgRef<T>;
7
- export declare type ArgRefName<T extends ArgRef<string>> = T extends AliasArgRef<string> ? T['name'] : T;
8
- export declare type OptionsReaderState = Record<string, unknown>;
9
- export declare type OptionsReaderRead = () => string;
10
- export declare type PrimitiveConstructor = StringConstructor | NumberConstructor | ArrayConstructor | BooleanConstructor;
11
- export declare type OptionValueType<T extends PrimitiveConstructor> = T extends StringConstructor ? string : T extends NumberConstructor ? number : T extends ArrayConstructor ? string[] : boolean;
12
- export declare type OptionResult<T extends string = string, K extends PrimitiveConstructor = PrimitiveConstructor> = Record<T, OptionValueType<K>>;
13
- export declare type OptionReader<T extends OptionResult = OptionResult> = (option: string, read: OptionsReaderRead, options: OptionsReaderState) => T | null;
6
+ export type ArgRef<T extends string> = SimpleArgRef<T> | AliasArgRef<T>;
7
+ export type ArgRefName<T extends ArgRef<string>> = T extends AliasArgRef<string> ? T['name'] : T;
8
+ export type OptionsReaderState = Record<string, unknown>;
9
+ export type OptionsReaderRead = () => string;
10
+ export type PrimitiveConstructor = StringConstructor | NumberConstructor | ArrayConstructor | BooleanConstructor;
11
+ export type OptionValueType<T extends PrimitiveConstructor> = T extends StringConstructor ? string : T extends NumberConstructor ? number : T extends ArrayConstructor ? string[] : boolean;
12
+ export type OptionResult<T extends string = string, K extends PrimitiveConstructor = PrimitiveConstructor> = Record<T, OptionValueType<K>>;
13
+ export type OptionReader<T extends OptionResult = OptionResult> = (option: string, read: OptionsReaderRead, options: OptionsReaderState) => T | null;
14
14
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oBAAY,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAA;AAE9C,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM;IAC3C,IAAI,EAAE,CAAC,CAAA;IACP,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,oBAAY,MAAM,CAAC,CAAC,SAAS,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;AAEvE,oBAAY,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,IAC7C,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,GACzB,CAAC,CAAC,MAAM,CAAC,GACT,CAAC,CAAA;AAEP,oBAAY,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAExD,oBAAY,iBAAiB,GAAG,MAAM,MAAM,CAAA;AAE5C,oBAAY,oBAAoB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,kBAAkB,CAAA;AAEhH,oBAAY,eAAe,CAAC,CAAC,SAAS,oBAAoB,IACxD,CAAC,SAAS,iBAAiB,GACvB,MAAM,GACN,CAAC,SAAS,iBAAiB,GACzB,MAAM,GACN,CAAC,SAAS,gBAAgB,GACxB,MAAM,EAAE,GACR,OAAO,CAAA;AAEjB,oBAAY,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,oBAAoB,GAAG,oBAAoB,IAAI,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAA;AAE1I,oBAAY,YAAY,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,IAC5D,CACE,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,kBAAkB,KACxB,CAAC,GAAG,IAAI,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAA;AAE9C,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM;IAC3C,IAAI,EAAE,CAAC,CAAA;IACP,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;AAEvE,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,IAC7C,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,GACzB,CAAC,CAAC,MAAM,CAAC,GACT,CAAC,CAAA;AAEP,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAExD,MAAM,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAA;AAE5C,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,kBAAkB,CAAA;AAEhH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,oBAAoB,IACxD,CAAC,SAAS,iBAAiB,GACvB,MAAM,GACN,CAAC,SAAS,iBAAiB,GACzB,MAAM,GACN,CAAC,SAAS,gBAAgB,GACxB,MAAM,EAAE,GACR,OAAO,CAAA;AAEjB,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,oBAAoB,GAAG,oBAAoB,IAAI,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAA;AAE1I,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,IAC5D,CACE,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,kBAAkB,KACxB,CAAC,GAAG,IAAI,CAAA"}
package/dist/utils.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { ArgRef } from './types.js';
2
- declare type FlatMerge<T> = T extends infer U ? {
1
+ import type { ArgRef } from './types.js';
2
+ type FlatMerge<T> = T extends infer U ? {
3
3
  [K in keyof U]: U[K];
4
4
  } : never;
5
- export declare type Merge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R] ? FlatMerge<NonNullable<L> & Merge<R>> : unknown;
6
- export declare type UnionMerge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R] ? L | Merge<R> : any;
7
- declare type AnyFunction = (...args: any[]) => any;
8
- export declare type ReturnTypes<T extends readonly [...AnyFunction[]]> = T extends [infer L, ...infer R] ? L extends AnyFunction ? R extends AnyFunction[] ? [ReturnType<L>, ...ReturnTypes<R>] : [] : [] : [];
5
+ export type Merge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R] ? FlatMerge<NonNullable<L> & Merge<R>> : unknown;
6
+ export type UnionMerge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R] ? L | Merge<R> : any;
7
+ type AnyFunction = (...args: any[]) => any;
8
+ export type ReturnTypes<T extends readonly [...AnyFunction[]]> = T extends [infer L, ...infer R] ? L extends AnyFunction ? R extends AnyFunction[] ? [ReturnType<L>, ...ReturnTypes<R>] : [] : [] : [];
9
9
  /**
10
10
  * Match reference with argument.
11
11
  * @param argRef
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEnC,aAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAA;AAExE,oBAAY,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GAClF,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GACpC,OAAO,CAAA;AAEX,oBAAY,UAAU,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GACvF,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAEZ,GAAG,CAAA;AAGP,aAAK,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;AAE1C,oBAAY,WAAW,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GAC5F,CAAC,SAAS,WAAW,GACnB,CAAC,SAAS,WAAW,EAAE,GACrB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAClC,EAAE,GACJ,EAAE,GACJ,EAAE,CAAA;AAEN;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,YAc5E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,YAanF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAA;AAExE,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GAClF,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GACpC,OAAO,CAAA;AAEX,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GACvF,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAEZ,GAAG,CAAA;AAGP,KAAK,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;AAE1C,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GAC5F,CAAC,SAAS,WAAW,GACnB,CAAC,SAAS,WAAW,EAAE,GACrB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAClC,EAAE,GACJ,EAAE,GACJ,EAAE,CAAA;AAEN;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,YAc5E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,YAanF"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "argue-cli",
3
3
  "type": "module",
4
- "version": "2.1.0",
4
+ "version": "3.1.0",
5
5
  "description": "A thin and strongly typed CLI arguments parser for Node.js.",
6
6
  "author": "dangreen",
7
7
  "license": "MIT",
8
+ "funding": "https://ko-fi.com/dangreen",
8
9
  "repository": {
9
10
  "type": "git",
10
11
  "url": "https://github.com/TrigenSoftware/Argue.git"
@@ -20,19 +21,14 @@
20
21
  "terminal"
21
22
  ],
22
23
  "engines": {
23
- "node": ">=14.0.0"
24
+ "node": ">=22"
24
25
  },
25
26
  "types": "./dist/index.d.ts",
26
27
  "exports": {
27
- "import": "./dist/index.js",
28
- "require": "./dist/index.cjs"
29
- },
30
- "publishConfig": {
31
- "directory": "package"
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
32
30
  },
33
31
  "files": [
34
32
  "dist"
35
- ],
36
- "readme": "",
37
- "scripts": {}
33
+ ]
38
34
  }
package/dist/index.cjs DELETED
@@ -1,221 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- const ARGV_START_INDEX = 2;
6
- /**
7
- * Internal state of arguments.
8
- */ const argv = process.argv.slice(ARGV_START_INDEX);
9
- /**
10
- * Reset arguments state.
11
- */ function resetArgs() {
12
- argv.splice(0, argv.length);
13
- argv.push(...process.argv.slice(ARGV_START_INDEX));
14
- }
15
- /**
16
- * Set arguments state.
17
- * @param args
18
- */ function setArgs(...args) {
19
- argv.splice(0, argv.length);
20
- argv.push(...args);
21
- }
22
-
23
- /**
24
- * Match reference with argument.
25
- * @param argRef
26
- * @param arg
27
- * @returns Full name or null.
28
- */ function matchArgName(argRef, arg) {
29
- if (typeof argRef === "string") {
30
- return argRef === arg ? argRef : null;
31
- }
32
- if (argRef.name === arg) {
33
- return argRef.name;
34
- }
35
- return argRef.aliases.includes(arg) ? argRef.name : null;
36
- }
37
- /**
38
- * Find full argument name in references.
39
- * @param argRefs
40
- * @param arg
41
- * @returns Found argument's full name or null.
42
- */ function findArgName(argRefs, arg) {
43
- let argRef;
44
- let argName;
45
- for (argRef of argRefs){
46
- argName = matchArgName(argRef, arg);
47
- if (argName) {
48
- return argName;
49
- }
50
- }
51
- return null;
52
- }
53
-
54
- /**
55
- * Read next argument.
56
- * Throws error if no next argument.
57
- * @returns Next argument.
58
- */ function read() {
59
- const value = argv.shift();
60
- if (!value) {
61
- throw new Error("Unexpected end of arguments");
62
- }
63
- return value;
64
- }
65
- /**
66
- * Expectation of the end.
67
- * Throws an error if there are more arguments left.
68
- */ function end() {
69
- if (argv.length) {
70
- throw new Error(`Unexpected argument "${argv[0]}"`);
71
- }
72
- }
73
- /**
74
- * Expect one of the given arguments.
75
- * @param argRefs
76
- * @returns Expected full argument name.
77
- */ function expect(...argRefs) {
78
- const arg = read();
79
- const argName = findArgName(argRefs, arg);
80
- if (!argName) {
81
- throw new Error(`Unexpected argument "${arg}"`);
82
- }
83
- return argName;
84
- }
85
-
86
- /**
87
- * Describe argument with aliases.
88
- * @param name - Main name.
89
- * @param alias - Alias name.
90
- * @param restAliases - Rest aliases.
91
- * @returns Description of argument with aliases..
92
- */ function alias(name, alias, ...restAliases) {
93
- return {
94
- name,
95
- aliases: [
96
- alias,
97
- ...restAliases
98
- ]
99
- };
100
- }
101
- /**
102
- * Describe option with value.
103
- * @param argRef - Option name.
104
- * @param type - Value type.
105
- * @returns Option reader.
106
- */ function option(argRef, type) {
107
- if (type === String) {
108
- return (option, read)=>{
109
- const argName = matchArgName(argRef, option);
110
- if (argName) {
111
- return {
112
- [argName]: read()
113
- };
114
- }
115
- return null;
116
- };
117
- }
118
- if (type === Number) {
119
- return (option, read)=>{
120
- const argName = matchArgName(argRef, option);
121
- if (argName) {
122
- return {
123
- [argName]: parseFloat(read())
124
- };
125
- }
126
- return null;
127
- };
128
- }
129
- if (type === Array) {
130
- return (option, read, options)=>{
131
- const argName = matchArgName(argRef, option);
132
- if (argName) {
133
- const prevValues = options[argName];
134
- const values = read().split(",");
135
- return {
136
- [argName]: Array.isArray(prevValues) ? prevValues.concat(values) : values
137
- };
138
- }
139
- return null;
140
- };
141
- }
142
- return (option)=>{
143
- const argName = matchArgName(argRef, option);
144
- if (argName) {
145
- return {
146
- [argName]: true
147
- };
148
- }
149
- return null;
150
- };
151
- }
152
-
153
- function isOption(arg) {
154
- return /^--?[^-].*/.test(arg);
155
- }
156
- function removePrefix(arg) {
157
- return arg.replace(/^--?/, "");
158
- }
159
- function createOptionReader(optionReaders) {
160
- const optionReader = optionReaders.reduceRight((readNextOption, readOption)=>{
161
- if (!readNextOption) {
162
- return readOption;
163
- }
164
- return (option, read, options)=>readOption(option, read, options) ?? readNextOption(option, read, options);
165
- }, null);
166
- return optionReader;
167
- }
168
- /**
169
- * Read options from arguments.
170
- * @param optionReaders
171
- * @returns Options with values.
172
- */ function readOptions(...optionReaders) {
173
- if (!argv.length) {
174
- return {};
175
- }
176
- const readOption = createOptionReader(optionReaders);
177
- if (!readOption) {
178
- return {};
179
- }
180
- const options = {};
181
- let i = 0;
182
- let arg = argv[i];
183
- let optionResult;
184
- const next = ()=>{
185
- arg = argv[++i];
186
- };
187
- const remove = ()=>{
188
- argv.splice(i--, 1);
189
- };
190
- const read = ()=>{
191
- next();
192
- remove();
193
- if (!arg) {
194
- throw new Error("Unexpected end of arguments");
195
- }
196
- return arg;
197
- };
198
- // eslint-disable-next-line no-unmodified-loop-condition
199
- while(arg){
200
- if (isOption(arg)) {
201
- optionResult = readOption(removePrefix(arg), read, options);
202
- if (optionResult) {
203
- remove();
204
- Object.assign(options, optionResult);
205
- }
206
- }
207
- next();
208
- }
209
- return options;
210
- }
211
-
212
- exports.alias = alias;
213
- exports.argv = argv;
214
- exports.end = end;
215
- exports.expect = expect;
216
- exports.option = option;
217
- exports.read = read;
218
- exports.readOptions = readOptions;
219
- exports.resetArgs = resetArgs;
220
- exports.setArgs = setArgs;
221
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/argv.ts","../src/utils.ts","../src/core.ts","../src/args.ts","../src/options.ts"],"sourcesContent":["\nconst ARGV_START_INDEX = 2\n\n/**\n * Internal state of arguments.\n */\nexport const argv = process.argv.slice(ARGV_START_INDEX)\n\n/**\n * Reset arguments state.\n */\nexport function resetArgs() {\n argv.splice(0, argv.length)\n argv.push(...process.argv.slice(ARGV_START_INDEX))\n}\n\n/**\n * Set arguments state.\n * @param args\n */\nexport function setArgs(...args: string[]) {\n argv.splice(0, argv.length)\n argv.push(...args)\n}\n","\nimport { ArgRef } from './types.js'\n\ntype FlatMerge<T> = T extends infer U ? { [K in keyof U]: U[K] } : never\n\nexport type Merge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R]\n ? FlatMerge<NonNullable<L> & Merge<R>>\n : unknown\n\nexport type UnionMerge<T extends readonly [...unknown[]]> = T extends [infer L, ...infer R]\n ? L | Merge<R>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : any\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyFunction = (...args: any[]) => any\n\nexport type ReturnTypes<T extends readonly [...AnyFunction[]]> = T extends [infer L, ...infer R]\n ? L extends AnyFunction\n ? R extends AnyFunction[]\n ? [ReturnType<L>, ...ReturnTypes<R>]\n : []\n : []\n : []\n\n/**\n * Match reference with argument.\n * @param argRef\n * @param arg\n * @returns Full name or null.\n */\nexport function matchArgName<T extends string>(argRef: ArgRef<T>, arg: string) {\n if (typeof argRef === 'string') {\n return argRef === arg\n ? argRef\n : null\n }\n\n if (argRef.name === arg) {\n return argRef.name\n }\n\n return argRef.aliases.includes(arg)\n ? argRef.name\n : null\n}\n\n/**\n * Find full argument name in references.\n * @param argRefs\n * @param arg\n * @returns Found argument's full name or null.\n */\nexport function findArgName<T extends string>(argRefs: [...ArgRef<T>[]], arg: string) {\n let argRef: ArgRef<T>\n let argName: T | null\n\n for (argRef of argRefs) {\n argName = matchArgName(argRef, arg)\n\n if (argName) {\n return argName\n }\n }\n\n return null\n}\n","import { argv } from './argv.js'\nimport { ArgRef } from './types.js'\nimport { findArgName } from './utils.js'\n\n/**\n * Read next argument.\n * Throws error if no next argument.\n * @returns Next argument.\n */\nexport function read() {\n const value = argv.shift()\n\n if (!value) {\n throw new Error('Unexpected end of arguments')\n }\n\n return value\n}\n\n/**\n * Expectation of the end.\n * Throws an error if there are more arguments left.\n */\nexport function end() {\n if (argv.length) {\n throw new Error(`Unexpected argument \"${argv[0]}\"`)\n }\n}\n\n/**\n * Expect one of the given arguments.\n * @param argRefs\n * @returns Expected full argument name.\n */\nexport function expect<T extends string>(...argRefs: [...ArgRef<T>[]]) {\n const arg = read()\n const argName = findArgName(argRefs, arg)\n\n if (!argName) {\n throw new Error(`Unexpected argument \"${arg}\"`)\n }\n\n return argName\n}\n","import {\n AliasArgRef,\n ArgRef,\n PrimitiveConstructor,\n OptionsReaderState,\n OptionsReaderRead,\n OptionResult\n} from './types.js'\nimport { matchArgName } from './utils.js'\n\n/**\n * Describe argument with aliases.\n * @param name - Main name.\n * @param alias - Alias name.\n * @param restAliases - Rest aliases.\n * @returns Description of argument with aliases..\n */\nexport function alias<T extends string>(name: T, alias: string, ...restAliases: string[]): AliasArgRef<T> {\n return {\n name,\n aliases: [alias, ...restAliases]\n }\n}\n\n/**\n * Describe option with value.\n * @param argRef - Option name.\n * @param type - Value type.\n * @returns Option reader.\n */\nexport function option<T extends string, K extends PrimitiveConstructor>(argRef: ArgRef<T>, type: K) {\n if (type === String) {\n return (option: string, read: OptionsReaderRead) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: read()\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n if (type === Number) {\n return (option: string, read: OptionsReaderRead) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: parseFloat(read())\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n if (type === Array) {\n return (option: string, read: OptionsReaderRead, options: OptionsReaderState) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n const prevValues = options[argName]\n const values = read().split(',')\n\n return {\n [argName]: Array.isArray(prevValues)\n ? prevValues.concat(values)\n : values\n } as OptionResult<T, K>\n }\n\n return null\n }\n }\n\n return (option: string) => {\n const argName = matchArgName(argRef, option)\n\n if (argName) {\n return {\n [argName]: true\n } as OptionResult<T, K>\n }\n\n return null\n }\n}\n","import { argv } from './argv.js'\nimport { OptionReader, OptionResult } from './types.js'\nimport { Merge, ReturnTypes, UnionMerge } from './utils.js'\n\nfunction isOption(arg: string) {\n return /^--?[^-].*/.test(arg)\n}\n\nfunction removePrefix(arg: string) {\n return arg.replace(/^--?/, '')\n}\n\nfunction createOptionReader<T extends OptionReader[]>(optionReaders: [...T]) {\n const optionReader = optionReaders.reduceRight<OptionReader | null>(\n (readNextOption, readOption) => {\n if (!readNextOption) {\n return readOption\n }\n\n return (option, read, options) => readOption(option, read, options) ?? readNextOption(option, read, options)\n },\n null\n )\n\n return optionReader as OptionReader<UnionMerge<ReturnTypes<T>>> | null\n}\n\n/**\n * Read options from arguments.\n * @param optionReaders\n * @returns Options with values.\n */\nexport function readOptions<T extends OptionReader[]>(...optionReaders: [...T]): Partial<Merge<ReturnTypes<T>>> {\n if (!argv.length) {\n return {}\n }\n\n const readOption = createOptionReader(optionReaders)\n\n if (!readOption) {\n return {}\n }\n\n const options = {}\n let i = 0\n let arg = argv[i]\n let optionResult: OptionResult | null\n const next = () => {\n arg = argv[++i]\n }\n const remove = () => {\n argv.splice(i--, 1)\n }\n const read = () => {\n next()\n remove()\n\n if (!arg) {\n throw new Error('Unexpected end of arguments')\n }\n\n return arg\n }\n\n // eslint-disable-next-line no-unmodified-loop-condition\n while (arg) {\n if (isOption(arg)) {\n optionResult = readOption(removePrefix(arg), read, options)\n\n if (optionResult) {\n remove()\n Object.assign(options, optionResult)\n }\n }\n\n next()\n }\n\n return options\n}\n"],"names":["ARGV_START_INDEX","argv","process","slice","resetArgs","splice","length","push","setArgs","args","matchArgName","argRef","arg","name","aliases","includes","findArgName","argRefs","argName","read","value","shift","Error","end","expect","alias","restAliases","option","type","String","Number","parseFloat","Array","options","prevValues","values","split","isArray","concat","isOption","test","removePrefix","replace","createOptionReader","optionReaders","optionReader","reduceRight","readNextOption","readOption","readOptions","i","optionResult","next","remove","Object","assign"],"mappings":"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"}