@ztimson/utils 0.23.2 → 0.23.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/dist/arg-parser.d.ts +53 -0
- package/dist/index.cjs +116 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +116 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type Arg<T = any> = {
|
|
2
|
+
/** Argument/property name */
|
|
3
|
+
name: string;
|
|
4
|
+
/** Argument description for help page */
|
|
5
|
+
desc: string;
|
|
6
|
+
/** Available shorthands */
|
|
7
|
+
flags?: string[];
|
|
8
|
+
/** Argument is not required */
|
|
9
|
+
optional?: boolean;
|
|
10
|
+
/** Default value if argument is not used */
|
|
11
|
+
default?: T;
|
|
12
|
+
/** Collects any unmatched arguments */
|
|
13
|
+
extras?: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare class ArgParser {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly desc: string;
|
|
18
|
+
readonly argList: (ArgParser | Arg)[];
|
|
19
|
+
readonly examples: string[];
|
|
20
|
+
static readonly helpArg: Arg;
|
|
21
|
+
commands: ArgParser[];
|
|
22
|
+
args: Arg[];
|
|
23
|
+
flags: Arg[];
|
|
24
|
+
defaults: {
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Create a unix-like argument parser to extract flags from the argument list. Can also create help messages.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} name Script name
|
|
31
|
+
* @param {string} desc Help description
|
|
32
|
+
* @param {(ArgParser | Arg[]} argList Array of CLI arguments
|
|
33
|
+
* @param {string[]} examples Additional examples to display
|
|
34
|
+
*/
|
|
35
|
+
constructor(name: string, desc: string, argList?: (ArgParser | Arg)[], examples?: string[]);
|
|
36
|
+
/**
|
|
37
|
+
* Parse an array into an arguments dictionary using the configuration.
|
|
38
|
+
*
|
|
39
|
+
* @param {string[]} args Array of arguments to be parsed
|
|
40
|
+
* @returns {object} Dictionary of arguments with defaults applied
|
|
41
|
+
*/
|
|
42
|
+
parse(args: string[]): any;
|
|
43
|
+
/**
|
|
44
|
+
* Create help message from the provided description & argument list.
|
|
45
|
+
*
|
|
46
|
+
* @returns {string} Help message
|
|
47
|
+
* @param opts Help options: command - display a commands help, message - override help description
|
|
48
|
+
*/
|
|
49
|
+
help(opts?: {
|
|
50
|
+
command?: string;
|
|
51
|
+
message?: string;
|
|
52
|
+
}): string;
|
|
53
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,121 @@
|
|
|
5
5
|
var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2;
|
|
6
6
|
var __publicField = (obj, key, value2) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2);
|
|
7
7
|
|
|
8
|
+
const _ArgParser = class _ArgParser {
|
|
9
|
+
/**
|
|
10
|
+
* Create a unix-like argument parser to extract flags from the argument list. Can also create help messages.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} name Script name
|
|
13
|
+
* @param {string} desc Help description
|
|
14
|
+
* @param {(ArgParser | Arg[]} argList Array of CLI arguments
|
|
15
|
+
* @param {string[]} examples Additional examples to display
|
|
16
|
+
*/
|
|
17
|
+
constructor(name, desc, argList = [], examples = []) {
|
|
18
|
+
__publicField(this, "commands", []);
|
|
19
|
+
__publicField(this, "args", []);
|
|
20
|
+
__publicField(this, "flags", []);
|
|
21
|
+
__publicField(this, "defaults");
|
|
22
|
+
this.name = name;
|
|
23
|
+
this.desc = desc;
|
|
24
|
+
this.argList = argList;
|
|
25
|
+
this.examples = examples;
|
|
26
|
+
this.commands = argList.filter((arg) => arg instanceof _ArgParser);
|
|
27
|
+
this.args = argList.filter((arg) => {
|
|
28
|
+
var _a;
|
|
29
|
+
return !(arg instanceof _ArgParser) && !((_a = arg.flags) == null ? void 0 : _a.length);
|
|
30
|
+
});
|
|
31
|
+
this.flags = [...argList.filter((arg) => !(arg instanceof _ArgParser) && arg.flags && arg.flags.length), ...this.flags];
|
|
32
|
+
this.defaults = argList.reduce((acc, arg) => ({ ...acc, [arg.name]: arg["extras"] ? [] : arg.default ?? null }), {});
|
|
33
|
+
this.examples = [
|
|
34
|
+
...examples,
|
|
35
|
+
`[OPTIONS] ${this.args.map((arg) => (arg.optional ? `[${arg.name.toUpperCase()}]` : arg.name.toUpperCase()) + (arg.extras ? "..." : "")).join(" ")}`,
|
|
36
|
+
this.commands.length ? `[OPTIONS] COMMAND` : null,
|
|
37
|
+
`--help ${this.commands.length ? "[COMMAND]" : ""}`
|
|
38
|
+
].filter((e) => !!e);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse an array into an arguments dictionary using the configuration.
|
|
42
|
+
*
|
|
43
|
+
* @param {string[]} args Array of arguments to be parsed
|
|
44
|
+
* @returns {object} Dictionary of arguments with defaults applied
|
|
45
|
+
*/
|
|
46
|
+
parse(args) {
|
|
47
|
+
var _a;
|
|
48
|
+
let extras = [], parsed = { ...this.defaults, "_error": [] }, queue = [...args];
|
|
49
|
+
while (queue.length) {
|
|
50
|
+
let arg = queue.splice(0, 1)[0];
|
|
51
|
+
if (arg[0] == "-") {
|
|
52
|
+
if (arg[1] != "-" && arg.length > 2) {
|
|
53
|
+
queue = [...arg.substring(2).split("").map((a2) => `-${a2}`), ...queue];
|
|
54
|
+
arg = `-${arg[1]}`;
|
|
55
|
+
}
|
|
56
|
+
const combined = arg.split("=");
|
|
57
|
+
const argDef = this.flags.find((flag) => {
|
|
58
|
+
var _a2;
|
|
59
|
+
return (_a2 = flag.flags) == null ? void 0 : _a2.includes(combined[0] || arg);
|
|
60
|
+
});
|
|
61
|
+
if (argDef == null) {
|
|
62
|
+
extras.push(arg);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const value2 = argDef.default === false ? true : argDef.default === true ? false : queue.splice(queue.findIndex((q) => q[0] != "-"), 1)[0] || argDef.default;
|
|
66
|
+
if (value2 == null) parsed["_error"].push(`Option missing value: ${argDef.name || combined[0]}`);
|
|
67
|
+
parsed[argDef.name] = value2;
|
|
68
|
+
} else {
|
|
69
|
+
const c = this.commands.find((command) => command.name == arg);
|
|
70
|
+
if (!!c) {
|
|
71
|
+
const parsedCommand = c.parse(queue.splice(0, queue.length));
|
|
72
|
+
Object.keys(parsedCommand).forEach((key) => {
|
|
73
|
+
if (parsed[key] != parsedCommand[key] && parsedCommand[key] == c.defaults[key])
|
|
74
|
+
delete parsedCommand[key];
|
|
75
|
+
});
|
|
76
|
+
parsed = {
|
|
77
|
+
...parsed,
|
|
78
|
+
...parsedCommand,
|
|
79
|
+
_command: c.name
|
|
80
|
+
};
|
|
81
|
+
} else extras.push(arg);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
this.args.filter((arg) => !arg.extras).forEach((arg) => {
|
|
85
|
+
if (!arg.optional && !extras.length) parsed["_error"].push(`Argument missing: ${arg.name.toUpperCase()}`);
|
|
86
|
+
if (extras.length) parsed[arg.name] = extras.splice(0, 1)[0];
|
|
87
|
+
});
|
|
88
|
+
const extraKey = ((_a = this.args.find((arg) => arg.extras)) == null ? void 0 : _a.name) || "_extra";
|
|
89
|
+
parsed[extraKey] = extras;
|
|
90
|
+
return parsed;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create help message from the provided description & argument list.
|
|
94
|
+
*
|
|
95
|
+
* @returns {string} Help message
|
|
96
|
+
* @param opts Help options: command - display a commands help, message - override help description
|
|
97
|
+
*/
|
|
98
|
+
help(opts = {}) {
|
|
99
|
+
const spacer = (text) => Array(24 - text.length || 1).fill(" ").join("");
|
|
100
|
+
if (opts.command) {
|
|
101
|
+
const argParser = this.commands.find((parser) => parser.name == opts.command);
|
|
102
|
+
if (!argParser) throw new Error(`${opts.command.toUpperCase()} is not a command`);
|
|
103
|
+
return argParser.help({ ...opts, command: void 0 });
|
|
104
|
+
}
|
|
105
|
+
let msg = `
|
|
106
|
+
|
|
107
|
+
${opts.message || this.desc}`;
|
|
108
|
+
msg += "\n\nUsage: " + this.examples.map((ex) => `run ${this.name} ${ex}`).join("\n ");
|
|
109
|
+
if (this.args.length) msg += "\n\n " + this.args.map((arg) => `${arg.name.toUpperCase()}${spacer(arg.name)}${arg.desc}`).join("\n ");
|
|
110
|
+
msg += "\n\nOptions:\n " + this.flags.map((flag) => {
|
|
111
|
+
var _a;
|
|
112
|
+
const flags = ((_a = flag.flags) == null ? void 0 : _a.join(", ")) || "";
|
|
113
|
+
return `${flags}${spacer(flags)}${flag.desc}`;
|
|
114
|
+
}).join("\n ");
|
|
115
|
+
if (this.commands.length) msg += "\n\nCommands:\n " + this.commands.map((command) => `${command.name}${spacer(command.name)}${command.desc}`).join("\n ");
|
|
116
|
+
return `${msg}
|
|
117
|
+
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
__publicField(_ArgParser, "helpArg", { name: "help", desc: "Display command's help message", flags: ["-h", "--help"], default: false });
|
|
122
|
+
let ArgParser = _ArgParser;
|
|
8
123
|
function clean(obj, undefinedOnly = false) {
|
|
9
124
|
if (obj == null) throw new Error("Cannot clean a NULL value");
|
|
10
125
|
if (Array.isArray(obj)) {
|
|
@@ -1541,6 +1656,7 @@ var __publicField = (obj, key, value2) => __defNormalProp(obj, typeof key !== "s
|
|
|
1541
1656
|
return Object.keys({});
|
|
1542
1657
|
}
|
|
1543
1658
|
exports.ASet = ASet;
|
|
1659
|
+
exports.ArgParser = ArgParser;
|
|
1544
1660
|
exports.BadGatewayError = BadGatewayError;
|
|
1545
1661
|
exports.BadRequestError = BadRequestError;
|
|
1546
1662
|
exports.CHAR_LIST = CHAR_LIST;
|