args-tokens 0.2.2 → 0.2.4

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
@@ -126,9 +126,7 @@ console.log(tokens)
126
126
  // ]
127
127
  ```
128
128
 
129
- ## 🚀 Usage
130
-
131
- ### 💿 Installation
129
+ ## 💿 Installation
132
130
 
133
131
  ```sh
134
132
  # npm
@@ -141,10 +139,23 @@ yarn add args-tokens
141
139
  pnpm add args-tokens
142
140
  ```
143
141
 
144
- ### 🍭 Codes
142
+ ### 🦕 Deno
143
+
144
+ ```sh
145
+ deno add jsr:@kazupon/args-tokens
146
+ ```
147
+
148
+ ### 🥟 Bun
149
+
150
+ ```sh
151
+ bun add args-tokens
152
+ ```
153
+
154
+ ## 🚀 Usage
145
155
 
146
156
  ```js
147
- import { parseArgs } from 'args-tokens'
157
+ import { parseArgs } from 'args-tokens' // for Node.js and Bun
158
+ // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
148
159
 
149
160
  const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
150
161
  // do something with using tokens
@@ -0,0 +1,27 @@
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 {};
@@ -0,0 +1,218 @@
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
8
+ Object.defineProperty(exports, "__esModule", { value: true });
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;
218
+ }
@@ -0,0 +1,27 @@
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 {};
@@ -0,0 +1,215 @@
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;
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.2.2",
4
+ "version": "0.2.4",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"