@jakubmazanec/args 1.0.0-de51f16
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/LICENSE.md +18 -0
- package/README.md +84 -0
- package/dist/ParsingError.d.ts +4 -0
- package/dist/ParsingError.js +11 -0
- package/dist/ParsingError.js.map +1 -0
- package/dist/ValidationError.d.ts +4 -0
- package/dist/ValidationError.js +16 -0
- package/dist/ValidationError.js.map +1 -0
- package/dist/internals/Checker.d.ts +13 -0
- package/dist/internals/Checker.js +118 -0
- package/dist/internals/Checker.js.map +1 -0
- package/dist/internals/CommandScope.d.ts +14 -0
- package/dist/internals/CommandScope.js +48 -0
- package/dist/internals/CommandScope.js.map +1 -0
- package/dist/internals/OptionScope.d.ts +14 -0
- package/dist/internals/OptionScope.js +87 -0
- package/dist/internals/OptionScope.js.map +1 -0
- package/dist/internals/castValue.d.ts +7 -0
- package/dist/internals/castValue.js +25 -0
- package/dist/internals/castValue.js.map +1 -0
- package/dist/internals/commandToArguments.d.ts +7 -0
- package/dist/internals/commandToArguments.js +21 -0
- package/dist/internals/commandToArguments.js.map +1 -0
- package/dist/internals/createOptionShortNameMap.d.ts +2 -0
- package/dist/internals/createOptionShortNameMap.js +11 -0
- package/dist/internals/createOptionShortNameMap.js.map +1 -0
- package/dist/internals/expandArguments.d.ts +8 -0
- package/dist/internals/expandArguments.js +21 -0
- package/dist/internals/expandArguments.js.map +1 -0
- package/dist/internals/isCommand.d.ts +8 -0
- package/dist/internals/isCommand.js +11 -0
- package/dist/internals/isCommand.js.map +1 -0
- package/dist/internals/isFalseString.d.ts +6 -0
- package/dist/internals/isFalseString.js +10 -0
- package/dist/internals/isFalseString.js.map +1 -0
- package/dist/internals/isLongOption.d.ts +7 -0
- package/dist/internals/isLongOption.js +11 -0
- package/dist/internals/isLongOption.js.map +1 -0
- package/dist/internals/isOptionLike.d.ts +7 -0
- package/dist/internals/isOptionLike.js +11 -0
- package/dist/internals/isOptionLike.js.map +1 -0
- package/dist/internals/isShortOption.d.ts +7 -0
- package/dist/internals/isShortOption.js +11 -0
- package/dist/internals/isShortOption.js.map +1 -0
- package/dist/internals/isShortOptionsGroup.d.ts +8 -0
- package/dist/internals/isShortOptionsGroup.js +11 -0
- package/dist/internals/isShortOptionsGroup.js.map +1 -0
- package/dist/internals/isTrueString.d.ts +6 -0
- package/dist/internals/isTrueString.js +10 -0
- package/dist/internals/isTrueString.js.map +1 -0
- package/dist/internals.d.ts +14 -0
- package/dist/internals.js +16 -0
- package/dist/internals.js.map +1 -0
- package/dist/main.d.ts +4 -0
- package/dist/main.js +6 -0
- package/dist/main.js.map +1 -0
- package/dist/parseArguments.d.ts +10 -0
- package/dist/parseArguments.js +244 -0
- package/dist/parseArguments.js.map +1 -0
- package/dist/types/Arguments.d.ts +22 -0
- package/dist/types/Arguments.js +3 -0
- package/dist/types/Arguments.js.map +1 -0
- package/dist/types/ArgumentsCommand.d.ts +3 -0
- package/dist/types/ArgumentsCommand.js +3 -0
- package/dist/types/ArgumentsCommand.js.map +1 -0
- package/dist/types/ArgumentsOptions.d.ts +14 -0
- package/dist/types/ArgumentsOptions.js +3 -0
- package/dist/types/ArgumentsOptions.js.map +1 -0
- package/dist/types/ArgumentsParameters.d.ts +91 -0
- package/dist/types/ArgumentsParameters.js +3 -0
- package/dist/types/ArgumentsParameters.js.map +1 -0
- package/dist/types/ArgumentsUnknownOptions.d.ts +3 -0
- package/dist/types/ArgumentsUnknownOptions.js +3 -0
- package/dist/types/ArgumentsUnknownOptions.js.map +1 -0
- package/dist/types/Argv.d.ts +2 -0
- package/dist/types/Argv.js +3 -0
- package/dist/types/Argv.js.map +1 -0
- package/dist/types/CommandConfig.d.ts +2 -0
- package/dist/types/CommandConfig.js +3 -0
- package/dist/types/CommandConfig.js.map +1 -0
- package/dist/types/CommandsConfig.d.ts +3 -0
- package/dist/types/CommandsConfig.js +3 -0
- package/dist/types/CommandsConfig.js.map +1 -0
- package/dist/types/LongOptionName.d.ts +2 -0
- package/dist/types/LongOptionName.js +3 -0
- package/dist/types/LongOptionName.js.map +1 -0
- package/dist/types/NormalizedCommandConfig.d.ts +5 -0
- package/dist/types/NormalizedCommandConfig.js +3 -0
- package/dist/types/NormalizedCommandConfig.js.map +1 -0
- package/dist/types/NormalizedCommandsConfig.d.ts +3 -0
- package/dist/types/NormalizedCommandsConfig.js +3 -0
- package/dist/types/NormalizedCommandsConfig.js.map +1 -0
- package/dist/types/OptionConfig.d.ts +220 -0
- package/dist/types/OptionConfig.js +3 -0
- package/dist/types/OptionConfig.js.map +1 -0
- package/dist/types/OptionsConfig.d.ts +3 -0
- package/dist/types/OptionsConfig.js +3 -0
- package/dist/types/OptionsConfig.js.map +1 -0
- package/dist/types/ParameterConfig.d.ts +74 -0
- package/dist/types/ParameterConfig.js +3 -0
- package/dist/types/ParameterConfig.js.map +1 -0
- package/dist/types/ParametersConfig.d.ts +10 -0
- package/dist/types/ParametersConfig.js +3 -0
- package/dist/types/ParametersConfig.js.map +1 -0
- package/dist/types/ParserConfig.d.ts +16 -0
- package/dist/types/ParserConfig.js +3 -0
- package/dist/types/ParserConfig.js.map +1 -0
- package/dist/types/ShortOptionName.d.ts +2 -0
- package/dist/types/ShortOptionName.js +3 -0
- package/dist/types/ShortOptionName.js.map +1 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -0
- package/src/ParsingError.ts +11 -0
- package/src/ValidationError.ts +22 -0
- package/src/internals/Checker.ts +145 -0
- package/src/internals/CommandScope.ts +61 -0
- package/src/internals/OptionScope.ts +101 -0
- package/src/internals/castValue.ts +36 -0
- package/src/internals/commandToArguments.ts +22 -0
- package/src/internals/createOptionShortNameMap.ts +13 -0
- package/src/internals/expandArguments.ts +22 -0
- package/src/internals/isCommand.ts +11 -0
- package/src/internals/isFalseString.ts +10 -0
- package/src/internals/isLongOption.ts +11 -0
- package/src/internals/isOptionLike.ts +11 -0
- package/src/internals/isShortOption.ts +11 -0
- package/src/internals/isShortOptionsGroup.ts +11 -0
- package/src/internals/isTrueString.ts +10 -0
- package/src/internals.ts +14 -0
- package/src/main.ts +4 -0
- package/src/parseArguments.ts +358 -0
- package/src/types/Arguments.ts +28 -0
- package/src/types/ArgumentsCommand.ts +8 -0
- package/src/types/ArgumentsOptions.ts +89 -0
- package/src/types/ArgumentsParameters.ts +158 -0
- package/src/types/ArgumentsUnknownOptions.ts +6 -0
- package/src/types/Argv.ts +2 -0
- package/src/types/CommandConfig.ts +2 -0
- package/src/types/CommandsConfig.ts +4 -0
- package/src/types/LongOptionName.ts +2 -0
- package/src/types/NormalizedCommandConfig.ts +5 -0
- package/src/types/NormalizedCommandsConfig.ts +4 -0
- package/src/types/OptionConfig.ts +279 -0
- package/src/types/OptionsConfig.ts +4 -0
- package/src/types/ParameterConfig.ts +100 -0
- package/src/types/ParametersConfig.ts +17 -0
- package/src/types/ParserConfig.ts +21 -0
- package/src/types/ShortOptionName.ts +54 -0
- package/src/types.ts +17 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Jakub Mazanec
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
12
|
+
portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
|
17
|
+
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# @jakubmazanec/args
|
|
4
|
+
|
|
5
|
+
TypeScript-first library for parsing command line arguments.
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @jakubmazanec/args
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
⚠️ This is an [ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) package!
|
|
16
|
+
It cannot be required from a CommonJS module.
|
|
17
|
+
|
|
18
|
+
#### Prerequisites
|
|
19
|
+
|
|
20
|
+
- Node.js 16 or later
|
|
21
|
+
- TypeScript 5 or later
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
Main purpose of this library is to parse command line arguments. Such command line can look like
|
|
26
|
+
this:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
┌─ 1 ─┐ ┌─ 2 ──┐ ┌─── 3 ───┐ ┌─── 4 ───┐ ┌─ 5 ─┐ ┌ 6 ┐ ┌─── 7 ───┐ ┌─────── 8 ──────┐
|
|
30
|
+
binname do stuff --key value --key=value -key -K -aBDc foo bar baz -- --key value bar -B
|
|
31
|
+
└───────────────────────────────────────── 9 ──────────────────────────────────────────┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
1. Binary name. This is never passed to the parser.
|
|
35
|
+
2. Command name.
|
|
36
|
+
3. Option with a value. Option name can be in camel case or kebab case.
|
|
37
|
+
4. Another way to specify an option with a value.
|
|
38
|
+
5. Boolean options don't have to specify value to be true. Options can also be defined using a short
|
|
39
|
+
option form.
|
|
40
|
+
6. Short options group; usually used for boolean options.
|
|
41
|
+
7. Parameters.
|
|
42
|
+
8. Rest arguments appear after the `--`; they are not parsed, but still included in the result.
|
|
43
|
+
9. The whole command line.
|
|
44
|
+
|
|
45
|
+
The parser is strict and returns fully typed result. You can use it by calling `parseArguments`
|
|
46
|
+
function with the list of arguments and parser configuration:
|
|
47
|
+
|
|
48
|
+
```TypeScript
|
|
49
|
+
import {parseArguments} from '@jakubmazanec/args';
|
|
50
|
+
|
|
51
|
+
let {command, parameters, options} = parseArguments(process.argv.slice(2), {
|
|
52
|
+
commands: ['run', 'build'],
|
|
53
|
+
parameters: [{
|
|
54
|
+
description: 'File name',
|
|
55
|
+
type: 'string',
|
|
56
|
+
required: true,
|
|
57
|
+
}],
|
|
58
|
+
options: {
|
|
59
|
+
help: {
|
|
60
|
+
type: 'boolean'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
console.log(command); // type of `command` is `'run' | 'build' | undefined`
|
|
66
|
+
console.log(parameters); // type of `parameters` is `[string | undefined]`
|
|
67
|
+
console.log(options); // type of `options` is `{help: boolean | undefined}`
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
See [`ParserConfig`](./docs/README.md#parserconfig) for more information about how to configure the
|
|
71
|
+
parser.
|
|
72
|
+
|
|
73
|
+
## Documentation
|
|
74
|
+
|
|
75
|
+
See [API reference](./docs) for auto-generated documentation.
|
|
76
|
+
|
|
77
|
+
## Contributing
|
|
78
|
+
|
|
79
|
+
If you want to contribute, see [CONTRIBUTING](./CONTRIBUTING.md) for details.
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
This package is licensed under the GNU Lesser General Public License v3. See [LICENSE](./LICENSE.md)
|
|
84
|
+
for details.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A subclass of `Error` that indicates a parsing failure.
|
|
3
|
+
*/
|
|
4
|
+
export declare const ParsingError: new (code: "INVALID_PARAMETER" | "UNKNOWN_PARAMETER" | "INVALID_OPTION" | "UNKNOWN_OPTION", options?: import("@jakubmazanec/error").CustomErrorOptions | undefined) => import("@jakubmazanec/error").CustomError<"INVALID_PARAMETER" | "UNKNOWN_PARAMETER" | "INVALID_OPTION" | "UNKNOWN_OPTION" | "UNKNOWN_ERROR">;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createCustomError } from '@jakubmazanec/error';
|
|
2
|
+
/**
|
|
3
|
+
* A subclass of `Error` that indicates a parsing failure.
|
|
4
|
+
*/ export const ParsingError = createCustomError('ParsingError', {
|
|
5
|
+
INVALID_PARAMETER: 'Invalid value "{0}" found. Allowed values for parameter "{1}" are: {2}.',
|
|
6
|
+
UNKNOWN_PARAMETER: 'Unknown parameter "{0}" found. Unknown parameters are not allowed.',
|
|
7
|
+
INVALID_OPTION: 'Invalid value "{0}" found. Allowed values for option "{1}" are: {2}.',
|
|
8
|
+
UNKNOWN_OPTION: 'Unknown option "{0}" found. Unknown options are not allowed.'
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=ParsingError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ParsingError.ts"],"sourcesContent":["import {createCustomError} from '@jakubmazanec/error';\n\n/**\n * A subclass of `Error` that indicates a parsing failure.\n */\nexport const ParsingError = createCustomError('ParsingError', {\n INVALID_PARAMETER: 'Invalid value \"{0}\" found. Allowed values for parameter \"{1}\" are: {2}.',\n UNKNOWN_PARAMETER: 'Unknown parameter \"{0}\" found. Unknown parameters are not allowed.',\n INVALID_OPTION: 'Invalid value \"{0}\" found. Allowed values for option \"{1}\" are: {2}.',\n UNKNOWN_OPTION: 'Unknown option \"{0}\" found. Unknown options are not allowed.',\n});\n"],"names":["createCustomError","ParsingError","INVALID_PARAMETER","UNKNOWN_PARAMETER","INVALID_OPTION","UNKNOWN_OPTION"],"mappings":"AAAA,SAAQA,iBAAiB,QAAO,sBAAsB;AAEtD;;CAEC,GACD,OAAO,MAAMC,eAAeD,kBAAkB,gBAAgB;IAC5DE,mBAAmB;IACnBC,mBAAmB;IACnBC,gBAAgB;IAChBC,gBAAgB;AAClB,GAAG"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A subclass of `Error` that indicates a validation issue.
|
|
3
|
+
*/
|
|
4
|
+
export declare const ValidationError: new (code: "INVALID_COMMAND" | "MISSING_PARAMETER" | "INVALID_PARAMETER_DEFAULT_AND_CHOICES" | "INVALID_PARAMETER_ORDER" | "MISSING_OPTION" | "INVALID_OPTION_DEFAULT_AND_CHOICES" | "INVALID_OPTION_NAME" | "REPEATED_OPTION_NAME" | "INVALID_OPTION_ARITY", options?: import("@jakubmazanec/error").CustomErrorOptions | undefined) => import("@jakubmazanec/error").CustomError<"INVALID_COMMAND" | "MISSING_PARAMETER" | "INVALID_PARAMETER_DEFAULT_AND_CHOICES" | "INVALID_PARAMETER_ORDER" | "MISSING_OPTION" | "INVALID_OPTION_DEFAULT_AND_CHOICES" | "INVALID_OPTION_NAME" | "REPEATED_OPTION_NAME" | "INVALID_OPTION_ARITY" | "UNKNOWN_ERROR">;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createCustomError } from '@jakubmazanec/error';
|
|
2
|
+
/**
|
|
3
|
+
* A subclass of `Error` that indicates a validation issue.
|
|
4
|
+
*/ export const ValidationError = createCustomError('ValidationError', {
|
|
5
|
+
INVALID_COMMAND: 'Command "{0}" has invalid format. Only words consisting of letters, numbers or dashes separated by single space are allowed.',
|
|
6
|
+
MISSING_PARAMETER: 'Parameter "{0}" is required but its value is undefined.',
|
|
7
|
+
INVALID_PARAMETER_DEFAULT_AND_CHOICES: 'Parameter "{0}" has invalid default value "{1}". Default value must be one of the `choices` elements.',
|
|
8
|
+
INVALID_PARAMETER_ORDER: 'Optional parameter "{0}" found before required parameter "{1}". Required parameter must be first.',
|
|
9
|
+
MISSING_OPTION: 'Option "{0}" is required but its value is undefined.',
|
|
10
|
+
INVALID_OPTION_DEFAULT_AND_CHOICES: 'Option "{0}" has invalid default value "{1}". Default value must be one of the `choices` elements.',
|
|
11
|
+
INVALID_OPTION_NAME: 'Option "{0}" has invalid name. Only names consisting of letters, numbers or dashes are allowed.',
|
|
12
|
+
REPEATED_OPTION_NAME: 'Option "{0}" has invalid short name "{1}". Short option names must be unique.',
|
|
13
|
+
INVALID_OPTION_ARITY: 'Option "{0}" has invalid number of values. Found "{1}", require "{2}".'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=ValidationError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ValidationError.ts"],"sourcesContent":["import {createCustomError} from '@jakubmazanec/error';\n\n/**\n * A subclass of `Error` that indicates a validation issue.\n */\nexport const ValidationError = createCustomError('ValidationError', {\n INVALID_COMMAND:\n 'Command \"{0}\" has invalid format. Only words consisting of letters, numbers or dashes separated by single space are allowed.',\n MISSING_PARAMETER: 'Parameter \"{0}\" is required but its value is undefined.',\n INVALID_PARAMETER_DEFAULT_AND_CHOICES:\n 'Parameter \"{0}\" has invalid default value \"{1}\". Default value must be one of the `choices` elements.',\n INVALID_PARAMETER_ORDER:\n 'Optional parameter \"{0}\" found before required parameter \"{1}\". Required parameter must be first.',\n MISSING_OPTION: 'Option \"{0}\" is required but its value is undefined.',\n INVALID_OPTION_DEFAULT_AND_CHOICES:\n 'Option \"{0}\" has invalid default value \"{1}\". Default value must be one of the `choices` elements.',\n INVALID_OPTION_NAME:\n 'Option \"{0}\" has invalid name. Only names consisting of letters, numbers or dashes are allowed.',\n REPEATED_OPTION_NAME:\n 'Option \"{0}\" has invalid short name \"{1}\". Short option names must be unique.',\n INVALID_OPTION_ARITY: 'Option \"{0}\" has invalid number of values. Found \"{1}\", require \"{2}\".',\n});\n"],"names":["createCustomError","ValidationError","INVALID_COMMAND","MISSING_PARAMETER","INVALID_PARAMETER_DEFAULT_AND_CHOICES","INVALID_PARAMETER_ORDER","MISSING_OPTION","INVALID_OPTION_DEFAULT_AND_CHOICES","INVALID_OPTION_NAME","REPEATED_OPTION_NAME","INVALID_OPTION_ARITY"],"mappings":"AAAA,SAAQA,iBAAiB,QAAO,sBAAsB;AAEtD;;CAEC,GACD,OAAO,MAAMC,kBAAkBD,kBAAkB,mBAAmB;IAClEE,iBACE;IACFC,mBAAmB;IACnBC,uCACE;IACFC,yBACE;IACFC,gBAAgB;IAChBC,oCACE;IACFC,qBACE;IACFC,sBACE;IACFC,sBAAsB;AACxB,GAAG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CommandsConfig, type OptionsConfig, type ParametersConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `Checker` is used for handling various check before, during, and after parsing of the arguments.
|
|
4
|
+
*/
|
|
5
|
+
export declare class Checker {
|
|
6
|
+
errors: Error[];
|
|
7
|
+
checkCommandsConfig(commandsConfig: CommandsConfig): void;
|
|
8
|
+
checkParametersConfig(parametersConfig: ParametersConfig | []): void;
|
|
9
|
+
checkOptionsConfig(optionsConfig: OptionsConfig): void;
|
|
10
|
+
checkParsedParameters(parametersConfig: ParametersConfig | [], parsedParameters: unknown[]): void;
|
|
11
|
+
checkParsedOptions(optionsConfig: OptionsConfig, parsedOptions: Record<string, unknown>): void;
|
|
12
|
+
addError(error: Error): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ValidationError } from '../ValidationError.js';
|
|
2
|
+
import { isCommand } from './isCommand.js';
|
|
3
|
+
import { isLongOption } from './isLongOption.js';
|
|
4
|
+
/**
|
|
5
|
+
* `Checker` is used for handling various check before, during, and after parsing of the arguments.
|
|
6
|
+
*/ export class Checker {
|
|
7
|
+
errors = [];
|
|
8
|
+
checkCommandsConfig(commandsConfig) {
|
|
9
|
+
for (let commandConfig of commandsConfig){
|
|
10
|
+
if (!isCommand(commandConfig)) {
|
|
11
|
+
this.addError(new ValidationError('INVALID_COMMAND', {
|
|
12
|
+
messageParameters: [
|
|
13
|
+
commandConfig
|
|
14
|
+
]
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
checkParametersConfig(parametersConfig) {
|
|
20
|
+
for (let [i, parameterConfig] of parametersConfig.entries()){
|
|
21
|
+
var _parametersConfig_;
|
|
22
|
+
// types of choices must be correct
|
|
23
|
+
if (parameterConfig.type !== 'boolean' && parameterConfig.choices && // default values and chocies do not contradict each other
|
|
24
|
+
typeof parameterConfig.defaultValue !== 'undefined' && !parameterConfig.choices.includes(parameterConfig.defaultValue)) {
|
|
25
|
+
this.addError(new ValidationError('INVALID_PARAMETER_DEFAULT_AND_CHOICES', {
|
|
26
|
+
messageParameters: [
|
|
27
|
+
parameterConfig.label ?? i,
|
|
28
|
+
parameterConfig.defaultValue
|
|
29
|
+
]
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
// if parameter is required, all parameters before must be required too
|
|
33
|
+
if (i >= 1 && parameterConfig.required === true && ((_parametersConfig_ = parametersConfig[i - 1]) === null || _parametersConfig_ === void 0 ? void 0 : _parametersConfig_.required) !== true) {
|
|
34
|
+
var _parametersConfig_1;
|
|
35
|
+
this.addError(new ValidationError('INVALID_PARAMETER_ORDER', {
|
|
36
|
+
messageParameters: [
|
|
37
|
+
((_parametersConfig_1 = parametersConfig[i - 1]) === null || _parametersConfig_1 === void 0 ? void 0 : _parametersConfig_1.label) ?? i - 1,
|
|
38
|
+
parameterConfig.label ?? i
|
|
39
|
+
]
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
checkOptionsConfig(optionsConfig) {
|
|
45
|
+
let usedShortOptionNames = new Set([]);
|
|
46
|
+
for (let [optionName, optionConfig] of Object.entries(optionsConfig)){
|
|
47
|
+
// option names must be in correct format
|
|
48
|
+
if (!isLongOption(`--${optionName}`)) {
|
|
49
|
+
this.addError(new ValidationError('INVALID_OPTION_NAME', {
|
|
50
|
+
messageParameters: [
|
|
51
|
+
optionName
|
|
52
|
+
]
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
// option short names must be unique
|
|
56
|
+
if (optionConfig.shortName && usedShortOptionNames.has(optionConfig.shortName)) {
|
|
57
|
+
this.addError(new ValidationError('REPEATED_OPTION_NAME', {
|
|
58
|
+
messageParameters: [
|
|
59
|
+
optionName,
|
|
60
|
+
optionConfig.shortName
|
|
61
|
+
]
|
|
62
|
+
}));
|
|
63
|
+
} else if (optionConfig.shortName) {
|
|
64
|
+
usedShortOptionNames.add(optionConfig.shortName);
|
|
65
|
+
}
|
|
66
|
+
// default values and chocies do not contradict each other
|
|
67
|
+
if ((optionConfig.type === 'string' || optionConfig.type === 'number' && !optionConfig.count) && optionConfig.choices && typeof optionConfig.defaultValue !== 'undefined' && !optionConfig.choices.includes(optionConfig.defaultValue)) {
|
|
68
|
+
this.addError(new ValidationError('INVALID_OPTION_DEFAULT_AND_CHOICES', {
|
|
69
|
+
messageParameters: [
|
|
70
|
+
optionName,
|
|
71
|
+
optionConfig.defaultValue
|
|
72
|
+
]
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
checkParsedParameters(parametersConfig, parsedParameters) {
|
|
78
|
+
for (let [i, parameterConfig] of parametersConfig.entries()){
|
|
79
|
+
let parsedParameter = parsedParameters[i];
|
|
80
|
+
// required parameters must have value
|
|
81
|
+
if (parameterConfig.required === true && typeof parsedParameter === 'undefined') {
|
|
82
|
+
this.addError(new ValidationError('MISSING_PARAMETER', {
|
|
83
|
+
messageParameters: [
|
|
84
|
+
parameterConfig.label ?? i
|
|
85
|
+
]
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
checkParsedOptions(optionsConfig, parsedOptions) {
|
|
91
|
+
for (let [optionName, optionConfig] of Object.entries(optionsConfig)){
|
|
92
|
+
let parsedOption = parsedOptions[optionName];
|
|
93
|
+
// check required
|
|
94
|
+
if (optionConfig.required && typeof parsedOption === 'undefined') {
|
|
95
|
+
this.addError(new ValidationError('MISSING_OPTION', {
|
|
96
|
+
messageParameters: [
|
|
97
|
+
optionName
|
|
98
|
+
]
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
// check arity
|
|
102
|
+
if (typeof parsedOption !== 'undefined' && (optionConfig.type === 'string' && optionConfig.multiple || optionConfig.type === 'number' && optionConfig.multiple) && typeof optionConfig.arity === 'number' && Array.isArray(parsedOption) && parsedOption.length > 0 && parsedOption.length !== optionConfig.arity) {
|
|
103
|
+
this.addError(new ValidationError('INVALID_OPTION_ARITY', {
|
|
104
|
+
messageParameters: [
|
|
105
|
+
optionName,
|
|
106
|
+
parsedOption.length,
|
|
107
|
+
optionConfig.arity
|
|
108
|
+
]
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
addError(error) {
|
|
114
|
+
this.errors.push(error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=Checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/internals/Checker.ts"],"sourcesContent":["import {type CommandsConfig, type OptionsConfig, type ParametersConfig} from '../types.js';\nimport {ValidationError} from '../ValidationError.js';\nimport {isCommand} from './isCommand.js';\nimport {isLongOption} from './isLongOption.js';\n\n/**\n * `Checker` is used for handling various check before, during, and after parsing of the arguments.\n */\nexport class Checker {\n errors: Error[] = [];\n\n checkCommandsConfig(commandsConfig: CommandsConfig) {\n for (let commandConfig of commandsConfig) {\n if (!isCommand(commandConfig)) {\n this.addError(new ValidationError('INVALID_COMMAND', {messageParameters: [commandConfig]}));\n }\n }\n }\n\n checkParametersConfig(parametersConfig: ParametersConfig | []) {\n for (let [i, parameterConfig] of parametersConfig.entries()) {\n // types of choices must be correct\n if (\n parameterConfig.type !== 'boolean' &&\n parameterConfig.choices && // default values and chocies do not contradict each other\n typeof parameterConfig.defaultValue !== 'undefined' &&\n !parameterConfig.choices.includes(parameterConfig.defaultValue as never)\n ) {\n this.addError(\n new ValidationError('INVALID_PARAMETER_DEFAULT_AND_CHOICES', {\n messageParameters: [parameterConfig.label ?? i, parameterConfig.defaultValue],\n }),\n );\n }\n\n // if parameter is required, all parameters before must be required too\n if (\n i >= 1 &&\n parameterConfig.required === true &&\n parametersConfig[i - 1]?.required !== true\n ) {\n this.addError(\n new ValidationError('INVALID_PARAMETER_ORDER', {\n messageParameters: [\n parametersConfig[i - 1]?.label ?? i - 1,\n parameterConfig.label ?? i,\n ],\n }),\n );\n }\n }\n }\n\n checkOptionsConfig(optionsConfig: OptionsConfig) {\n let usedShortOptionNames: Set<string> = new Set([]);\n\n for (let [optionName, optionConfig] of Object.entries(optionsConfig)) {\n // option names must be in correct format\n if (!isLongOption(`--${optionName}`)) {\n this.addError(\n new ValidationError('INVALID_OPTION_NAME', {\n messageParameters: [optionName],\n }),\n );\n }\n\n // option short names must be unique\n if (optionConfig.shortName && usedShortOptionNames.has(optionConfig.shortName)) {\n this.addError(\n new ValidationError('REPEATED_OPTION_NAME', {\n messageParameters: [optionName, optionConfig.shortName],\n }),\n );\n } else if (optionConfig.shortName) {\n usedShortOptionNames.add(optionConfig.shortName);\n }\n\n // default values and chocies do not contradict each other\n if (\n (optionConfig.type === 'string' ||\n (optionConfig.type === 'number' && !optionConfig.count)) &&\n optionConfig.choices &&\n typeof optionConfig.defaultValue !== 'undefined' &&\n !optionConfig.choices.includes(optionConfig.defaultValue as never)\n ) {\n this.addError(\n new ValidationError('INVALID_OPTION_DEFAULT_AND_CHOICES', {\n messageParameters: [optionName, optionConfig.defaultValue],\n }),\n );\n }\n }\n }\n\n checkParsedParameters(parametersConfig: ParametersConfig | [], parsedParameters: unknown[]) {\n for (let [i, parameterConfig] of parametersConfig.entries()) {\n let parsedParameter = parsedParameters[i];\n\n // required parameters must have value\n if (parameterConfig.required === true && typeof parsedParameter === 'undefined') {\n this.addError(\n new ValidationError('MISSING_PARAMETER', {\n messageParameters: [parameterConfig.label ?? i],\n }),\n );\n }\n }\n }\n\n checkParsedOptions(optionsConfig: OptionsConfig, parsedOptions: Record<string, unknown>) {\n for (let [optionName, optionConfig] of Object.entries(optionsConfig)) {\n let parsedOption = parsedOptions[optionName];\n\n // check required\n if (optionConfig.required && typeof parsedOption === 'undefined') {\n this.addError(\n new ValidationError('MISSING_OPTION', {\n messageParameters: [optionName],\n }),\n );\n }\n\n // check arity\n if (\n typeof parsedOption !== 'undefined' &&\n ((optionConfig.type === 'string' && optionConfig.multiple) ||\n (optionConfig.type === 'number' && optionConfig.multiple)) &&\n typeof optionConfig.arity === 'number' &&\n Array.isArray(parsedOption) &&\n (parsedOption as unknown[]).length > 0 &&\n (parsedOption as unknown[]).length !== optionConfig.arity\n ) {\n this.addError(\n new ValidationError('INVALID_OPTION_ARITY', {\n messageParameters: [optionName, (parsedOption as unknown[]).length, optionConfig.arity],\n }),\n );\n }\n }\n }\n\n addError(error: Error) {\n this.errors.push(error);\n }\n}\n"],"names":["ValidationError","isCommand","isLongOption","Checker","errors","checkCommandsConfig","commandsConfig","commandConfig","addError","messageParameters","checkParametersConfig","parametersConfig","i","parameterConfig","entries","type","choices","defaultValue","includes","label","required","checkOptionsConfig","optionsConfig","usedShortOptionNames","Set","optionName","optionConfig","Object","shortName","has","add","count","checkParsedParameters","parsedParameters","parsedParameter","checkParsedOptions","parsedOptions","parsedOption","multiple","arity","Array","isArray","length","error","push"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type NormalizedCommandConfig, type NormalizedCommandsConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `CommandScope` handles storing information about parsing of a command.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CommandScope {
|
|
6
|
+
private readonly args;
|
|
7
|
+
readonly config: NormalizedCommandConfig;
|
|
8
|
+
constructor(arg: string, normalizedCommandsConfig: NormalizedCommandsConfig);
|
|
9
|
+
captureArg(arg: string): this;
|
|
10
|
+
isComplete(): boolean;
|
|
11
|
+
isDone(): boolean;
|
|
12
|
+
getValue(): string;
|
|
13
|
+
getArgs(): string[];
|
|
14
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `CommandScope` handles storing information about parsing of a command.
|
|
3
|
+
*/ export class CommandScope {
|
|
4
|
+
args;
|
|
5
|
+
config;
|
|
6
|
+
constructor(arg, normalizedCommandsConfig){
|
|
7
|
+
let normalizedArgument = arg.toLowerCase();
|
|
8
|
+
let commandConfig = normalizedCommandsConfig.find((commandConfig)=>commandConfig.args[0] === normalizedArgument);
|
|
9
|
+
this.config = commandConfig ?? [];
|
|
10
|
+
this.args = [
|
|
11
|
+
normalizedArgument
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
captureArg(arg) {
|
|
15
|
+
this.args.push(arg.toLowerCase());
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
isComplete() {
|
|
19
|
+
let isComplete = true;
|
|
20
|
+
for (let [i, arg] of this.config.args.entries()){
|
|
21
|
+
if (this.args[i] !== arg) {
|
|
22
|
+
isComplete = false;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return isComplete;
|
|
27
|
+
}
|
|
28
|
+
isDone() {
|
|
29
|
+
let isDone = false;
|
|
30
|
+
for (let [i, arg] of this.config.args.entries()){
|
|
31
|
+
if (this.args[i] !== arg) {
|
|
32
|
+
isDone = true;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return isDone;
|
|
37
|
+
}
|
|
38
|
+
getValue() {
|
|
39
|
+
return this.config.command;
|
|
40
|
+
}
|
|
41
|
+
getArgs() {
|
|
42
|
+
return [
|
|
43
|
+
...this.args
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=CommandScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/internals/CommandScope.ts"],"sourcesContent":["import {type NormalizedCommandConfig, type NormalizedCommandsConfig} from '../types.js';\n\n/**\n * `CommandScope` handles storing information about parsing of a command.\n */\nexport class CommandScope {\n private readonly args: string[];\n readonly config: NormalizedCommandConfig;\n\n constructor(arg: string, normalizedCommandsConfig: NormalizedCommandsConfig) {\n let normalizedArgument = arg.toLowerCase();\n let commandConfig = normalizedCommandsConfig.find(\n (commandConfig) => commandConfig.args[0] === normalizedArgument,\n );\n\n this.config = commandConfig ?? ([] as unknown as NormalizedCommandConfig);\n this.args = [normalizedArgument];\n }\n\n captureArg(arg: string) {\n this.args.push(arg.toLowerCase());\n\n return this;\n }\n\n isComplete() {\n let isComplete = true;\n\n for (let [i, arg] of this.config.args.entries()) {\n if (this.args[i] !== arg) {\n isComplete = false;\n\n break;\n }\n }\n\n return isComplete;\n }\n\n isDone() {\n let isDone = false;\n\n for (let [i, arg] of this.config.args.entries()) {\n if (this.args[i] !== arg) {\n isDone = true;\n\n break;\n }\n }\n\n return isDone;\n }\n\n getValue() {\n return this.config.command;\n }\n\n getArgs() {\n return [...this.args];\n }\n}\n"],"names":["CommandScope","args","config","constructor","arg","normalizedCommandsConfig","normalizedArgument","toLowerCase","commandConfig","find","captureArg","push","isComplete","i","entries","isDone","getValue","command","getArgs"],"mappings":"AAEA;;CAEC,GACD,OAAO,MAAMA;IACMC,KAAe;IACvBC,OAAgC;IAEzCC,YAAYC,GAAW,EAAEC,wBAAkD,CAAE;QAC3E,IAAIC,qBAAqBF,IAAIG,WAAW;QACxC,IAAIC,gBAAgBH,yBAAyBI,IAAI,CAC/C,CAACD,gBAAkBA,cAAcP,IAAI,CAAC,EAAE,KAAKK;QAG/C,IAAI,CAACJ,MAAM,GAAGM,iBAAkB,EAAE;QAClC,IAAI,CAACP,IAAI,GAAG;YAACK;SAAmB;IAClC;IAEAI,WAAWN,GAAW,EAAE;QACtB,IAAI,CAACH,IAAI,CAACU,IAAI,CAACP,IAAIG,WAAW;QAE9B,OAAO,IAAI;IACb;IAEAK,aAAa;QACX,IAAIA,aAAa,IAAI;QAErB,KAAK,IAAI,CAACC,GAAGT,IAAI,IAAI,IAAI,CAACF,MAAM,CAACD,IAAI,CAACa,OAAO,GAAI;YAC/C,IAAI,IAAI,CAACb,IAAI,CAACY,EAAE,KAAKT,KAAK;gBACxBQ,aAAa,KAAK;gBAElB,KAAM;YACR,CAAC;QACH;QAEA,OAAOA;IACT;IAEAG,SAAS;QACP,IAAIA,SAAS,KAAK;QAElB,KAAK,IAAI,CAACF,GAAGT,IAAI,IAAI,IAAI,CAACF,MAAM,CAACD,IAAI,CAACa,OAAO,GAAI;YAC/C,IAAI,IAAI,CAACb,IAAI,CAACY,EAAE,KAAKT,KAAK;gBACxBW,SAAS,IAAI;gBAEb,KAAM;YACR,CAAC;QACH;QAEA,OAAOA;IACT;IAEAC,WAAW;QACT,OAAO,IAAI,CAACd,MAAM,CAACe,OAAO;IAC5B;IAEAC,UAAU;QACR,OAAO;eAAI,IAAI,CAACjB,IAAI;SAAC;IACvB;AACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type OptionConfig, type OptionsConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* `CommandScope` handles storing information about parsing of an option..
|
|
4
|
+
*/
|
|
5
|
+
export declare class OptionScope {
|
|
6
|
+
name: string;
|
|
7
|
+
values: unknown[];
|
|
8
|
+
previousParsedValue?: unknown[] | unknown;
|
|
9
|
+
readonly config: OptionConfig;
|
|
10
|
+
constructor(optionName: string, optionsConfig: OptionsConfig, allowUnknownOptions?: boolean);
|
|
11
|
+
captureArg(arg: string): void;
|
|
12
|
+
isComplete(): boolean;
|
|
13
|
+
getValue(): unknown;
|
|
14
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import camelCase from 'lodash.camelcase';
|
|
2
|
+
import { ParsingError } from '../ParsingError.js';
|
|
3
|
+
import { castValue } from './castValue.js';
|
|
4
|
+
/**
|
|
5
|
+
* `CommandScope` handles storing information about parsing of an option..
|
|
6
|
+
*/ export class OptionScope {
|
|
7
|
+
name;
|
|
8
|
+
values = [];
|
|
9
|
+
previousParsedValue;
|
|
10
|
+
config;
|
|
11
|
+
constructor(optionName, optionsConfig, allowUnknownOptions = false){
|
|
12
|
+
this.name = optionName;
|
|
13
|
+
// Convert option to camel case
|
|
14
|
+
if (this.name.includes('-')) {
|
|
15
|
+
this.name = camelCase(this.name);
|
|
16
|
+
}
|
|
17
|
+
let optionConfig = optionsConfig[this.name];
|
|
18
|
+
if (!optionConfig) {
|
|
19
|
+
if (!allowUnknownOptions) {
|
|
20
|
+
throw new ParsingError('UNKNOWN_OPTION', {
|
|
21
|
+
messageParameters: [
|
|
22
|
+
this.name
|
|
23
|
+
]
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
optionConfig = {
|
|
27
|
+
type: 'string'
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
this.config = optionConfig;
|
|
31
|
+
}
|
|
32
|
+
captureArg(arg) {
|
|
33
|
+
let value = castValue(arg, this.config.type);
|
|
34
|
+
if ((this.config.type === 'number' && !this.config.count || this.config.type === 'string') && typeof this.config.choices !== 'undefined' && !this.config.choices.includes(value)) {
|
|
35
|
+
throw new ParsingError('INVALID_OPTION', {
|
|
36
|
+
messageParameters: [
|
|
37
|
+
value,
|
|
38
|
+
this.name,
|
|
39
|
+
this.config.choices.map((choice)=>`"${choice}"`).join(', ')
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (this.config.multiple) {
|
|
44
|
+
this.values.push(value);
|
|
45
|
+
} else {
|
|
46
|
+
this.values = [
|
|
47
|
+
value
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
isComplete() {
|
|
52
|
+
if (!this.config.multiple && this.values.length === 1) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (this.config.multiple && typeof this.config.arity === 'number' && this.values.length + (this.previousParsedValue ?? []).length === this.config.arity) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
getValue() {
|
|
61
|
+
let { config , previousParsedValue } = this;
|
|
62
|
+
let { values } = this;
|
|
63
|
+
if (config.type === 'boolean' && !config.multiple && !values.length) {
|
|
64
|
+
values = [
|
|
65
|
+
true
|
|
66
|
+
];
|
|
67
|
+
} else if (config.type === 'number' && config.count && !values.length) {
|
|
68
|
+
values = [
|
|
69
|
+
1
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
if (config.multiple && previousParsedValue) {
|
|
73
|
+
values = [
|
|
74
|
+
...previousParsedValue,
|
|
75
|
+
...values
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
if (config.type === 'number' && config.count && previousParsedValue) {
|
|
79
|
+
values = [
|
|
80
|
+
values[0] + previousParsedValue
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
return config.multiple ? values : values[0];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=OptionScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/internals/OptionScope.ts"],"sourcesContent":["import camelCase from 'lodash.camelcase';\n\nimport {ParsingError} from '../ParsingError.js';\nimport {type OptionConfig, type OptionsConfig} from '../types.js';\nimport {castValue} from './castValue.js';\n\n/**\n * `CommandScope` handles storing information about parsing of an option..\n */\nexport class OptionScope {\n name: string;\n\n values: unknown[] = [];\n previousParsedValue?: unknown[] | unknown;\n readonly config: OptionConfig;\n\n constructor(optionName: string, optionsConfig: OptionsConfig, allowUnknownOptions = false) {\n this.name = optionName;\n\n // Convert option to camel case\n if (this.name.includes('-')) {\n this.name = camelCase(this.name);\n }\n\n let optionConfig = optionsConfig[this.name];\n\n if (!optionConfig) {\n if (!allowUnknownOptions) {\n throw new ParsingError('UNKNOWN_OPTION', {messageParameters: [this.name]});\n }\n\n optionConfig = {\n type: 'string',\n };\n }\n\n this.config = optionConfig;\n }\n\n captureArg(arg: string) {\n let value = castValue(arg, this.config.type);\n\n if (\n ((this.config.type === 'number' && !this.config.count) || this.config.type === 'string') &&\n typeof this.config.choices !== 'undefined' &&\n !this.config.choices.includes(value as never)\n ) {\n throw new ParsingError('INVALID_OPTION', {\n messageParameters: [\n value,\n this.name,\n this.config.choices.map((choice) => `\"${choice}\"`).join(', '),\n ],\n });\n }\n\n if (this.config.multiple) {\n this.values.push(value);\n } else {\n this.values = [value];\n }\n }\n\n isComplete() {\n if (!this.config.multiple && this.values.length === 1) {\n return true;\n }\n\n if (\n this.config.multiple &&\n typeof this.config.arity === 'number' &&\n this.values.length + ((this.previousParsedValue as unknown[] | undefined) ?? []).length ===\n this.config.arity\n ) {\n return true;\n }\n\n return false;\n }\n\n getValue() {\n let {config, previousParsedValue} = this;\n let {values} = this;\n\n if (config.type === 'boolean' && !config.multiple && !values.length) {\n values = [true];\n } else if (config.type === 'number' && config.count && !values.length) {\n values = [1];\n }\n\n if (config.multiple && previousParsedValue) {\n values = [...(previousParsedValue as unknown[]), ...values];\n }\n\n if (config.type === 'number' && config.count && previousParsedValue) {\n values = [(values[0] as number) + (previousParsedValue as number)];\n }\n\n return config.multiple ? values : values[0];\n }\n}\n"],"names":["camelCase","ParsingError","castValue","OptionScope","name","values","previousParsedValue","config","constructor","optionName","optionsConfig","allowUnknownOptions","includes","optionConfig","messageParameters","type","captureArg","arg","value","count","choices","map","choice","join","multiple","push","isComplete","length","arity","getValue"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function that casts string value to a specified type.
|
|
3
|
+
*
|
|
4
|
+
* @param value The value to be converted.
|
|
5
|
+
* @param type The type to convert the value into.
|
|
6
|
+
* */
|
|
7
|
+
export declare function castValue<T extends 'boolean' | 'number' | 'string'>(value: string, type?: T): T extends 'boolean' ? boolean : T extends 'number' ? number : string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isFalseString } from './isFalseString.js';
|
|
2
|
+
/**
|
|
3
|
+
* A function that casts string value to a specified type.
|
|
4
|
+
*
|
|
5
|
+
* @param value The value to be converted.
|
|
6
|
+
* @param type The type to convert the value into.
|
|
7
|
+
* */ export function castValue(value, type) {
|
|
8
|
+
switch(type){
|
|
9
|
+
case 'boolean':
|
|
10
|
+
{
|
|
11
|
+
let booleanString = String(value).toLowerCase();
|
|
12
|
+
return !(isFalseString(booleanString) || booleanString === '');
|
|
13
|
+
}
|
|
14
|
+
case 'number':
|
|
15
|
+
{
|
|
16
|
+
return Number.parseFloat(value);
|
|
17
|
+
}
|
|
18
|
+
default:
|
|
19
|
+
{
|
|
20
|
+
return String(value);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=castValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/internals/castValue.ts"],"sourcesContent":["import {isFalseString} from './isFalseString.js';\n\n/**\n * A function that casts string value to a specified type.\n *\n * @param value The value to be converted.\n * @param type The type to convert the value into.\n * */\nexport function castValue<T extends 'boolean' | 'number' | 'string'>(\n value: string,\n type?: T,\n): T extends 'boolean' ? boolean : T extends 'number' ? number : string {\n switch (type) {\n case 'boolean': {\n let booleanString = String(value).toLowerCase();\n\n return !(isFalseString(booleanString) || booleanString === '') as T extends 'boolean'\n ? boolean\n : T extends 'number'\n ? number\n : string;\n }\n\n case 'number': {\n return Number.parseFloat(value) as T extends 'boolean'\n ? boolean\n : T extends 'number'\n ? number\n : string;\n }\n\n default: {\n return String(value) as T extends 'boolean' ? boolean : T extends 'number' ? number : string;\n }\n }\n}\n"],"names":["isFalseString","castValue","value","type","booleanString","String","toLowerCase","Number","parseFloat"],"mappings":"AAAA,SAAQA,aAAa,QAAO,qBAAqB;AAEjD;;;;;GAKG,GACH,OAAO,SAASC,UACdC,KAAa,EACbC,IAAQ,EAC8D;IACtE,OAAQA;QACN,KAAK;YAAW;gBACd,IAAIC,gBAAgBC,OAAOH,OAAOI,WAAW;gBAE7C,OAAO,CAAEN,CAAAA,cAAcI,kBAAkBA,kBAAkB,EAAC;YAK9D;QAEA,KAAK;YAAU;gBACb,OAAOG,OAAOC,UAAU,CAACN;YAK3B;QAEA;YAAS;gBACP,OAAOG,OAAOH;YAChB;IACF;AACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function that converts a string representing a command into the arguments, i.e. array of strings.
|
|
3
|
+
*
|
|
4
|
+
* @param value The value to convert.
|
|
5
|
+
* @return Arguments.
|
|
6
|
+
*/ export function commandToArguments(value) {
|
|
7
|
+
let rawArgs = value.split(' ');
|
|
8
|
+
let args = [];
|
|
9
|
+
for (let [, rawValue] of rawArgs.entries()){
|
|
10
|
+
if (typeof rawValue !== 'undefined') {
|
|
11
|
+
if (rawValue === '' && args.at(-1)) {
|
|
12
|
+
args[args.length - 1] += ' ';
|
|
13
|
+
} else {
|
|
14
|
+
args.push(rawValue);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return args;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=commandToArguments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/internals/commandToArguments.ts"],"sourcesContent":["/**\n * A function that converts a string representing a command into the arguments, i.e. array of strings.\n *\n * @param value The value to convert.\n * @return Arguments.\n */\nexport function commandToArguments(value: string): string[] {\n let rawArgs = value.split(' ');\n let args: string[] = [];\n\n for (let [, rawValue] of rawArgs.entries()) {\n if (typeof rawValue !== 'undefined') {\n if (rawValue === '' && args.at(-1)) {\n args[args.length - 1] += ' ';\n } else {\n args.push(rawValue);\n }\n }\n }\n\n return args;\n}\n"],"names":["commandToArguments","value","rawArgs","split","args","rawValue","entries","at","length","push"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA,mBAAmBC,KAAa,EAAY;IAC1D,IAAIC,UAAUD,MAAME,KAAK,CAAC;IAC1B,IAAIC,OAAiB,EAAE;IAEvB,KAAK,IAAI,GAAGC,SAAS,IAAIH,QAAQI,OAAO,GAAI;QAC1C,IAAI,OAAOD,aAAa,aAAa;YACnC,IAAIA,aAAa,MAAMD,KAAKG,EAAE,CAAC,CAAC,IAAI;gBAClCH,IAAI,CAACA,KAAKI,MAAM,GAAG,EAAE,IAAI;YAC3B,OAAO;gBACLJ,KAAKK,IAAI,CAACJ;YACZ,CAAC;QACH,CAAC;IACH;IAEA,OAAOD;AACT,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function createOptionShortNameMap(optionsConfig) {
|
|
2
|
+
let map = {};
|
|
3
|
+
for (let [optionName, optionConfig] of Object.entries(optionsConfig)){
|
|
4
|
+
if (typeof optionConfig.shortName === 'string') {
|
|
5
|
+
map[optionConfig.shortName] = optionName;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return map;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=createOptionShortNameMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/internals/createOptionShortNameMap.ts"],"sourcesContent":["import {type OptionsConfig} from '../types.js';\n\nexport function createOptionShortNameMap(optionsConfig: OptionsConfig) {\n let map: Record<string, string> = {};\n\n for (let [optionName, optionConfig] of Object.entries(optionsConfig)) {\n if (typeof optionConfig.shortName === 'string') {\n map[optionConfig.shortName] = optionName;\n }\n }\n\n return map;\n}\n"],"names":["createOptionShortNameMap","optionsConfig","map","optionName","optionConfig","Object","entries","shortName"],"mappings":"AAEA,OAAO,SAASA,yBAAyBC,aAA4B,EAAE;IACrE,IAAIC,MAA8B,CAAC;IAEnC,KAAK,IAAI,CAACC,YAAYC,aAAa,IAAIC,OAAOC,OAAO,CAACL,eAAgB;QACpE,IAAI,OAAOG,aAAaG,SAAS,KAAK,UAAU;YAC9CL,GAAG,CAACE,aAAaG,SAAS,CAAC,GAAGJ;QAChC,CAAC;IACH;IAEA,OAAOD;AACT,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Argv } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A function that converts any argument that is a short options group into separate short options.
|
|
4
|
+
*
|
|
5
|
+
* @param argv Arguments.
|
|
6
|
+
* @return Arguments that contain no short options group
|
|
7
|
+
*/
|
|
8
|
+
export declare function expandArguments(argv: Argv): Argv;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isShortOptionsGroup } from './isShortOptionsGroup.js';
|
|
2
|
+
/**
|
|
3
|
+
* A function that converts any argument that is a short options group into separate short options.
|
|
4
|
+
*
|
|
5
|
+
* @param argv Arguments.
|
|
6
|
+
* @return Arguments that contain no short options group
|
|
7
|
+
*/ export function expandArguments(argv) {
|
|
8
|
+
let expandedArguments = [];
|
|
9
|
+
for (let arg of argv){
|
|
10
|
+
if (isShortOptionsGroup(arg)) {
|
|
11
|
+
expandedArguments.push(...[
|
|
12
|
+
...arg
|
|
13
|
+
].slice(1).map((value)=>`-${value}`));
|
|
14
|
+
} else {
|
|
15
|
+
expandedArguments.push(arg);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return expandedArguments;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=expandArguments.js.map
|