better-command 1.0.0 → 1.0.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.
@@ -0,0 +1,149 @@
1
+ // src/mod.ts
2
+ var ArgType = /* @__PURE__ */ ((ArgType2) => {
3
+ ArgType2[ArgType2["String"] = 0] = "String";
4
+ ArgType2[ArgType2["Number"] = 1] = "Number";
5
+ ArgType2[ArgType2["Boolean"] = 2] = "Boolean";
6
+ return ArgType2;
7
+ })(ArgType || {});
8
+ var arg = (name, init) => ({
9
+ ...init,
10
+ name: Array.isArray(name) ? name[0] : name,
11
+ alias: Array.isArray(name) ? name.slice(1) : [],
12
+ isArray: init.isArray ?? false,
13
+ required: init.required ?? false,
14
+ type: init.type ?? 0 /* String */
15
+ });
16
+ var parseValue = (value, type, name) => {
17
+ if (type === 1 /* Number */) {
18
+ const num = Number(value);
19
+ if (isNaN(num)) throw new Error(`Invalid number value: ${value} for ${name}`);
20
+ return num;
21
+ }
22
+ if (type === 2 /* Boolean */) {
23
+ return value.toLowerCase() === "true" || value === "1";
24
+ }
25
+ return value;
26
+ };
27
+ var parseArg = (current) => {
28
+ if (current.includes("=")) {
29
+ const [key, value] = current.split("=", 2);
30
+ return [key, value];
31
+ }
32
+ return [current, null];
33
+ };
34
+ var addOrSetValue = (result, name, value, isArray) => {
35
+ if (isArray) {
36
+ if (!result[name]) {
37
+ result[name] = [value];
38
+ } else {
39
+ result[name].push(value);
40
+ }
41
+ } else {
42
+ result[name] = value;
43
+ }
44
+ };
45
+ var isCommandParser = (obj) => {
46
+ return "parse" in obj;
47
+ };
48
+ var command = (init, ...args) => {
49
+ if (isCommandParser(init)) {
50
+ return {
51
+ ...init.opts,
52
+ name: init.opts.name,
53
+ alias: init.opts.alias ?? [],
54
+ action: (e) => {
55
+ init.parse(e.argv.splice(1), ...args);
56
+ }
57
+ };
58
+ } else {
59
+ return {
60
+ ...init,
61
+ alias: init.alias ?? []
62
+ };
63
+ }
64
+ };
65
+ var defineCommandParser = (opts, ...args) => {
66
+ const commands = opts.commands ?? [];
67
+ return {
68
+ opts,
69
+ parse: async (argv, callback = console.log, onError = (error) => {
70
+ console.error(error.message);
71
+ }) => {
72
+ argv = argv.filter(Boolean);
73
+ const currentBasicCmd = commands.find(
74
+ (cmd) => cmd.name === argv[0] || cmd.alias.includes(argv[0])
75
+ );
76
+ if (currentBasicCmd) {
77
+ currentBasicCmd.action({ opts, args, argv, commands });
78
+ return true;
79
+ }
80
+ const argMap = /* @__PURE__ */ new Map();
81
+ for (const arg2 of args) {
82
+ argMap.set(`--${arg2.name}`, arg2);
83
+ for (const alias of arg2.alias) {
84
+ argMap.set(`-${alias}`, arg2);
85
+ }
86
+ }
87
+ const result = {};
88
+ let i = 0;
89
+ let usingNamedArgs = false;
90
+ let positionalIndex = 0;
91
+ try {
92
+ while (i < argv.length) {
93
+ const current = argv[i];
94
+ if (current.startsWith("-")) {
95
+ usingNamedArgs = true;
96
+ const [key, value] = parseArg(current);
97
+ const argDef = argMap.get(key);
98
+ if (!argDef) throw new Error(`Unknown option: ${key}`);
99
+ if (argDef.type === 2 /* Boolean */) {
100
+ if (value !== null) {
101
+ addOrSetValue(result, argDef.name, value.toLowerCase() === "true" || value === "1", argDef.isArray);
102
+ } else if (i + 1 < argv.length && !argv[i + 1].startsWith("-")) {
103
+ addOrSetValue(result, argDef.name, parseValue(argv[++i], 2 /* Boolean */, argDef.name), argDef.isArray);
104
+ } else {
105
+ addOrSetValue(result, argDef.name, true, argDef.isArray);
106
+ }
107
+ i++;
108
+ } else {
109
+ if (value !== null) {
110
+ addOrSetValue(result, argDef.name, parseValue(value, argDef.type, argDef.name), argDef.isArray);
111
+ i++;
112
+ } else {
113
+ if (i + 1 >= argv.length) throw new Error(`Missing value for option: ${key}`);
114
+ addOrSetValue(result, argDef.name, parseValue(argv[++i], argDef.type, argDef.name), argDef.isArray);
115
+ i++;
116
+ }
117
+ }
118
+ } else if (usingNamedArgs) {
119
+ throw new Error(`Unexpected positional argument: ${current} after named arguments`);
120
+ } else if (positionalIndex < args.length) {
121
+ const argDef = args[positionalIndex++];
122
+ addOrSetValue(result, argDef.name, parseValue(current, argDef.type, argDef.name), argDef.isArray);
123
+ i++;
124
+ } else {
125
+ i++;
126
+ }
127
+ }
128
+ for (const argDef of args) {
129
+ if (result[argDef.name] === void 0) {
130
+ if (argDef.required) throw new Error(`Missing required argument: ${argDef.name}`);
131
+ result[argDef.name] = argDef.isArray ? [] : argDef.type === 2 /* Boolean */ ? false : void 0;
132
+ }
133
+ }
134
+ await callback(result);
135
+ return true;
136
+ } catch (error) {
137
+ onError(error instanceof Error ? error : new Error(String(error)), argv);
138
+ return false;
139
+ }
140
+ }
141
+ };
142
+ };
143
+
144
+ export {
145
+ ArgType,
146
+ arg,
147
+ command,
148
+ defineCommandParser
149
+ };
@@ -9,6 +9,7 @@ var arg = (name, init) => ({
9
9
  ...init,
10
10
  name: Array.isArray(name) ? name[0] : name,
11
11
  alias: Array.isArray(name) ? name.slice(1) : [],
12
+ isArray: init.isArray ?? false,
12
13
  required: init.required ?? false,
13
14
  type: init.type ?? 0 /* String */
14
15
  });
@@ -23,6 +24,13 @@ var parseValue = (value, type, name) => {
23
24
  }
24
25
  return value;
25
26
  };
27
+ var parseArg = (current) => {
28
+ if (current.includes("=")) {
29
+ const [key, value] = current.split("=", 2);
30
+ return [key, value];
31
+ }
32
+ return [current, null];
33
+ };
26
34
  var isCommandParser = (obj) => {
27
35
  return "parse" in obj;
28
36
  };
@@ -74,15 +82,27 @@ var defineCommandParser = (opts, ...args) => {
74
82
  const current = argv[i];
75
83
  if (current.startsWith("-")) {
76
84
  usingNamedArgs = true;
77
- const argDef = argMap.get(current);
78
- if (!argDef) throw new Error(`Unknown option: ${current}`);
85
+ const [key, value] = parseArg(current);
86
+ const argDef = argMap.get(key);
87
+ if (!argDef) throw new Error(`Unknown option: ${key}`);
79
88
  if (argDef.type === 2 /* Boolean */) {
80
- result[argDef.name] = true;
89
+ if (value !== null) {
90
+ result[argDef.name] = value.toLowerCase() === "true" || value === "1";
91
+ } else if (i + 1 < argv.length && !argv[i + 1].startsWith("-")) {
92
+ result[argDef.name] = parseValue(argv[++i], 2 /* Boolean */, argDef.name);
93
+ } else {
94
+ result[argDef.name] = true;
95
+ }
81
96
  i++;
82
97
  } else {
83
- if (i + 1 >= argv.length) throw new Error(`Missing value for option: ${current}`);
84
- result[argDef.name] = parseValue(argv[++i], argDef.type, argDef.name);
85
- i++;
98
+ if (value !== null) {
99
+ result[argDef.name] = parseValue(value, argDef.type, argDef.name);
100
+ i++;
101
+ } else {
102
+ if (i + 1 >= argv.length) throw new Error(`Missing value for option: ${key}`);
103
+ result[argDef.name] = parseValue(argv[++i], argDef.type, argDef.name);
104
+ i++;
105
+ }
86
106
  }
87
107
  } else if (usingNamedArgs) {
88
108
  throw new Error(`Unexpected positional argument: ${current} after named arguments`);
package/dist/mod.d.ts CHANGED
@@ -5,7 +5,7 @@ declare enum ArgType {
5
5
  }
6
6
  type CommandActionEvent<T extends CommandParserInit = CommandParserInit> = {
7
7
  opts: T;
8
- args: readonly ArgumentObject<any, any>[];
8
+ args: readonly ArgumentObject[];
9
9
  argv: string[];
10
10
  commands: CommandObject[];
11
11
  };
@@ -15,30 +15,32 @@ declare interface Command {
15
15
  }
16
16
  declare interface CommandParserOpts extends Command {
17
17
  }
18
- type ArgumentObject<TName extends string = string, TRequired extends boolean = false, TType extends ArgType = ArgType> = Argument & {
18
+ type ArgumentObject<TName extends string = string, TRequired extends boolean = false, TAaray extends boolean = false, TType extends ArgType = ArgType> = Argument & {
19
19
  name: TName;
20
20
  alias: string[];
21
21
  type: TType;
22
22
  required: TRequired;
23
+ isArray: TAaray;
23
24
  };
24
25
  type CommandObject = Command & {
25
26
  name: string;
26
27
  alias: string[];
27
28
  action: (e: CommandActionEvent) => void;
28
29
  };
29
- type CommandParserObject<T extends readonly ArgumentObject<any, any>[], Opts extends CommandParserInit = CommandParserInit> = {
30
+ type CommandParserObject<T extends readonly ArgumentObject<any, any, any, any>[], Opts extends CommandParserInit = CommandParserInit> = {
30
31
  opts: Opts;
31
- parse: (argv: string[], callback: (args: ArgumentsToObject<T>) => void, onError?: (err: Error, args: string[]) => void) => void;
32
+ parse: (argv: string[], callback: (args: ArgumentsToObject<T>) => void, onError?: (err: Error, args: string[]) => void) => Promise<boolean>;
32
33
  };
33
34
  type ArgTypeToTS<T extends ArgType> = T extends ArgType.String ? string : T extends ArgType.Number ? number : T extends ArgType.Boolean ? boolean : never;
34
- type ArgumentsToObject<T extends readonly ArgumentObject<any, any>[]> = {
35
- [P in T[number] as P['name']]: P extends ArgumentObject<any, true, any> ? ArgTypeToTS<P['type']> : ArgTypeToTS<P['type']> | undefined;
35
+ type ArgumentsToObject<T extends readonly ArgumentObject<any, any, any, any>[]> = {
36
+ [P in T[number] as P['name']]: P extends ArgumentObject<any, any, true, any> ? ArgTypeToTS<P['type']>[] : P extends ArgumentObject<any, true, false, any> ? ArgTypeToTS<P['type']> : ArgTypeToTS<P['type']> | undefined;
36
37
  };
37
- interface CommandArgInit<TType extends ArgType = ArgType, TRequired extends boolean = false> extends Argument {
38
+ interface CommandArgInit<TType extends ArgType = ArgType, TRequired extends boolean = false, TAaray extends boolean = false> extends Argument {
38
39
  type: TType;
39
40
  required?: TRequired;
41
+ isArray?: TAaray;
40
42
  }
41
- declare const arg: <const TName extends string, const TRequired extends boolean = false, TType extends ArgType = ArgType.String>(name: TName | [TName, ...string[]], init: CommandArgInit<TType, TRequired>) => ArgumentObject<TName, TRequired, TType>;
43
+ declare const arg: <const TName extends string, const TRequired extends boolean = false, const TArray extends boolean = false, const TType extends ArgType = ArgType.String>(name: TName | [TName, ...string[]], init: CommandArgInit<TType, TRequired, TArray>) => ArgumentObject<TName, TRequired, TArray, TType>;
42
44
  interface CommandInit extends Command {
43
45
  name: string;
44
46
  alias?: string[];
@@ -50,6 +52,6 @@ interface CommandParserInit extends CommandParserOpts {
50
52
  alias?: string[];
51
53
  commands?: CommandObject[];
52
54
  }
53
- declare const defineCommandParser: <Opts extends CommandParserInit, T extends readonly ArgumentObject<any, any>[]>(opts: Opts, ...args: T) => CommandParserObject<T, Opts>;
55
+ declare const defineCommandParser: <Opts extends CommandParserInit, T extends readonly ArgumentObject<any, any, any, any>[]>(opts: Opts, ...args: T) => CommandParserObject<T, Opts>;
54
56
 
55
57
  export { ArgType, type Argument, type ArgumentObject, type Command, type CommandActionEvent, type CommandObject, type CommandParserObject, type CommandParserOpts, arg, command, defineCommandParser };
package/dist/mod.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  arg,
4
4
  command,
5
5
  defineCommandParser
6
- } from "./chunk-QDFNMQ2V.js";
6
+ } from "./chunk-EQS53463.js";
7
7
  export {
8
8
  ArgType,
9
9
  arg,
package/dist/plugin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ArgType,
3
3
  command
4
- } from "./chunk-QDFNMQ2V.js";
4
+ } from "./chunk-EQS53463.js";
5
5
 
6
6
  // src/plugin.ts
7
7
  var helpCommand = command({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-command",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "license": "MIT",
5
5
  "description": "一个轻量化的类型友好的命令行解析工具,适用于Bun运行时",
6
6
  "repository": {