args-tokens 0.22.6 → 0.23.1

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/lib/resolver.js CHANGED
@@ -1,5 +1,288 @@
1
- import "./parser-M-ayhS1h.js";
2
- import "./utils-1LQrGCWG.js";
3
- import { ArgResolveError, resolveArgs } from "./resolver-DBvNkaE7.js";
1
+ import { hasLongOptionPrefix, isShortOption } from "./parser.js";
2
+ import { t as kebabnize } from "./utils-CxvkckUD.js";
4
3
 
4
+ //#region src/resolver.ts
5
+ /**
6
+ * Entry point of argument options resolver.
7
+ *
8
+ * @module
9
+ */
10
+ /**
11
+ * @author kazuya kawaguchi (a.k.a. kazupon)
12
+ * @license MIT
13
+ */
14
+ const SKIP_POSITIONAL_DEFAULT = -1;
15
+ /**
16
+ * Resolve command line arguments.
17
+ *
18
+ * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
19
+ *
20
+ * @param args - An arguments that contains {@link ArgSchema | arguments schema}.
21
+ * @param tokens - An array of {@link ArgToken | tokens}.
22
+ * @param resolveArgs - An arguments that contains {@link ResolveArgs | resolve arguments}.
23
+ * @returns An object that contains the values of the arguments, positional arguments, rest arguments, {@link AggregateError | validation errors}, and explicit provision status.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // passed tokens: --port 3000
28
+ *
29
+ * const { values, explicit } = resolveArgs({
30
+ * port: {
31
+ * type: 'number',
32
+ * default: 8080
33
+ * },
34
+ * host: {
35
+ * type: 'string',
36
+ * default: 'localhost'
37
+ * }
38
+ * }, parsedTokens)
39
+ *
40
+ * values.port // 3000
41
+ * values.host // 'localhost'
42
+ *
43
+ * explicit.port // true (explicitly provided)
44
+ * explicit.host // false (not provided, fallback to default)
45
+ * ```
46
+ */
47
+ function resolveArgs(args, tokens, { shortGrouping = false, skipPositional = SKIP_POSITIONAL_DEFAULT, toKebab = false } = {}) {
48
+ const skipPositionalIndex = typeof skipPositional === "number" ? Math.max(skipPositional, SKIP_POSITIONAL_DEFAULT) : SKIP_POSITIONAL_DEFAULT;
49
+ const rest = [];
50
+ const optionTokens = [];
51
+ const positionalTokens = [];
52
+ let currentLongOption;
53
+ let currentShortOption;
54
+ const expandableShortOptions = [];
55
+ function toShortValue() {
56
+ if (expandableShortOptions.length === 0) return;
57
+ else {
58
+ const value = expandableShortOptions.map((token) => token.name).join("");
59
+ expandableShortOptions.length = 0;
60
+ return value;
61
+ }
62
+ }
63
+ function applyLongOptionValue(value = void 0) {
64
+ if (currentLongOption) {
65
+ currentLongOption.value = value;
66
+ optionTokens.push({ ...currentLongOption });
67
+ currentLongOption = void 0;
68
+ }
69
+ }
70
+ function applyShortOptionValue(value = void 0) {
71
+ if (currentShortOption) {
72
+ currentShortOption.value = value || toShortValue();
73
+ optionTokens.push({ ...currentShortOption });
74
+ currentShortOption = void 0;
75
+ }
76
+ }
77
+ /**
78
+ * analyze phase to resolve value
79
+ * separate tokens into positionals, long and short options, after that resolve values
80
+ */
81
+ const schemas = Object.values(args);
82
+ let terminated = false;
83
+ for (let i = 0; i < tokens.length; i++) {
84
+ const token = tokens[i];
85
+ if (token.kind === "positional") {
86
+ if (terminated && token.value) {
87
+ rest.push(token.value);
88
+ continue;
89
+ }
90
+ if (currentShortOption) {
91
+ if (schemas.find((schema) => schema.short === currentShortOption.name && schema.type === "boolean")) positionalTokens.push({ ...token });
92
+ } else if (currentLongOption) {
93
+ if (args[currentLongOption.name]?.type === "boolean") positionalTokens.push({ ...token });
94
+ } else positionalTokens.push({ ...token });
95
+ applyLongOptionValue(token.value);
96
+ applyShortOptionValue(token.value);
97
+ } else if (token.kind === "option") if (token.rawName) {
98
+ if (hasLongOptionPrefix(token.rawName)) {
99
+ applyLongOptionValue();
100
+ if (token.inlineValue) optionTokens.push({ ...token });
101
+ else currentLongOption = { ...token };
102
+ applyShortOptionValue();
103
+ } else if (isShortOption(token.rawName)) if (currentShortOption) {
104
+ if (currentShortOption.index === token.index) if (shortGrouping) {
105
+ currentShortOption.value = token.value;
106
+ optionTokens.push({ ...currentShortOption });
107
+ currentShortOption = { ...token };
108
+ } else expandableShortOptions.push({ ...token });
109
+ else {
110
+ currentShortOption.value = toShortValue();
111
+ optionTokens.push({ ...currentShortOption });
112
+ currentShortOption = { ...token };
113
+ }
114
+ applyLongOptionValue();
115
+ } else {
116
+ currentShortOption = { ...token };
117
+ applyLongOptionValue();
118
+ }
119
+ } else {
120
+ if (currentShortOption && currentShortOption.index == token.index && token.inlineValue) {
121
+ currentShortOption.value = token.value;
122
+ optionTokens.push({ ...currentShortOption });
123
+ currentShortOption = void 0;
124
+ }
125
+ applyLongOptionValue();
126
+ }
127
+ else {
128
+ if (token.kind === "option-terminator") terminated = true;
129
+ applyLongOptionValue();
130
+ applyShortOptionValue();
131
+ }
132
+ }
133
+ /**
134
+ * check if the last long or short option is not resolved
135
+ */
136
+ applyLongOptionValue();
137
+ applyShortOptionValue();
138
+ /**
139
+ * resolve values
140
+ */
141
+ const values = Object.create(null);
142
+ const errors = [];
143
+ const explicit = Object.create(null);
144
+ const actualInputNames = /* @__PURE__ */ new Map();
145
+ function checkTokenName(option, schema, token) {
146
+ return token.name === (schema.type === "boolean" ? schema.negatable && token.name?.startsWith("no-") ? `no-${option}` : option : option);
147
+ }
148
+ const positionalItemCount = tokens.filter((token) => token.kind === "positional").length;
149
+ function getPositionalSkipIndex() {
150
+ return Math.min(skipPositionalIndex, positionalItemCount);
151
+ }
152
+ let positionalsCount = 0;
153
+ for (const [rawArg, schema] of Object.entries(args)) {
154
+ const arg = toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
155
+ explicit[rawArg] = false;
156
+ if (schema.type === "positional") {
157
+ if (skipPositionalIndex > SKIP_POSITIONAL_DEFAULT) while (positionalsCount <= getPositionalSkipIndex()) positionalsCount++;
158
+ if (schema.multiple) {
159
+ const remainingPositionals = positionalTokens.slice(positionalsCount);
160
+ if (remainingPositionals.length > 0) {
161
+ values[rawArg] = remainingPositionals.map((p) => p.value);
162
+ positionalsCount += remainingPositionals.length;
163
+ explicit[rawArg] = true;
164
+ } else if (schema.required) errors.push(createRequireError(arg, schema));
165
+ } else {
166
+ const positional = positionalTokens[positionalsCount];
167
+ if (positional != null) {
168
+ values[rawArg] = positional.value;
169
+ explicit[rawArg] = true;
170
+ } else errors.push(createRequireError(arg, schema));
171
+ positionalsCount++;
172
+ }
173
+ continue;
174
+ }
175
+ if (schema.required) {
176
+ if (!optionTokens.find((token) => {
177
+ return schema.short && token.name === schema.short || token.rawName && hasLongOptionPrefix(token.rawName) && token.name === arg;
178
+ })) {
179
+ errors.push(createRequireError(arg, schema));
180
+ continue;
181
+ }
182
+ }
183
+ for (let i = 0; i < optionTokens.length; i++) {
184
+ const token = optionTokens[i];
185
+ if (checkTokenName(arg, schema, token) && token.rawName != void 0 && hasLongOptionPrefix(token.rawName) || schema.short === token.name && token.rawName != void 0 && isShortOption(token.rawName)) {
186
+ const invalid = validateRequire(token, arg, schema);
187
+ if (invalid) {
188
+ errors.push(invalid);
189
+ continue;
190
+ }
191
+ explicit[rawArg] = true;
192
+ const actualInputName = isShortOption(token.rawName) ? `-${token.name}` : `--${arg}`;
193
+ actualInputNames.set(rawArg, actualInputName);
194
+ if (schema.type === "boolean") token.value = void 0;
195
+ const [parsedValue, error] = parse(token, arg, schema);
196
+ if (error) errors.push(error);
197
+ else if (schema.multiple) {
198
+ values[rawArg] ||= [];
199
+ values[rawArg].push(parsedValue);
200
+ } else values[rawArg] = parsedValue;
201
+ }
202
+ }
203
+ if (values[rawArg] == null && schema.default != null) values[rawArg] = schema.default;
204
+ }
205
+ const conflictErrors = checkConflicts(args, explicit, toKebab, actualInputNames);
206
+ errors.push(...conflictErrors);
207
+ return {
208
+ values,
209
+ positionals: positionalTokens.map((token) => token.value),
210
+ rest,
211
+ error: errors.length > 0 ? new AggregateError(errors) : void 0,
212
+ explicit
213
+ };
214
+ }
215
+ function parse(token, option, schema) {
216
+ switch (schema.type) {
217
+ case "string": return typeof token.value === "string" ? [token.value || schema.default, void 0] : [void 0, createTypeError(option, schema)];
218
+ case "boolean": return token.value ? [token.value || schema.default, void 0] : [!(schema.negatable && token.name.startsWith("no-")), void 0];
219
+ case "number":
220
+ if (!isNumeric(token.value)) return [void 0, createTypeError(option, schema)];
221
+ return token.value ? [+token.value, void 0] : [+(schema.default || ""), void 0];
222
+ case "enum":
223
+ if (schema.choices && !schema.choices.includes(token.value)) return [void 0, new ArgResolveError(`Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}should be chosen from '${schema.type}' [${schema.choices.map((c) => JSON.stringify(c)).join(", ")}] values`, option, "type", schema)];
224
+ return [token.value || schema.default, void 0];
225
+ case "custom":
226
+ if (typeof schema.parse !== "function") throw new TypeError(`argument '${option}' should have a 'parse' function`);
227
+ try {
228
+ return [schema.parse(token.value || String(schema.default || "")), void 0];
229
+ } catch (error) {
230
+ return [void 0, error];
231
+ }
232
+ default: throw new Error(`Unsupported argument type '${schema.type}' for option '${option}'`);
233
+ }
234
+ }
235
+ function createRequireError(option, schema) {
236
+ return new ArgResolveError(schema.type === "positional" ? `Positional argument '${option}' is required` : `Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}is required`, option, "required", schema);
237
+ }
238
+ /**
239
+ * An error that occurs when resolving arguments.
240
+ * This error is thrown when the argument is not valid.
241
+ */
242
+ var ArgResolveError = class extends Error {
243
+ name;
244
+ schema;
245
+ type;
246
+ /**
247
+ * Create an `ArgResolveError` instance.
248
+ *
249
+ * @param message - the error message
250
+ * @param name - the name of the argument
251
+ * @param type - the type of the error, either 'type' or 'required'
252
+ * @param schema - the argument schema that caused the error
253
+ */
254
+ constructor(message, name, type, schema) {
255
+ super(message);
256
+ this.name = name;
257
+ this.type = type;
258
+ this.schema = schema;
259
+ }
260
+ };
261
+ function validateRequire(token, option, schema) {
262
+ if (schema.required && schema.type !== "boolean" && !token.value) return createRequireError(option, schema);
263
+ }
264
+ function isNumeric(str) {
265
+ return str.trim() !== "" && !isNaN(str);
266
+ }
267
+ function createTypeError(option, schema) {
268
+ return new ArgResolveError(`Optional argument '--${option}' ${schema.short ? `or '-${schema.short}' ` : ""}should be '${schema.type}'`, option, "type", schema);
269
+ }
270
+ function checkConflicts(args, explicit, toKebab, actualInputNames) {
271
+ for (const rawArg in args) {
272
+ const schema = args[rawArg];
273
+ if (!explicit[rawArg]) continue;
274
+ if (!schema.conflicts) continue;
275
+ const conflicts = Array.isArray(schema.conflicts) ? schema.conflicts : [schema.conflicts];
276
+ for (let i = 0; i < conflicts.length; i++) {
277
+ const conflictingArg = conflicts[i];
278
+ if (!explicit[conflictingArg]) continue;
279
+ const arg = toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
280
+ const conflictingArgKebab = toKebab || args[conflictingArg]?.toKebab ? kebabnize(conflictingArg) : conflictingArg;
281
+ return [new ArgResolveError(`Optional argument '${actualInputNames.get(rawArg) || `--${arg}`}' conflicts with '${actualInputNames.get(conflictingArg) || `--${conflictingArgKebab}`}'`, rawArg, "conflict", schema)];
282
+ }
283
+ }
284
+ return [];
285
+ }
286
+
287
+ //#endregion
5
288
  export { ArgResolveError, resolveArgs };
@@ -21,4 +21,4 @@ function kebabnize(str) {
21
21
  }
22
22
 
23
23
  //#endregion
24
- export { kebabnize };
24
+ export { kebabnize as t };
package/lib/utils.js CHANGED
@@ -1,3 +1,3 @@
1
- import { kebabnize } from "./utils-1LQrGCWG.js";
1
+ import { t as kebabnize } from "./utils-CxvkckUD.js";
2
2
 
3
3
  export { kebabnize };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "args-tokens",
3
3
  "description": "parseArgs tokens compatibility and more high-performance parser",
4
- "version": "0.22.6",
4
+ "version": "0.23.1",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -71,35 +71,36 @@
71
71
  }
72
72
  },
73
73
  "devDependencies": {
74
- "@eslint/markdown": "^6.6.0",
75
- "@kazupon/eslint-config": "^0.33.3",
76
- "@kazupon/prettier-config": "^0.1.1",
77
- "@types/node": "^22.17.0",
78
- "@typescript/native-preview": "7.0.0-dev.20250802.1",
79
- "@vitest/eslint-plugin": "^1.3.4",
80
- "bumpp": "^10.2.2",
81
- "deno": "^2.4.3",
82
- "eslint": "^9.32.0",
74
+ "@eslint/markdown": "^7.5.1",
75
+ "@kazupon/eslint-config": "^0.44.0",
76
+ "@kazupon/prettier-config": "^0.2.0",
77
+ "@types/node": "^24.10.9",
78
+ "@typescript/native-preview": "7.0.0-dev.20260131.1",
79
+ "@vitest/eslint-plugin": "^1.6.6",
80
+ "bumpp": "^10.4.0",
81
+ "deno": "^2.6.7",
82
+ "eslint": "^9.39.2",
83
83
  "eslint-config-prettier": "^10.1.8",
84
- "eslint-plugin-jsdoc": "^52.0.2",
85
- "eslint-plugin-jsonc": "^2.20.1",
84
+ "eslint-plugin-jsdoc": "^52.0.4",
85
+ "eslint-plugin-jsonc": "^2.21.0",
86
+ "eslint-plugin-markdown-preferences": "^0.10.0",
86
87
  "eslint-plugin-promise": "^7.2.1",
87
- "eslint-plugin-regexp": "^2.9.0",
88
+ "eslint-plugin-regexp": "^2.10.0",
88
89
  "eslint-plugin-unicorn": "^60.0.0",
89
- "eslint-plugin-yml": "^1.18.0",
90
+ "eslint-plugin-yml": "^1.19.1",
90
91
  "gh-changelogen": "^0.2.8",
91
- "jsr": "^0.13.5",
92
- "jsr-exports-lint": "^0.4.1",
93
- "knip": "^5.62.0",
94
- "lint-staged": "^16.1.2",
92
+ "jsr": "^0.14.2",
93
+ "jsr-exports-lint": "^0.4.2",
94
+ "knip": "^5.82.1",
95
+ "lint-staged": "^16.2.7",
95
96
  "mitata": "^1.0.34",
96
- "pkg-pr-new": "^0.0.54",
97
- "prettier": "^3.6.2",
98
- "tsdown": "^0.13.1",
99
- "typescript": "^5.9.2",
100
- "typescript-eslint": "^8.38.0",
101
- "vitest": "^3.2.4",
102
- "zod": "^4.0.14"
97
+ "pkg-pr-new": "^0.0.62",
98
+ "prettier": "^3.8.1",
99
+ "tsdown": "^0.20.1",
100
+ "typescript": "^5.9.3",
101
+ "typescript-eslint": "^8.54.0",
102
+ "vitest": "^4.0.18",
103
+ "zod": "^4.3.6"
103
104
  },
104
105
  "prettier": "@kazupon/prettier-config",
105
106
  "lint-staged": {
@@ -1,98 +0,0 @@
1
- //#region src/parser.d.ts
2
- /**
3
- * Entry point of argument parser.
4
- *
5
- * @module
6
- */
7
- /**
8
- * forked from `nodejs/node` (`pkgjs/parseargs`)
9
- * repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
10
- * code url: https://github.com/nodejs/node/blob/main/lib/internal/util/parse_args/parse_args.js
11
- *
12
- * @author kazuya kawaguchi (a.k.a. kazupon)
13
- * @license MIT
14
- */
15
- /**
16
- * Argument token Kind.
17
- *
18
- * - `option`: option token, support short option (e.g. `-x`) and long option (e.g. `--foo`)
19
- * - `option-terminator`: option terminator (`--`) token, see guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
20
- * - `positional`: positional token
21
- */
22
- type ArgTokenKind = 'option' | 'option-terminator' | 'positional';
23
- /**
24
- * Argument token.
25
- */
26
- interface ArgToken {
27
- /**
28
- * Argument token kind.
29
- */
30
- kind: ArgTokenKind;
31
- /**
32
- * Argument token index, e.g `--foo bar` => `--foo` index is 0, `bar` index is 1.
33
- */
34
- index: number;
35
- /**
36
- * Option name, e.g. `--foo` => `foo`, `-x` => `x`.
37
- */
38
- name?: string;
39
- /**
40
- * Raw option name, e.g. `--foo` => `--foo`, `-x` => `-x`.
41
- */
42
- rawName?: string;
43
- /**
44
- * Option value, e.g. `--foo=bar` => `bar`, `-x=bar` => `bar`.
45
- * If the `allowCompatible` option is `true`, short option value will be same as Node.js `parseArgs` behavior.
46
- */
47
- value?: string;
48
- /**
49
- * Inline value, e.g. `--foo=bar` => `true`, `-x=bar` => `true`.
50
- */
51
- inlineValue?: boolean;
52
- }
53
- /**
54
- * Parser Options.
55
- */
56
- interface ParserOptions {
57
- /**
58
- * [Node.js parseArgs](https://nodejs.org/api/util.html#parseargs-tokens) tokens compatible mode.
59
- *
60
- * @default false
61
- */
62
- allowCompatible?: boolean;
63
- }
64
- /**
65
- * Parse command line arguments.
66
- *
67
- * @param args - command line arguments
68
- * @param options - parse options, about details see {@link ParserOptions}
69
- * @returns Argument tokens.
70
- *
71
- * @example
72
- * ```js
73
- * import { parseArgs } from 'args-tokens' // for Node.js and Bun
74
- * // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
75
- *
76
- * const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
77
- * // do something with using tokens
78
- * // ...
79
- * console.log('tokens:', tokens)
80
- * ```
81
- */
82
- declare function parseArgs(args: string[], options?: ParserOptions): ArgToken[];
83
- /**
84
- * Check if `arg` is a short option (e.g. `-f`).
85
- *
86
- * @param arg - An argument to check
87
- * @returns Whether `arg` is a short option.
88
- */
89
- declare function isShortOption(arg: string): boolean;
90
- /**
91
- * Check if `arg` is a long option prefix (e.g. `--`).
92
- *
93
- * @param arg - An argument to check
94
- * @returns Whether `arg` is a long option prefix.
95
- */
96
- declare function hasLongOptionPrefix(arg: string): boolean;
97
- //#endregion
98
- export { ArgToken, ParserOptions, hasLongOptionPrefix as hasLongOptionPrefix$1, isShortOption as isShortOption$1, parseArgs as parseArgs$1 };
@@ -1,199 +0,0 @@
1
- //#region src/parser.ts
2
- const HYPHEN_CHAR = "-";
3
- const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
4
- const EQUAL_CHAR = "=";
5
- const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
6
- const TERMINATOR = "--";
7
- const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
8
- const LONG_OPTION_PREFIX = "--";
9
- /**
10
- * Parse command line arguments.
11
- *
12
- * @param args - command line arguments
13
- * @param options - parse options, about details see {@link ParserOptions}
14
- * @returns Argument tokens.
15
- *
16
- * @example
17
- * ```js
18
- * import { parseArgs } from 'args-tokens' // for Node.js and Bun
19
- * // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
20
- *
21
- * const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
22
- * // do something with using tokens
23
- * // ...
24
- * console.log('tokens:', tokens)
25
- * ```
26
- */
27
- function parseArgs(args, options = {}) {
28
- const { allowCompatible = false } = options;
29
- const tokens = [];
30
- const remainings = [...args];
31
- let index = -1;
32
- let groupCount = 0;
33
- let hasShortValueSeparator = false;
34
- while (remainings.length > 0) {
35
- const arg = remainings.shift();
36
- if (arg == void 0) break;
37
- const nextArg = remainings[0];
38
- if (groupCount > 0) groupCount--;
39
- else index++;
40
- if (arg === TERMINATOR) {
41
- tokens.push({
42
- kind: "option-terminator",
43
- index
44
- });
45
- const mapped = remainings.map((arg$1) => {
46
- return {
47
- kind: "positional",
48
- index: ++index,
49
- value: arg$1
50
- };
51
- });
52
- tokens.push(...mapped);
53
- break;
54
- }
55
- if (isShortOption(arg)) {
56
- const shortOption = arg.charAt(1);
57
- let value;
58
- let inlineValue;
59
- if (groupCount) {
60
- tokens.push({
61
- kind: "option",
62
- name: shortOption,
63
- rawName: arg,
64
- index,
65
- value,
66
- inlineValue
67
- });
68
- if (groupCount === 1 && hasOptionValue(nextArg)) {
69
- value = remainings.shift();
70
- if (hasShortValueSeparator) {
71
- inlineValue = true;
72
- hasShortValueSeparator = false;
73
- }
74
- tokens.push({
75
- kind: "option",
76
- index,
77
- value,
78
- inlineValue
79
- });
80
- }
81
- } else tokens.push({
82
- kind: "option",
83
- name: shortOption,
84
- rawName: arg,
85
- index,
86
- value,
87
- inlineValue
88
- });
89
- if (value != null) ++index;
90
- continue;
91
- }
92
- if (isShortOptionGroup(arg)) {
93
- const expanded = [];
94
- let shortValue = "";
95
- for (let i = 1; i < arg.length; i++) {
96
- const shortableOption = arg.charAt(i);
97
- if (hasShortValueSeparator) shortValue += shortableOption;
98
- else if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE) hasShortValueSeparator = true;
99
- else expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
100
- }
101
- if (shortValue) expanded.push(shortValue);
102
- remainings.unshift(...expanded);
103
- groupCount = expanded.length;
104
- continue;
105
- }
106
- if (isLongOption(arg)) {
107
- const longOption = arg.slice(2);
108
- tokens.push({
109
- kind: "option",
110
- name: longOption,
111
- rawName: arg,
112
- index,
113
- value: void 0,
114
- inlineValue: void 0
115
- });
116
- continue;
117
- }
118
- if (isLongOptionAndValue(arg)) {
119
- const equalIndex = arg.indexOf(EQUAL_CHAR);
120
- const longOption = arg.slice(2, equalIndex);
121
- const value = arg.slice(equalIndex + 1);
122
- tokens.push({
123
- kind: "option",
124
- name: longOption,
125
- rawName: `${LONG_OPTION_PREFIX}${longOption}`,
126
- index,
127
- value,
128
- inlineValue: true
129
- });
130
- continue;
131
- }
132
- tokens.push({
133
- kind: "positional",
134
- index,
135
- value: arg
136
- });
137
- }
138
- return tokens;
139
- }
140
- /**
141
- * Check if `arg` is a short option (e.g. `-f`).
142
- *
143
- * @param arg - An argument to check
144
- * @returns Whether `arg` is a short option.
145
- */
146
- function isShortOption(arg) {
147
- return arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE;
148
- }
149
- /**
150
- * Check if `arg` is a short option group (e.g. `-abc`).
151
- *
152
- * @param arg - An argument to check
153
- * @returns Whether `arg` is a short option group.
154
- */
155
- function isShortOptionGroup(arg) {
156
- if (arg.length <= 2) return false;
157
- if (arg.codePointAt(0) !== HYPHEN_CODE) return false;
158
- if (arg.codePointAt(1) === HYPHEN_CODE) return false;
159
- return true;
160
- }
161
- /**
162
- * Check if `arg` is a long option (e.g. `--foo`).
163
- *
164
- * @param arg - An argument to check
165
- * @returns Whether `arg` is a long option.
166
- */
167
- function isLongOption(arg) {
168
- return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
169
- }
170
- /**
171
- * Check if `arg` is a long option with value (e.g. `--foo=bar`).
172
- *
173
- * @param arg - An argument to check
174
- * @returns Whether `arg` is a long option.
175
- */
176
- function isLongOptionAndValue(arg) {
177
- return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
178
- }
179
- /**
180
- * Check if `arg` is a long option prefix (e.g. `--`).
181
- *
182
- * @param arg - An argument to check
183
- * @returns Whether `arg` is a long option prefix.
184
- */
185
- function hasLongOptionPrefix(arg) {
186
- return arg.length > 2 && ~arg.indexOf(LONG_OPTION_PREFIX);
187
- }
188
- /**
189
- * Check if a `value` is an option value.
190
- *
191
- * @param value - A value to check
192
- * @returns Whether a `value` is an option value.
193
- */
194
- function hasOptionValue(value) {
195
- return !(value == null) && value.codePointAt(0) !== HYPHEN_CODE;
196
- }
197
-
198
- //#endregion
199
- export { hasLongOptionPrefix, isShortOption, parseArgs };