argot-cli 0.0.0-stage → 0.4.0-beta.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/CHANGELOG.md +14 -0
- package/LICENSE +13 -0
- package/README.md +2 -2
- package/argot-cli-0.4.0-beta.1.tgz +0 -0
- package/dist/arg_parser.d.ts +60 -0
- package/dist/arg_parser.js +557 -0
- package/dist/errors.d.ts +172 -0
- package/dist/errors.js +246 -0
- package/dist/mod.d.ts +49 -0
- package/dist/mod.js +48 -0
- package/dist/parser_config.d.ts +23 -0
- package/dist/parser_config.js +83 -0
- package/dist/read_config.d.ts +7 -0
- package/dist/read_config.js +12 -0
- package/dist/types.d.ts +185 -0
- package/dist/types.js +112 -0
- package/dist/utils.d.ts +48 -0
- package/dist/utils.js +175 -0
- package/package.json +23 -4
- package/src/arg_parser.ts +586 -0
- package/src/errors.ts +272 -0
- package/src/mod.ts +49 -0
- package/src/parser_config.ts +104 -0
- package/src/read_config.ts +14 -0
- package/src/types.ts +262 -0
- package/src/utils.ts +219 -0
- package/tsconfig.json +35 -0
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime error.
|
|
3
|
+
* Represents errors that occur while parsing input arguments.
|
|
4
|
+
* These errors are triggered by invalid or unexpected user input,
|
|
5
|
+
* such as unknown options, missing values, or values of the wrong type.
|
|
6
|
+
* Runtime errors are produced during the execution of the `.parse()`
|
|
7
|
+
* method and depend on the provided input rather than the parser
|
|
8
|
+
* configuration.
|
|
9
|
+
*/
|
|
10
|
+
export declare class RuntimeError extends Error {
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Configuration error.
|
|
14
|
+
* Represents errors caused by an invalid parser configuration.
|
|
15
|
+
* These errors occur when defining or initializing the parser,
|
|
16
|
+
* such as using unsupported option types or referencing invalid
|
|
17
|
+
* alias targets.
|
|
18
|
+
* Configuration errors are independent of user input and are
|
|
19
|
+
* typically raised before any parsing takes place.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ConfigError extends Error {
|
|
22
|
+
private _errors;
|
|
23
|
+
push(error: Error): void;
|
|
24
|
+
get errors(): Error[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Invalid integer argument error.
|
|
28
|
+
* Raised when an option of type "int" is provided with an associated
|
|
29
|
+
* value that cannot be parsed as an integer.
|
|
30
|
+
* This error only applies when a value is present. Missing values are
|
|
31
|
+
* reported using NullIntError.
|
|
32
|
+
*/
|
|
33
|
+
export declare class InvalidIntError extends RuntimeError {
|
|
34
|
+
value: string;
|
|
35
|
+
constructor(value: string);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Invalid float argument error.
|
|
39
|
+
* Raised when an option of type "float" is provided with an associated
|
|
40
|
+
* value that cannot be parsed as a number.
|
|
41
|
+
* This error only applies when a value is present. Missing values are
|
|
42
|
+
* reported using NullFloatError.
|
|
43
|
+
*/
|
|
44
|
+
export declare class InvalidFloatError extends RuntimeError {
|
|
45
|
+
value: string;
|
|
46
|
+
constructor(value: string);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Unsafe integer error.
|
|
50
|
+
* Raised when a parsed integer cannot be safely represented
|
|
51
|
+
* by the underlying runtime.
|
|
52
|
+
* This error only applies to values that are successfully parsed
|
|
53
|
+
* as integers.
|
|
54
|
+
*/
|
|
55
|
+
export declare class UnsafeIntegerError extends RuntimeError {
|
|
56
|
+
value: number;
|
|
57
|
+
constructor(value: number);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Missing argument error.
|
|
61
|
+
* Raised when an option that requires an associated value is provided
|
|
62
|
+
* without one.
|
|
63
|
+
* If the option is an alias, the error message includes both the
|
|
64
|
+
* alias name and its target.
|
|
65
|
+
*/
|
|
66
|
+
export declare class NullArgError extends RuntimeError {
|
|
67
|
+
option: string;
|
|
68
|
+
target?: string;
|
|
69
|
+
constructor(name: string, target?: string);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Missing integer argument error.
|
|
73
|
+
* Raised when an option of type "int" is provided without an
|
|
74
|
+
* associated value.
|
|
75
|
+
* This error does not cover invalid integer values. Invalid values
|
|
76
|
+
* are reported using InvalidIntError.
|
|
77
|
+
* If the option is an alias, the error message includes both the
|
|
78
|
+
* alias name and its target.
|
|
79
|
+
*/
|
|
80
|
+
export declare class NullIntError extends RuntimeError {
|
|
81
|
+
option: string;
|
|
82
|
+
target?: string;
|
|
83
|
+
constructor(name: string, target?: string);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Missing float argument error.
|
|
87
|
+
* Raised when an option of type "float" is provided without an
|
|
88
|
+
* associated value.
|
|
89
|
+
* This error does not cover invalid float values. Invalid values
|
|
90
|
+
* are reported using InvalidFloatError.
|
|
91
|
+
* If the option is an alias, the error message includes both the
|
|
92
|
+
* alias name and its target.
|
|
93
|
+
*/
|
|
94
|
+
export declare class NullFloatError extends RuntimeError {
|
|
95
|
+
option: string;
|
|
96
|
+
target?: string;
|
|
97
|
+
constructor(name: string, target?: string);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Unknown option error.
|
|
101
|
+
* Raised when an input contains an option that is not defined in the
|
|
102
|
+
* parser configuration.
|
|
103
|
+
* This applies to both long and short options. The error is triggered
|
|
104
|
+
* as soon as the parser encounters an unrecognized option name.
|
|
105
|
+
*/
|
|
106
|
+
export declare class UnknownOptionError extends RuntimeError {
|
|
107
|
+
option: string;
|
|
108
|
+
constructor(name: string);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Invalid option type error.
|
|
112
|
+
* Raised when an option is declared with a type that is not supported
|
|
113
|
+
* by the parser.
|
|
114
|
+
* This is a configuration error and typically occurs during parser
|
|
115
|
+
* initialization rather than at parse time.
|
|
116
|
+
*/
|
|
117
|
+
export declare class InvalidOptionTypeError extends ConfigError {
|
|
118
|
+
type: string;
|
|
119
|
+
constructor(tag: string);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Alias target not found error.
|
|
123
|
+
* Raised when an alias references a target option that does not exist
|
|
124
|
+
* in the parser configuration.
|
|
125
|
+
* This is a configuration error and indicates that the alias points
|
|
126
|
+
* to an undefined option.
|
|
127
|
+
*/
|
|
128
|
+
export declare class AliasTargetNotFoundError extends ConfigError {
|
|
129
|
+
option: string;
|
|
130
|
+
target: string;
|
|
131
|
+
constructor(name: string, target: string);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Invalid alias target error.
|
|
135
|
+
* Raised when an alias references a target that is not a valid option
|
|
136
|
+
* for aliasing.
|
|
137
|
+
* This may occur if the target is itself an alias (when alias chaining
|
|
138
|
+
* is not supported) or if the target cannot accept the alias due to
|
|
139
|
+
* type or configuration constraints.
|
|
140
|
+
*/
|
|
141
|
+
export declare class InvalidAliasTargetError extends ConfigError {
|
|
142
|
+
option: string;
|
|
143
|
+
target: string;
|
|
144
|
+
constructor(name: string, target: string);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Missing option property error.
|
|
148
|
+
* Raised when an option entry in the parser configuration is missing
|
|
149
|
+
* one or more required properties.
|
|
150
|
+
* This is a configuration error and indicates that the option
|
|
151
|
+
* definition is incomplete or malformed.
|
|
152
|
+
* Implementations may include the option name and the missing
|
|
153
|
+
* property name to aid debugging.
|
|
154
|
+
*/
|
|
155
|
+
export declare class MissingOptionPropertyError extends ConfigError {
|
|
156
|
+
option: string;
|
|
157
|
+
property: string;
|
|
158
|
+
constructor(option: string, property: string);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Missing option type error.
|
|
162
|
+
* Raised when a configuration entry does not define a "type" property.
|
|
163
|
+
* The "type" property is required for all option entries and determines
|
|
164
|
+
* how the option is parsed and validated. Without it, the entry cannot
|
|
165
|
+
* be interpreted by the parser.
|
|
166
|
+
* This is a configuration error and is typically raised during
|
|
167
|
+
* configuration validation.
|
|
168
|
+
*/
|
|
169
|
+
export declare class MissingOptionTypeError extends ConfigError {
|
|
170
|
+
option: string;
|
|
171
|
+
constructor(name: string);
|
|
172
|
+
}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime error.
|
|
3
|
+
* Represents errors that occur while parsing input arguments.
|
|
4
|
+
* These errors are triggered by invalid or unexpected user input,
|
|
5
|
+
* such as unknown options, missing values, or values of the wrong type.
|
|
6
|
+
* Runtime errors are produced during the execution of the `.parse()`
|
|
7
|
+
* method and depend on the provided input rather than the parser
|
|
8
|
+
* configuration.
|
|
9
|
+
*/
|
|
10
|
+
export class RuntimeError extends Error {
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Configuration error.
|
|
14
|
+
* Represents errors caused by an invalid parser configuration.
|
|
15
|
+
* These errors occur when defining or initializing the parser,
|
|
16
|
+
* such as using unsupported option types or referencing invalid
|
|
17
|
+
* alias targets.
|
|
18
|
+
* Configuration errors are independent of user input and are
|
|
19
|
+
* typically raised before any parsing takes place.
|
|
20
|
+
*/
|
|
21
|
+
export class ConfigError extends Error {
|
|
22
|
+
_errors = [];
|
|
23
|
+
push(error) {
|
|
24
|
+
this._errors.push(error);
|
|
25
|
+
}
|
|
26
|
+
get errors() {
|
|
27
|
+
return this._errors;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Invalid integer argument error.
|
|
32
|
+
* Raised when an option of type "int" is provided with an associated
|
|
33
|
+
* value that cannot be parsed as an integer.
|
|
34
|
+
* This error only applies when a value is present. Missing values are
|
|
35
|
+
* reported using NullIntError.
|
|
36
|
+
*/
|
|
37
|
+
export class InvalidIntError extends RuntimeError {
|
|
38
|
+
value;
|
|
39
|
+
constructor(value) {
|
|
40
|
+
super(`'${value}' is not a valid integer`);
|
|
41
|
+
this.value = value;
|
|
42
|
+
Object.freeze(this);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Invalid float argument error.
|
|
47
|
+
* Raised when an option of type "float" is provided with an associated
|
|
48
|
+
* value that cannot be parsed as a number.
|
|
49
|
+
* This error only applies when a value is present. Missing values are
|
|
50
|
+
* reported using NullFloatError.
|
|
51
|
+
*/
|
|
52
|
+
export class InvalidFloatError extends RuntimeError {
|
|
53
|
+
value;
|
|
54
|
+
constructor(value) {
|
|
55
|
+
super(`'${value}' is not a valid integer`);
|
|
56
|
+
this.value = value;
|
|
57
|
+
Object.freeze(this);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Unsafe integer error.
|
|
62
|
+
* Raised when a parsed integer cannot be safely represented
|
|
63
|
+
* by the underlying runtime.
|
|
64
|
+
* This error only applies to values that are successfully parsed
|
|
65
|
+
* as integers.
|
|
66
|
+
*/
|
|
67
|
+
export class UnsafeIntegerError extends RuntimeError {
|
|
68
|
+
value;
|
|
69
|
+
constructor(value) {
|
|
70
|
+
super(`${value} is not a safe integer`);
|
|
71
|
+
this.value = value;
|
|
72
|
+
Object.freeze(this);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Missing argument error.
|
|
77
|
+
* Raised when an option that requires an associated value is provided
|
|
78
|
+
* without one.
|
|
79
|
+
* If the option is an alias, the error message includes both the
|
|
80
|
+
* alias name and its target.
|
|
81
|
+
*/
|
|
82
|
+
export class NullArgError extends RuntimeError {
|
|
83
|
+
option;
|
|
84
|
+
target;
|
|
85
|
+
constructor(name, target) {
|
|
86
|
+
const msg = target
|
|
87
|
+
? `option '${name}' (alias for '${target}') must take an argument`
|
|
88
|
+
: `option '${name}' must take an argument`;
|
|
89
|
+
super(msg);
|
|
90
|
+
this.option = name;
|
|
91
|
+
if (target) {
|
|
92
|
+
this.target = target;
|
|
93
|
+
}
|
|
94
|
+
Object.freeze(this);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Missing integer argument error.
|
|
99
|
+
* Raised when an option of type "int" is provided without an
|
|
100
|
+
* associated value.
|
|
101
|
+
* This error does not cover invalid integer values. Invalid values
|
|
102
|
+
* are reported using InvalidIntError.
|
|
103
|
+
* If the option is an alias, the error message includes both the
|
|
104
|
+
* alias name and its target.
|
|
105
|
+
*/
|
|
106
|
+
export class NullIntError extends RuntimeError {
|
|
107
|
+
option;
|
|
108
|
+
target;
|
|
109
|
+
constructor(name, target) {
|
|
110
|
+
const msg = target
|
|
111
|
+
? `option '${name}' (alias for '${target}') requires an integer number argument`
|
|
112
|
+
: `option '${name}' requires an integer number argument`;
|
|
113
|
+
super(msg);
|
|
114
|
+
this.option = name;
|
|
115
|
+
if (target) {
|
|
116
|
+
this.target = target;
|
|
117
|
+
}
|
|
118
|
+
Object.freeze(this);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Missing float argument error.
|
|
123
|
+
* Raised when an option of type "float" is provided without an
|
|
124
|
+
* associated value.
|
|
125
|
+
* This error does not cover invalid float values. Invalid values
|
|
126
|
+
* are reported using InvalidFloatError.
|
|
127
|
+
* If the option is an alias, the error message includes both the
|
|
128
|
+
* alias name and its target.
|
|
129
|
+
*/
|
|
130
|
+
export class NullFloatError extends RuntimeError {
|
|
131
|
+
option;
|
|
132
|
+
target;
|
|
133
|
+
constructor(name, target) {
|
|
134
|
+
const msg = target
|
|
135
|
+
? `option '${name}' (alias for '${target}') requires a numeric argument`
|
|
136
|
+
: `option '${name}' requires a numeric argument`;
|
|
137
|
+
super(msg);
|
|
138
|
+
this.option = name;
|
|
139
|
+
if (target) {
|
|
140
|
+
this.target = target;
|
|
141
|
+
}
|
|
142
|
+
Object.freeze(this);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Unknown option error.
|
|
147
|
+
* Raised when an input contains an option that is not defined in the
|
|
148
|
+
* parser configuration.
|
|
149
|
+
* This applies to both long and short options. The error is triggered
|
|
150
|
+
* as soon as the parser encounters an unrecognized option name.
|
|
151
|
+
*/
|
|
152
|
+
export class UnknownOptionError extends RuntimeError {
|
|
153
|
+
option;
|
|
154
|
+
constructor(name) {
|
|
155
|
+
super(`option '${name}' is not supported`);
|
|
156
|
+
this.option = name;
|
|
157
|
+
Object.freeze(this);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Invalid option type error.
|
|
162
|
+
* Raised when an option is declared with a type that is not supported
|
|
163
|
+
* by the parser.
|
|
164
|
+
* This is a configuration error and typically occurs during parser
|
|
165
|
+
* initialization rather than at parse time.
|
|
166
|
+
*/
|
|
167
|
+
export class InvalidOptionTypeError extends ConfigError {
|
|
168
|
+
type;
|
|
169
|
+
constructor(tag) {
|
|
170
|
+
super(`option type '${tag}' is not supported`);
|
|
171
|
+
this.type = tag;
|
|
172
|
+
Object.freeze(this);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Alias target not found error.
|
|
177
|
+
* Raised when an alias references a target option that does not exist
|
|
178
|
+
* in the parser configuration.
|
|
179
|
+
* This is a configuration error and indicates that the alias points
|
|
180
|
+
* to an undefined option.
|
|
181
|
+
*/
|
|
182
|
+
export class AliasTargetNotFoundError extends ConfigError {
|
|
183
|
+
option;
|
|
184
|
+
target;
|
|
185
|
+
constructor(name, target) {
|
|
186
|
+
super(`target value '${target}' for option '${name}' was not found`);
|
|
187
|
+
this.option = name;
|
|
188
|
+
this.target = target;
|
|
189
|
+
Object.freeze(this);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Invalid alias target error.
|
|
194
|
+
* Raised when an alias references a target that is not a valid option
|
|
195
|
+
* for aliasing.
|
|
196
|
+
* This may occur if the target is itself an alias (when alias chaining
|
|
197
|
+
* is not supported) or if the target cannot accept the alias due to
|
|
198
|
+
* type or configuration constraints.
|
|
199
|
+
*/
|
|
200
|
+
export class InvalidAliasTargetError extends ConfigError {
|
|
201
|
+
option;
|
|
202
|
+
target;
|
|
203
|
+
constructor(name, target) {
|
|
204
|
+
super(`cannot create an alias to another alias (${name} => ${target})`);
|
|
205
|
+
this.option = name;
|
|
206
|
+
this.target = target;
|
|
207
|
+
Object.freeze(this);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Missing option property error.
|
|
212
|
+
* Raised when an option entry in the parser configuration is missing
|
|
213
|
+
* one or more required properties.
|
|
214
|
+
* This is a configuration error and indicates that the option
|
|
215
|
+
* definition is incomplete or malformed.
|
|
216
|
+
* Implementations may include the option name and the missing
|
|
217
|
+
* property name to aid debugging.
|
|
218
|
+
*/
|
|
219
|
+
export class MissingOptionPropertyError extends ConfigError {
|
|
220
|
+
option;
|
|
221
|
+
property;
|
|
222
|
+
constructor(option, property) {
|
|
223
|
+
super(`option '${option}' is missing required property '${property}'`);
|
|
224
|
+
this.option = option;
|
|
225
|
+
this.property = property;
|
|
226
|
+
Object.freeze(this);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Missing option type error.
|
|
231
|
+
* Raised when a configuration entry does not define a "type" property.
|
|
232
|
+
* The "type" property is required for all option entries and determines
|
|
233
|
+
* how the option is parsed and validated. Without it, the entry cannot
|
|
234
|
+
* be interpreted by the parser.
|
|
235
|
+
* This is a configuration error and is typically raised during
|
|
236
|
+
* configuration validation.
|
|
237
|
+
*/
|
|
238
|
+
export class MissingOptionTypeError extends ConfigError {
|
|
239
|
+
option;
|
|
240
|
+
constructor(name) {
|
|
241
|
+
const msg = `option '${name}' is missing required property 'type'`;
|
|
242
|
+
super(msg);
|
|
243
|
+
this.option = name;
|
|
244
|
+
Object.freeze(this);
|
|
245
|
+
}
|
|
246
|
+
}
|
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argot CLI argument parser.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a schema-based command-line argument parser.
|
|
5
|
+
* The parser processes an array of strings and produces a structured
|
|
6
|
+
* result containing options, parameters, and operands.
|
|
7
|
+
*
|
|
8
|
+
* Parsing behavior is fully determined by a configuration object.
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import {
|
|
14
|
+
* ArgParser,
|
|
15
|
+
* ParserConfig,
|
|
16
|
+
* type ConfigEntries,
|
|
17
|
+
* } from '@argot-cli/argot';
|
|
18
|
+
*
|
|
19
|
+
* const entries: ConfigEntries = {
|
|
20
|
+
* verbose: { type: 'flag' },
|
|
21
|
+
* count: { type: 'int' },
|
|
22
|
+
* name: { type: 'text', default: 'world' },
|
|
23
|
+
* };
|
|
24
|
+
*
|
|
25
|
+
* const config = new ParserConfig(entries);
|
|
26
|
+
*
|
|
27
|
+
* const parser = new ArgParser(config);
|
|
28
|
+
*
|
|
29
|
+
* const result = parser.parse([
|
|
30
|
+
* '--verbose',
|
|
31
|
+
* '--count=3',
|
|
32
|
+
* 'mode=fast',
|
|
33
|
+
* 'file.txt',
|
|
34
|
+
* ]);
|
|
35
|
+
*
|
|
36
|
+
* console.log(result.options.get('verbose')); // true
|
|
37
|
+
* console.log(result.options.get('count')); // 3
|
|
38
|
+
* console.log(result.options.get('name')); // "world"
|
|
39
|
+
*
|
|
40
|
+
* console.log(result.parameters.get('mode')); // "fast"
|
|
41
|
+
*
|
|
42
|
+
* console.log(result.operands); // ["file.txt"]
|
|
43
|
+
* ```
|
|
44
|
+
* @module
|
|
45
|
+
*/
|
|
46
|
+
export { ArgParser } from './arg_parser.ts';
|
|
47
|
+
export { ParserConfig } from './parser_config.ts';
|
|
48
|
+
export { readJSONConfig } from './read_config.ts';
|
|
49
|
+
export type { ConfigEntry, ConfigEntries } from './types.ts';
|
package/dist/mod.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argot CLI argument parser.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a schema-based command-line argument parser.
|
|
5
|
+
* The parser processes an array of strings and produces a structured
|
|
6
|
+
* result containing options, parameters, and operands.
|
|
7
|
+
*
|
|
8
|
+
* Parsing behavior is fully determined by a configuration object.
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import {
|
|
14
|
+
* ArgParser,
|
|
15
|
+
* ParserConfig,
|
|
16
|
+
* type ConfigEntries,
|
|
17
|
+
* } from '@argot-cli/argot';
|
|
18
|
+
*
|
|
19
|
+
* const entries: ConfigEntries = {
|
|
20
|
+
* verbose: { type: 'flag' },
|
|
21
|
+
* count: { type: 'int' },
|
|
22
|
+
* name: { type: 'text', default: 'world' },
|
|
23
|
+
* };
|
|
24
|
+
*
|
|
25
|
+
* const config = new ParserConfig(entries);
|
|
26
|
+
*
|
|
27
|
+
* const parser = new ArgParser(config);
|
|
28
|
+
*
|
|
29
|
+
* const result = parser.parse([
|
|
30
|
+
* '--verbose',
|
|
31
|
+
* '--count=3',
|
|
32
|
+
* 'mode=fast',
|
|
33
|
+
* 'file.txt',
|
|
34
|
+
* ]);
|
|
35
|
+
*
|
|
36
|
+
* console.log(result.options.get('verbose')); // true
|
|
37
|
+
* console.log(result.options.get('count')); // 3
|
|
38
|
+
* console.log(result.options.get('name')); // "world"
|
|
39
|
+
*
|
|
40
|
+
* console.log(result.parameters.get('mode')); // "fast"
|
|
41
|
+
*
|
|
42
|
+
* console.log(result.operands); // ["file.txt"]
|
|
43
|
+
* ```
|
|
44
|
+
* @module
|
|
45
|
+
*/
|
|
46
|
+
export { ArgParser } from './arg_parser.js';
|
|
47
|
+
export { ParserConfig } from './parser_config.js';
|
|
48
|
+
export { readJSONConfig } from './read_config.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ConfigEntry, ParserConfigInput } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Immutable configuration for the argument parser.
|
|
4
|
+
* The configuration defines the set of supported options and their types.
|
|
5
|
+
* Entries are provided as an object mapping option names to configuration
|
|
6
|
+
* entries.
|
|
7
|
+
* The configuration is normalized and validated during construction.
|
|
8
|
+
* The resulting object is immutable.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ParserConfig {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(input: ParserConfigInput);
|
|
13
|
+
entries(): Iterable<[string, ConfigEntry]>;
|
|
14
|
+
get(key: string): ConfigEntry | undefined;
|
|
15
|
+
has(key: string): boolean;
|
|
16
|
+
keys(): Iterable<string>;
|
|
17
|
+
values(): Iterable<ConfigEntry>;
|
|
18
|
+
toJSON(): ParserConfigInput;
|
|
19
|
+
get size(): number;
|
|
20
|
+
get allowUnknown(): boolean;
|
|
21
|
+
get parseParameters(): boolean;
|
|
22
|
+
get aggregateErrors(): boolean;
|
|
23
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { validateEntries, validateEntriesAggregate } from './utils.js';
|
|
2
|
+
function isObject(obj) {
|
|
3
|
+
if (Array.isArray(obj) || obj == null || typeof obj !== 'object')
|
|
4
|
+
return false;
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Immutable configuration for the argument parser.
|
|
9
|
+
* The configuration defines the set of supported options and their types.
|
|
10
|
+
* Entries are provided as an object mapping option names to configuration
|
|
11
|
+
* entries.
|
|
12
|
+
* The configuration is normalized and validated during construction.
|
|
13
|
+
* The resulting object is immutable.
|
|
14
|
+
*/
|
|
15
|
+
export class ParserConfig {
|
|
16
|
+
#entries;
|
|
17
|
+
#parser;
|
|
18
|
+
#size;
|
|
19
|
+
constructor(input) {
|
|
20
|
+
if (!isObject(input)) {
|
|
21
|
+
throw new TypeError('input value must be a plain object');
|
|
22
|
+
}
|
|
23
|
+
else if (!isObject(input.options)) {
|
|
24
|
+
throw new TypeError('"options" value must be a plain object');
|
|
25
|
+
}
|
|
26
|
+
else if (input.parser != null && !isObject(input.parser)) {
|
|
27
|
+
throw new TypeError('"parser" value must be a plain object');
|
|
28
|
+
}
|
|
29
|
+
const { options, parser } = input;
|
|
30
|
+
this.#parser = {
|
|
31
|
+
allowUnknown: parser?.allowUnknown ?? false,
|
|
32
|
+
parseParameters: parser?.parseParameters ?? true,
|
|
33
|
+
aggregateErrors: parser?.aggregateErrors ?? false,
|
|
34
|
+
};
|
|
35
|
+
this.#size = 0;
|
|
36
|
+
const entryMap = Object.create(null);
|
|
37
|
+
for (const [key, value] of Object.entries(options)) {
|
|
38
|
+
entryMap[key] = Object.freeze({ ...value });
|
|
39
|
+
this.#size += 1;
|
|
40
|
+
}
|
|
41
|
+
this.#entries = entryMap;
|
|
42
|
+
if (this.#parser.aggregateErrors)
|
|
43
|
+
validateEntriesAggregate(this.#entries);
|
|
44
|
+
else
|
|
45
|
+
validateEntries(this.#entries);
|
|
46
|
+
Object.freeze(this.#entries);
|
|
47
|
+
Object.freeze(this.#parser);
|
|
48
|
+
Object.freeze(this);
|
|
49
|
+
}
|
|
50
|
+
entries() {
|
|
51
|
+
return Object.entries(this.#entries);
|
|
52
|
+
}
|
|
53
|
+
get(key) {
|
|
54
|
+
return this.#entries[key];
|
|
55
|
+
}
|
|
56
|
+
has(key) {
|
|
57
|
+
return Object.hasOwn(this.#entries, key);
|
|
58
|
+
}
|
|
59
|
+
keys() {
|
|
60
|
+
return Object.keys(this.#entries);
|
|
61
|
+
}
|
|
62
|
+
values() {
|
|
63
|
+
return Object.values(this.#entries);
|
|
64
|
+
}
|
|
65
|
+
toJSON() {
|
|
66
|
+
return {
|
|
67
|
+
options: this.#entries,
|
|
68
|
+
parser: this.#parser,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
get size() {
|
|
72
|
+
return this.#size;
|
|
73
|
+
}
|
|
74
|
+
get allowUnknown() {
|
|
75
|
+
return this.#parser.allowUnknown;
|
|
76
|
+
}
|
|
77
|
+
get parseParameters() {
|
|
78
|
+
return this.#parser.parseParameters;
|
|
79
|
+
}
|
|
80
|
+
get aggregateErrors() {
|
|
81
|
+
return this.#parser.aggregateErrors;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ParserConfig } from './parser_config.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Reads a parser configuration from a JSON file.
|
|
4
|
+
* The file must contain a valid configuration object that can be
|
|
5
|
+
* passed to the ParserConfig constructor.
|
|
6
|
+
*/
|
|
7
|
+
export declare function readJSONConfig(configFile: string): ParserConfig;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { ParserConfig } from './parser_config.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reads a parser configuration from a JSON file.
|
|
5
|
+
* The file must contain a valid configuration object that can be
|
|
6
|
+
* passed to the ParserConfig constructor.
|
|
7
|
+
*/
|
|
8
|
+
export function readJSONConfig(configFile) {
|
|
9
|
+
const content = fs.readFileSync(configFile, { encoding: 'utf8' });
|
|
10
|
+
const configObj = JSON.parse(content);
|
|
11
|
+
return new ParserConfig(configObj);
|
|
12
|
+
}
|