args-tokens 0.0.0 โ†’ 0.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 +1,200 @@
1
- # args
1
+ # args-tokens
2
+
3
+ [![Version][npm-version-src]][npm-version-href]
4
+ [![CI][ci-src]][ci-href]
5
+
6
+ > [`parseArgs` tokens](https://nodejs.org/api/util.html#parseargs-tokens) compatibility and more high-performance parser
7
+
8
+ ## ๐Ÿฑ Motivation
9
+
10
+ - Although Node.js's [`parseArgs`](https://nodejs.org/api/util.html#utilparseargsconfig) can return tokens, tokens that the shot options are not in the format I expect. Of course, I know the background of [this issue](https://github.com/pkgjs/parseargs/issues/78).
11
+ - `parseArgs` gives the command line args parser a useful util, so the resolution of the options values and the parsing of the tokens are tightly coupled. As a result, Performance is sacrificed. Of course, I know that's a trade-off.
12
+
13
+ ## โฑ๏ธ Benchmark
14
+
15
+ With [mitata](https://github.com/evanwashere/mitata):
16
+
17
+ ```
18
+ pnpm bench:mitata
19
+
20
+ > args-tokens@0.0.0 bench:mitata /path/to/projects/args-tokens
21
+ > node --expose-gc bench/index.mjs
22
+
23
+ clk: ~2.87 GHz
24
+ cpu: Apple M1 Max
25
+ runtime: node 18.19.1 (arm64-darwin)
26
+
27
+ benchmark avg (min โ€ฆ max) p75 / p99 (min โ€ฆ top 1%)
28
+ ------------------------------------------- -------------------------------
29
+ node:util parseArgs 4.69 ยตs/iter 4.78 ยตs โ–ˆ โ–ˆ โ–ˆโ–ˆ
30
+ (4.49 ยตs โ€ฆ 4.91 ยตs) 4.85 ยตs โ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ
31
+ ( 1.32 kb โ€ฆ 1.49 kb) 1.33 kb โ–ˆโ–โ–ˆโ–ˆโ–โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
32
+
33
+ args-tokens parseArgs 842.98 ns/iter 882.65 ns โ–„โ–„โ–„โ–‡โ–ƒ โ–„โ–ƒ โ–ˆ
34
+ (734.10 ns โ€ฆ 984.32 ns) 966.06 ns โ–‚โ–„โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–„โ–ˆโ–ˆโ–ˆโ–ˆโ–…โ–…โ–„
35
+ ( 3.11 kb โ€ฆ 3.41 kb) 3.12 kb โ–ˆโ–‚โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–†โ–†โ–†โ–‚
36
+
37
+ โ”Œ โ”
38
+ node:util parseArgs โ”คโ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ– โ–  4.69 ยตs
39
+ args-tokens parseArgs โ”ค 842.98 ns
40
+ โ”” โ”˜
41
+ ```
42
+
43
+ With [vitest](https://vitest.dev/guide/features.html#benchmarking):
44
+
45
+ ```
46
+ pnpm bench:vitest
47
+
48
+ > args-tokens@0.0.0 bench:vitest /path/to/projects/args-tokens
49
+ > vitest bench --run
50
+
51
+ Benchmarking is an experimental feature.
52
+ Breaking changes might not follow SemVer, please pin Vitest's version when using it.
53
+
54
+ RUN v3.0.5 /path/to/projects/args-tokens
55
+
56
+
57
+ โœ“ bench/vitest.bench.mjs > parseArgs 1466ms
58
+ name hz min max mean p75 p99 p995 p999 rme samples
59
+ ยท node:util 194,911.34 0.0042 0.6821 0.0051 0.0046 0.0151 0.0292 0.1079 ยฑ0.82% 97456
60
+ ยท args-tokens 1,101,845.21 0.0007 0.1883 0.0009 0.0009 0.0012 0.0031 0.0140 ยฑ0.32% 550923 fastest
61
+
62
+ BENCH Summary
63
+
64
+ args-tokens - bench/vitest.bench.mjs > parseArgs
65
+ 5.65x faster than node:util
66
+ ```
67
+
68
+ ## โ“ What's different about parseArgs tokens?
69
+
70
+ The token output for the short option `-x=v` is different:
71
+
72
+ ```js
73
+ import { parseArgs as parseArgsNode } from 'node:util'
74
+ import { parseArgs } from 'args-tokens'
75
+
76
+ // Node.js parseArgs tokens
77
+ const { tokens: tokensNode } = parseArgsNode({
78
+ allowPositionals: true,
79
+ strict: false,
80
+ args: ['-a=1'],
81
+ tokens: true
82
+ })
83
+ console.log(tokensNode)
84
+
85
+ // ({
86
+ // kind: 'option',
87
+ // name: 'a',
88
+ // rawName: '-a',
89
+ // index: 0,
90
+ // value: undefined,
91
+ // inlineValue: undefined
92
+ // },
93
+ // {
94
+ // kind: 'option',
95
+ // name: '=',
96
+ // rawName: '-=',
97
+ // index: 0,
98
+ // value: undefined,
99
+ // inlineValue: undefined
100
+ // },
101
+ // {
102
+ // kind: 'option',
103
+ // name: '1',
104
+ // rawName: '-1',
105
+ // index: 0,
106
+ // value: undefined,
107
+ // inlineValue: undefined
108
+ // })
109
+ // ]
110
+
111
+ // args-tokens parseArgs tokens
112
+ const tokens = parseArgs(['-a=1'])
113
+ console.log(tokens)
114
+
115
+ // [
116
+ // {
117
+ // kind: 'option',
118
+ // name: 'a',
119
+ // rawName: '-a',
120
+ // index: 0,
121
+ // value: undefined,
122
+ // inlineValue: undefined
123
+ // },
124
+ // { kind: 'option', index: 0, value: '1', inlineValue: true }
125
+ // ]
126
+ ```
127
+
128
+ ## ๐Ÿš€ Usage
129
+
130
+ ### ๐Ÿ’ฟ Installation
131
+
132
+ ```sh
133
+ # npm
134
+ npm install --save args-tokens
135
+
136
+ ## yarn
137
+ yarn add args-tokens
138
+
139
+ ## pnpm
140
+ pnpm add args-tokens
141
+ ```
142
+
143
+ ### ๐Ÿญ Codes
144
+
145
+ ```js
146
+ import { parseArgs } from 'args-tokens'
147
+
148
+ const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
149
+ // do something with using tokens
150
+ // ...
151
+ console.log('tokens:', tokens)
152
+ ```
153
+
154
+ ## Node.js `parseArgs` tokens compatible
155
+
156
+ If you want to use the same short options tokens as returned Node.js `parseArgs`, you can use `allowCompatible` parse option on `parseArgs`:
157
+
158
+ ```js
159
+ import { parseArgs as parseArgsNode } from 'node:util'
160
+ import { parseArgs } from 'args-tokens'
161
+ import { deepStrictEqual } from 'node:assert'
162
+
163
+ const args = ['-a=1', '2']
164
+
165
+ // Node.js parseArgs tokens
166
+ const { tokens: tokensNode } = parseArgsNode({
167
+ allowPositionals: true,
168
+ strict: false,
169
+ args,
170
+ tokens: true
171
+ })
172
+
173
+ // args-tokens parseArgs tokens
174
+ const tokens = parseArgs(['-a=1'])
175
+
176
+ // validate
177
+ deepStrictEqual(tokensNode, tokens)
178
+ ```
179
+
180
+ ## ๐Ÿ™Œ Contributing guidelines
181
+
182
+ If you are interested in contributing to `args-tokens`, I highly recommend checking out [the contributing guidelines](/CONTRIBUTING.md) here. You'll find all the relevant information such as [how to make a PR](/CONTRIBUTING.md#pull-request-guidelines), [how to setup development](/CONTRIBUTING.md#development-setup)) etc., there.
183
+
184
+ ## ๐Ÿ’– Credits
185
+
186
+ This project is inspired by:
187
+
188
+ - [`utils.parseArgs`](https://nodejs.org/api/util.html#utilparseargsconfig), created by Node.js contributors and [OpenJS Foundation](https://openjsf.org/)
189
+ - [`pkgjs/parseargs`](https://github.com/pkgjs/parseargs), created by Node.js CLI package maintainers and Node.js community.
190
+
191
+ ## ยฉ๏ธ License
192
+
193
+ [MIT](http://opensource.org/licenses/MIT)
194
+
195
+ <!-- Badges -->
196
+
197
+ [npm-version-src]: https://img.shields.io/npm/v/args-tokens?style=flat
198
+ [npm-version-href]: https://npmjs.com/package/args-tokens
199
+ [ci-src]: https://github.com/kazupon/args-tokens/actions/workflows/ci.yml/badge.svg
200
+ [ci-href]: https://github.com/kazupon/args-tokens/actions/workflows/ci.yml
@@ -1 +1,27 @@
1
- export declare function add(a: number, b: number): number;
1
+ type ArgTokenKind = 'option' | 'option-terminator' | 'positional';
2
+ export interface ArgToken {
3
+ kind: ArgTokenKind;
4
+ index: number;
5
+ name?: string;
6
+ rawName?: string;
7
+ value?: string;
8
+ inlineValue?: boolean;
9
+ }
10
+ /**
11
+ * Parse Options
12
+ */
13
+ export interface ParseOptions {
14
+ /**
15
+ * [Node.js parseArgs](https://nodejs.org/api/util.html#parseargs-tokens) tokens compatible mode
16
+ * @default false
17
+ */
18
+ allowCompatible?: boolean;
19
+ }
20
+ /**
21
+ * Parse command line arguments
22
+ * @param args command line arguments
23
+ * @param options parse options
24
+ * @returns argument tokens
25
+ */
26
+ export declare function parseArgs(args: string[], options?: ParseOptions): ArgToken[];
27
+ export {};
package/lib/cjs/index.js CHANGED
@@ -1,6 +1,218 @@
1
1
  "use strict";
2
+ // SPDX-License-Identifier: MIT
3
+ // Modifier: kazuya kawaguchi (a.k.a. kazupon)
4
+ // Forked from `nodejs/node` (`pkgjs/parseargs`)
5
+ // Repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
6
+ // Author: Node.js contributors
7
+ // Code url: https://github.com/nodejs/node/blob/main/lib/internal/util/parse_args/parse_args.js
2
8
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.add = add;
4
- function add(a, b) {
5
- return a + b;
9
+ exports.parseArgs = parseArgs;
10
+ const HYPHEN_CHAR = '-';
11
+ const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
12
+ const EQUAL_CHAR = '=';
13
+ const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
14
+ const TERMINATOR = '--';
15
+ const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
16
+ const LONG_OPTION_PREFIX = '--';
17
+ /**
18
+ * Parse command line arguments
19
+ * @param args command line arguments
20
+ * @param options parse options
21
+ * @returns argument tokens
22
+ */
23
+ function parseArgs(args, options = {}) {
24
+ const { allowCompatible = false } = options;
25
+ const tokens = [];
26
+ const remainings = [...args];
27
+ let index = -1;
28
+ let groupCount = 0;
29
+ let hasShortValueSeparator = false;
30
+ while (remainings.length > 0) {
31
+ const arg = remainings.shift();
32
+ if (arg == undefined) {
33
+ break;
34
+ }
35
+ const nextArg = remainings[0];
36
+ if (groupCount > 0) {
37
+ groupCount--;
38
+ }
39
+ else {
40
+ index++;
41
+ }
42
+ // check if `arg` is an options terminator.
43
+ // guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
44
+ if (arg === TERMINATOR) {
45
+ tokens.push({
46
+ kind: 'option-terminator',
47
+ index
48
+ });
49
+ const mapped = remainings.map(arg => {
50
+ return { kind: 'positional', index: ++index, value: arg };
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
+ // e.g. `-abc`
61
+ tokens.push({
62
+ kind: 'option',
63
+ name: shortOption,
64
+ rawName: arg,
65
+ index,
66
+ value,
67
+ inlineValue
68
+ });
69
+ if (groupCount === 1 && hasOptionValue(nextArg)) {
70
+ value = remainings.shift();
71
+ if (hasShortValueSeparator) {
72
+ inlineValue = true;
73
+ hasShortValueSeparator = false;
74
+ }
75
+ tokens.push({
76
+ kind: 'option',
77
+ index,
78
+ value,
79
+ inlineValue
80
+ });
81
+ }
82
+ }
83
+ else {
84
+ // e.g. `-a`
85
+ tokens.push({
86
+ kind: 'option',
87
+ name: shortOption,
88
+ rawName: arg,
89
+ index,
90
+ value,
91
+ inlineValue
92
+ });
93
+ }
94
+ // eslint-disable-next-line unicorn/no-null
95
+ if (value != null) {
96
+ ++index;
97
+ }
98
+ continue;
99
+ }
100
+ if (isShortOptionGroup(arg)) {
101
+ // expend short option group (e.g. `-abc` => `-a -b -c`, `-f=bar` => `-f bar`)
102
+ const expanded = [];
103
+ let shortValue = '';
104
+ for (let i = 1; i < arg.length; i++) {
105
+ const shortableOption = arg.charAt(i);
106
+ if (hasShortValueSeparator) {
107
+ shortValue += shortableOption;
108
+ }
109
+ else {
110
+ if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE) {
111
+ hasShortValueSeparator = true;
112
+ }
113
+ else {
114
+ expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
115
+ }
116
+ }
117
+ }
118
+ if (shortValue) {
119
+ expanded.push(shortValue);
120
+ }
121
+ remainings.unshift(...expanded);
122
+ groupCount = expanded.length;
123
+ continue;
124
+ }
125
+ if (isLongOption(arg)) {
126
+ // e.g. `--foo`
127
+ const longOption = arg.slice(2);
128
+ tokens.push({
129
+ kind: 'option',
130
+ name: longOption,
131
+ rawName: arg,
132
+ index,
133
+ value: undefined,
134
+ inlineValue: undefined
135
+ });
136
+ continue;
137
+ }
138
+ if (isLongOptionAndValue(arg)) {
139
+ // e.g. `--foo=bar`
140
+ const equalIndex = arg.indexOf(EQUAL_CHAR);
141
+ const longOption = arg.slice(2, equalIndex);
142
+ const value = arg.slice(equalIndex + 1);
143
+ tokens.push({
144
+ kind: 'option',
145
+ name: longOption,
146
+ rawName: `${LONG_OPTION_PREFIX}${longOption}`,
147
+ index,
148
+ value,
149
+ inlineValue: true
150
+ });
151
+ continue;
152
+ }
153
+ tokens.push({
154
+ kind: 'positional',
155
+ index,
156
+ value: arg
157
+ });
158
+ }
159
+ return tokens;
160
+ }
161
+ /**
162
+ * Check if `arg` is a short option (e.g. `-f`)
163
+ * @param arg the argument to check
164
+ * @returns whether `arg` is a short option
165
+ */
166
+ function isShortOption(arg) {
167
+ return (arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE);
168
+ }
169
+ /**
170
+ * Check if `arg` is a short option group (e.g. `-abc`)
171
+ * @param arg the argument to check
172
+ * @returns whether `arg` is a short option group
173
+ */
174
+ function isShortOptionGroup(arg) {
175
+ if (arg.length <= 2) {
176
+ return false;
177
+ }
178
+ if (arg.codePointAt(0) !== HYPHEN_CODE) {
179
+ return false;
180
+ }
181
+ if (arg.codePointAt(1) === HYPHEN_CODE) {
182
+ return false;
183
+ }
184
+ return true;
185
+ }
186
+ /**
187
+ * Check if `arg` is a long option (e.g. `--foo`)
188
+ * @param arg the argument to check
189
+ * @returns whether `arg` is a long option
190
+ */
191
+ function isLongOption(arg) {
192
+ return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
193
+ }
194
+ /**
195
+ * Check if `arg` is a long option with value (e.g. `--foo=bar`)
196
+ * @param arg the argument to check
197
+ * @returns whether `arg` is a long option
198
+ */
199
+ function isLongOptionAndValue(arg) {
200
+ return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
201
+ }
202
+ /**
203
+ * Check if `arg` is a long option prefix (e.g. `--`)
204
+ * @param arg the argument to check
205
+ * @returns whether `arg` is a long option prefix
206
+ */
207
+ function hasLongOptionPrefix(arg) {
208
+ return arg.length > 2 && ~arg.indexOf(LONG_OPTION_PREFIX);
209
+ }
210
+ /**
211
+ * Check if a `value` is an option value
212
+ * @param value a value to check
213
+ * @returns whether a `value` is an option value
214
+ */
215
+ function hasOptionValue(value) {
216
+ // eslint-disable-next-line unicorn/no-null
217
+ return !(value == null) && value.codePointAt(0) !== HYPHEN_CODE;
6
218
  }
@@ -1 +1,27 @@
1
- export declare function add(a: number, b: number): number;
1
+ type ArgTokenKind = 'option' | 'option-terminator' | 'positional';
2
+ export interface ArgToken {
3
+ kind: ArgTokenKind;
4
+ index: number;
5
+ name?: string;
6
+ rawName?: string;
7
+ value?: string;
8
+ inlineValue?: boolean;
9
+ }
10
+ /**
11
+ * Parse Options
12
+ */
13
+ export interface ParseOptions {
14
+ /**
15
+ * [Node.js parseArgs](https://nodejs.org/api/util.html#parseargs-tokens) tokens compatible mode
16
+ * @default false
17
+ */
18
+ allowCompatible?: boolean;
19
+ }
20
+ /**
21
+ * Parse command line arguments
22
+ * @param args command line arguments
23
+ * @param options parse options
24
+ * @returns argument tokens
25
+ */
26
+ export declare function parseArgs(args: string[], options?: ParseOptions): ArgToken[];
27
+ export {};
package/lib/esm/index.js CHANGED
@@ -1,3 +1,215 @@
1
- export function add(a, b) {
2
- return a + b;
1
+ // SPDX-License-Identifier: MIT
2
+ // Modifier: kazuya kawaguchi (a.k.a. kazupon)
3
+ // Forked from `nodejs/node` (`pkgjs/parseargs`)
4
+ // Repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
5
+ // Author: Node.js contributors
6
+ // Code url: https://github.com/nodejs/node/blob/main/lib/internal/util/parse_args/parse_args.js
7
+ const HYPHEN_CHAR = '-';
8
+ const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
9
+ const EQUAL_CHAR = '=';
10
+ const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
11
+ const TERMINATOR = '--';
12
+ const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
13
+ const LONG_OPTION_PREFIX = '--';
14
+ /**
15
+ * Parse command line arguments
16
+ * @param args command line arguments
17
+ * @param options parse options
18
+ * @returns argument tokens
19
+ */
20
+ export function parseArgs(args, options = {}) {
21
+ const { allowCompatible = false } = options;
22
+ const tokens = [];
23
+ const remainings = [...args];
24
+ let index = -1;
25
+ let groupCount = 0;
26
+ let hasShortValueSeparator = false;
27
+ while (remainings.length > 0) {
28
+ const arg = remainings.shift();
29
+ if (arg == undefined) {
30
+ break;
31
+ }
32
+ const nextArg = remainings[0];
33
+ if (groupCount > 0) {
34
+ groupCount--;
35
+ }
36
+ else {
37
+ index++;
38
+ }
39
+ // check if `arg` is an options terminator.
40
+ // guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
41
+ if (arg === TERMINATOR) {
42
+ tokens.push({
43
+ kind: 'option-terminator',
44
+ index
45
+ });
46
+ const mapped = remainings.map(arg => {
47
+ return { kind: 'positional', index: ++index, value: arg };
48
+ });
49
+ tokens.push(...mapped);
50
+ break;
51
+ }
52
+ if (isShortOption(arg)) {
53
+ const shortOption = arg.charAt(1);
54
+ let value;
55
+ let inlineValue;
56
+ if (groupCount) {
57
+ // e.g. `-abc`
58
+ tokens.push({
59
+ kind: 'option',
60
+ name: shortOption,
61
+ rawName: arg,
62
+ index,
63
+ value,
64
+ inlineValue
65
+ });
66
+ if (groupCount === 1 && hasOptionValue(nextArg)) {
67
+ value = remainings.shift();
68
+ if (hasShortValueSeparator) {
69
+ inlineValue = true;
70
+ hasShortValueSeparator = false;
71
+ }
72
+ tokens.push({
73
+ kind: 'option',
74
+ index,
75
+ value,
76
+ inlineValue
77
+ });
78
+ }
79
+ }
80
+ else {
81
+ // e.g. `-a`
82
+ tokens.push({
83
+ kind: 'option',
84
+ name: shortOption,
85
+ rawName: arg,
86
+ index,
87
+ value,
88
+ inlineValue
89
+ });
90
+ }
91
+ // eslint-disable-next-line unicorn/no-null
92
+ if (value != null) {
93
+ ++index;
94
+ }
95
+ continue;
96
+ }
97
+ if (isShortOptionGroup(arg)) {
98
+ // expend short option group (e.g. `-abc` => `-a -b -c`, `-f=bar` => `-f bar`)
99
+ const expanded = [];
100
+ let shortValue = '';
101
+ for (let i = 1; i < arg.length; i++) {
102
+ const shortableOption = arg.charAt(i);
103
+ if (hasShortValueSeparator) {
104
+ shortValue += shortableOption;
105
+ }
106
+ else {
107
+ if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE) {
108
+ hasShortValueSeparator = true;
109
+ }
110
+ else {
111
+ expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
112
+ }
113
+ }
114
+ }
115
+ if (shortValue) {
116
+ expanded.push(shortValue);
117
+ }
118
+ remainings.unshift(...expanded);
119
+ groupCount = expanded.length;
120
+ continue;
121
+ }
122
+ if (isLongOption(arg)) {
123
+ // e.g. `--foo`
124
+ const longOption = arg.slice(2);
125
+ tokens.push({
126
+ kind: 'option',
127
+ name: longOption,
128
+ rawName: arg,
129
+ index,
130
+ value: undefined,
131
+ inlineValue: undefined
132
+ });
133
+ continue;
134
+ }
135
+ if (isLongOptionAndValue(arg)) {
136
+ // e.g. `--foo=bar`
137
+ const equalIndex = arg.indexOf(EQUAL_CHAR);
138
+ const longOption = arg.slice(2, equalIndex);
139
+ const value = arg.slice(equalIndex + 1);
140
+ tokens.push({
141
+ kind: 'option',
142
+ name: longOption,
143
+ rawName: `${LONG_OPTION_PREFIX}${longOption}`,
144
+ index,
145
+ value,
146
+ inlineValue: true
147
+ });
148
+ continue;
149
+ }
150
+ tokens.push({
151
+ kind: 'positional',
152
+ index,
153
+ value: arg
154
+ });
155
+ }
156
+ return tokens;
157
+ }
158
+ /**
159
+ * Check if `arg` is a short option (e.g. `-f`)
160
+ * @param arg the argument to check
161
+ * @returns whether `arg` is a short option
162
+ */
163
+ function isShortOption(arg) {
164
+ return (arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE);
165
+ }
166
+ /**
167
+ * Check if `arg` is a short option group (e.g. `-abc`)
168
+ * @param arg the argument to check
169
+ * @returns whether `arg` is a short option group
170
+ */
171
+ function isShortOptionGroup(arg) {
172
+ if (arg.length <= 2) {
173
+ return false;
174
+ }
175
+ if (arg.codePointAt(0) !== HYPHEN_CODE) {
176
+ return false;
177
+ }
178
+ if (arg.codePointAt(1) === HYPHEN_CODE) {
179
+ return false;
180
+ }
181
+ return true;
182
+ }
183
+ /**
184
+ * Check if `arg` is a long option (e.g. `--foo`)
185
+ * @param arg the argument to check
186
+ * @returns whether `arg` is a long option
187
+ */
188
+ function isLongOption(arg) {
189
+ return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
190
+ }
191
+ /**
192
+ * Check if `arg` is a long option with value (e.g. `--foo=bar`)
193
+ * @param arg the argument to check
194
+ * @returns whether `arg` is a long option
195
+ */
196
+ function isLongOptionAndValue(arg) {
197
+ return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
198
+ }
199
+ /**
200
+ * Check if `arg` is a long option prefix (e.g. `--`)
201
+ * @param arg the argument to check
202
+ * @returns whether `arg` is a long option prefix
203
+ */
204
+ function hasLongOptionPrefix(arg) {
205
+ return arg.length > 2 && ~arg.indexOf(LONG_OPTION_PREFIX);
206
+ }
207
+ /**
208
+ * Check if a `value` is an option value
209
+ * @param value a value to check
210
+ * @returns whether a `value` is an option value
211
+ */
212
+ function hasOptionValue(value) {
213
+ // eslint-disable-next-line unicorn/no-null
214
+ return !(value == null) && value.codePointAt(0) !== HYPHEN_CODE;
3
215
  }
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.0.0",
4
+ "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -28,6 +28,7 @@
28
28
  "engines": {
29
29
  "node": ">= 18.18"
30
30
  },
31
+ "type": "module",
31
32
  "files": [
32
33
  "lib"
33
34
  ],
@@ -70,6 +71,7 @@
70
71
  "gh-changelogen": "^0.2.8",
71
72
  "knip": "^5.44.0",
72
73
  "lint-staged": "^15.4.3",
74
+ "mitata": "^1.0.34",
73
75
  "pkg-pr-new": "^0.0.39",
74
76
  "prettier": "^3.5.0",
75
77
  "typescript": "^5.7.3",
@@ -91,6 +93,8 @@
91
93
  ]
92
94
  },
93
95
  "scripts": {
96
+ "bench:mitata": "node --expose-gc bench/index.mjs",
97
+ "bench:vitest": "vitest bench --run",
94
98
  "build": "pnpm run --parallel --color \"/^build:/\"",
95
99
  "build:cjs": "tsc -p ./tsconfig.cjs.json",
96
100
  "build:esm": "tsc -p ./tsconfig.esm.json",