@ztimson/utils 0.23.2 → 0.23.3

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