chrome-cdp-cli 2.0.4 → 2.1.0
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/cli/ArgumentParser.js +172 -91
- package/dist/cli/CLIApplication.js +181 -57
- package/dist/cli/CommandRouter.js +98 -74
- package/dist/cli/CommandSchemaRegistry.js +506 -398
- package/dist/cli/EnhancedCLIInterface.js +2 -1
- package/dist/cli/HelpSystem.js +286 -256
- package/dist/handlers/ClickHandler.js +91 -27
- package/dist/handlers/InstallClaudeSkillHandler.js +220 -220
- package/dist/handlers/InstallCursorCommandHandler.js +60 -60
- package/dist/handlers/ListConsoleMessagesHandler.js +126 -178
- package/dist/handlers/ListNetworkRequestsHandler.js +128 -108
- package/dist/handlers/RestartProxyHandler.js +4 -4
- package/dist/handlers/TakeScreenshotHandler.js +70 -59
- package/dist/handlers/TakeSnapshotHandler.js +223 -165
- package/dist/handlers/index.js +0 -1
- package/dist/monitors/ConsoleMonitor.js +29 -0
- package/dist/monitors/NetworkMonitor.js +43 -19
- package/dist/proxy/server/CDPProxyServer.js +5 -1
- package/dist/proxy/server/CommandExecutionService.js +1 -1
- package/dist/proxy/server/ProxyAPIServer.js +11 -6
- package/package.json +3 -2
|
@@ -6,23 +6,87 @@ class ArgumentParser {
|
|
|
6
6
|
constructor() {
|
|
7
7
|
this.commands = new Map();
|
|
8
8
|
this.aliases = new Map();
|
|
9
|
+
this.globalOptionDefs = [
|
|
10
|
+
{
|
|
11
|
+
name: "host",
|
|
12
|
+
short: "h",
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "Chrome host address",
|
|
15
|
+
default: "localhost",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: "port",
|
|
19
|
+
short: "p",
|
|
20
|
+
type: "number",
|
|
21
|
+
description: "DevTools port",
|
|
22
|
+
default: 9222,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "format",
|
|
26
|
+
short: "f",
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Output format",
|
|
29
|
+
choices: ["json", "text"],
|
|
30
|
+
default: "text",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "verbose",
|
|
34
|
+
short: "v",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "Enable verbose logging",
|
|
37
|
+
default: false,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "quiet",
|
|
41
|
+
short: "q",
|
|
42
|
+
type: "boolean",
|
|
43
|
+
description: "Enable quiet mode",
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "timeout",
|
|
48
|
+
short: "t",
|
|
49
|
+
type: "number",
|
|
50
|
+
description: "Command timeout in milliseconds",
|
|
51
|
+
default: 30000,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "debug",
|
|
55
|
+
short: "d",
|
|
56
|
+
type: "boolean",
|
|
57
|
+
description: "Enable debug logging",
|
|
58
|
+
default: false,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "config",
|
|
62
|
+
short: "c",
|
|
63
|
+
type: "string",
|
|
64
|
+
description: "Configuration file path",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "target-index",
|
|
68
|
+
short: "i",
|
|
69
|
+
type: "number",
|
|
70
|
+
description: "Target page index (1-based, excludes DevTools windows)",
|
|
71
|
+
},
|
|
72
|
+
];
|
|
9
73
|
this.helpSystem = new HelpSystem_1.HelpSystem(undefined, this);
|
|
10
74
|
}
|
|
11
75
|
parseArguments(argv) {
|
|
12
76
|
try {
|
|
13
77
|
if (!Array.isArray(argv)) {
|
|
14
|
-
return this.createParseResult(
|
|
78
|
+
return this.createParseResult("help", {}, [], true);
|
|
15
79
|
}
|
|
16
80
|
const sliceStart = Math.max(0, Math.min(2, argv.length));
|
|
17
81
|
const args = argv.slice(sliceStart);
|
|
18
82
|
if (args.length === 0) {
|
|
19
|
-
return this.createParseResult(
|
|
83
|
+
return this.createParseResult("help", {}, [], true);
|
|
20
84
|
}
|
|
21
|
-
if (args.includes(
|
|
22
|
-
return this.createParseResult(
|
|
85
|
+
if (args.includes("--help")) {
|
|
86
|
+
return this.createParseResult("help", {}, [], true);
|
|
23
87
|
}
|
|
24
|
-
if (args.includes(
|
|
25
|
-
return this.createParseResult(
|
|
88
|
+
if (args.includes("--version") || args.includes("-V")) {
|
|
89
|
+
return this.createParseResult("version", {}, [], true);
|
|
26
90
|
}
|
|
27
91
|
let globalOptions;
|
|
28
92
|
let commandName;
|
|
@@ -34,41 +98,49 @@ class ArgumentParser {
|
|
|
34
98
|
commandArgs = parseResult.commandArgs;
|
|
35
99
|
}
|
|
36
100
|
catch (parseError) {
|
|
37
|
-
if (args.some(arg => arg ===
|
|
38
|
-
return this.createParseResult(
|
|
101
|
+
if (args.some((arg) => arg === "--help" || arg === "help")) {
|
|
102
|
+
return this.createParseResult("help", {}, [], true);
|
|
39
103
|
}
|
|
40
104
|
throw parseError;
|
|
41
105
|
}
|
|
42
106
|
const resolvedCommand = this.resolveCommandName(commandName);
|
|
43
|
-
if (resolvedCommand ===
|
|
107
|
+
if (resolvedCommand === "help") {
|
|
44
108
|
return this.createParseResult(resolvedCommand, globalOptions, [], true, commandArgs);
|
|
45
109
|
}
|
|
46
110
|
const commandDef = this.commands.get(resolvedCommand);
|
|
47
111
|
if (!commandDef) {
|
|
48
|
-
return this.createParseResult(resolvedCommand, globalOptions, [
|
|
112
|
+
return this.createParseResult(resolvedCommand, globalOptions, [
|
|
113
|
+
`Unknown command: ${commandName}. Use 'help' to see available commands.`,
|
|
114
|
+
], false);
|
|
49
115
|
}
|
|
50
116
|
const parseResult = this.parseCommandArguments(commandDef, commandArgs);
|
|
51
|
-
const allOptions = {
|
|
117
|
+
const allOptions = {
|
|
118
|
+
...globalOptions,
|
|
119
|
+
...parseResult.globalOptions,
|
|
120
|
+
...parseResult.options,
|
|
121
|
+
};
|
|
52
122
|
return this.createParseResult(resolvedCommand, allOptions, parseResult.errors, parseResult.errors.length === 0, parseResult.arguments);
|
|
53
123
|
}
|
|
54
124
|
catch (error) {
|
|
55
125
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
56
126
|
if (process.env.DEBUG) {
|
|
57
|
-
console.error(
|
|
127
|
+
console.error("Parse error details:", error);
|
|
58
128
|
if (error instanceof Error && error.stack) {
|
|
59
|
-
console.error(
|
|
129
|
+
console.error("Stack trace:", error.stack);
|
|
60
130
|
}
|
|
61
131
|
}
|
|
62
|
-
if (errorMessage.includes(
|
|
63
|
-
return this.createParseResult(
|
|
132
|
+
if (errorMessage.includes("Invalid count value")) {
|
|
133
|
+
return this.createParseResult("help", {}, [
|
|
134
|
+
`Parse error: Invalid argument format. Please check your command syntax.`,
|
|
135
|
+
], false);
|
|
64
136
|
}
|
|
65
|
-
return this.createParseResult(
|
|
137
|
+
return this.createParseResult("help", {}, [`Parse error: ${errorMessage}`], false);
|
|
66
138
|
}
|
|
67
139
|
}
|
|
68
140
|
registerCommand(command) {
|
|
69
141
|
const validation = this.validateCommandDefinition(command);
|
|
70
142
|
if (!validation.valid) {
|
|
71
|
-
throw new Error(`Invalid command definition: ${validation.errors.join(
|
|
143
|
+
throw new Error(`Invalid command definition: ${validation.errors.join(", ")}`);
|
|
72
144
|
}
|
|
73
145
|
this.commands.set(command.name, command);
|
|
74
146
|
for (const alias of command.aliases) {
|
|
@@ -80,7 +152,7 @@ class ArgumentParser {
|
|
|
80
152
|
}
|
|
81
153
|
generateHelp(command) {
|
|
82
154
|
if (command) {
|
|
83
|
-
if (command.startsWith(
|
|
155
|
+
if (command.startsWith("topic ")) {
|
|
84
156
|
const topicName = command.substring(6);
|
|
85
157
|
return this.helpSystem.generateTopicHelp(topicName);
|
|
86
158
|
}
|
|
@@ -94,7 +166,7 @@ class ArgumentParser {
|
|
|
94
166
|
return {
|
|
95
167
|
valid: false,
|
|
96
168
|
errors: [`Unknown command: ${command}`],
|
|
97
|
-
warnings: []
|
|
169
|
+
warnings: [],
|
|
98
170
|
};
|
|
99
171
|
}
|
|
100
172
|
const errors = [];
|
|
@@ -104,23 +176,27 @@ class ArgumentParser {
|
|
|
104
176
|
errors.push(`Required option --${option.name} is missing`);
|
|
105
177
|
}
|
|
106
178
|
}
|
|
107
|
-
const requiredArgs = commandDef.arguments.filter(arg => arg.required);
|
|
179
|
+
const requiredArgs = commandDef.arguments.filter((arg) => arg.required);
|
|
108
180
|
if (args.arguments.length < requiredArgs.length) {
|
|
109
181
|
const providedCount = Math.max(0, Math.min(args.arguments.length, requiredArgs.length));
|
|
110
182
|
const missingCount = Math.max(0, requiredArgs.length - providedCount);
|
|
111
183
|
if (missingCount > 0) {
|
|
112
184
|
const startIndex = Math.max(0, providedCount);
|
|
113
185
|
const endIndex = Math.min(requiredArgs.length, startIndex + missingCount);
|
|
114
|
-
if (startIndex < endIndex &&
|
|
115
|
-
|
|
186
|
+
if (startIndex < endIndex &&
|
|
187
|
+
startIndex >= 0 &&
|
|
188
|
+
endIndex <= requiredArgs.length) {
|
|
189
|
+
const missingArgs = requiredArgs
|
|
190
|
+
.slice(startIndex, endIndex)
|
|
191
|
+
.map((arg) => arg.name);
|
|
116
192
|
if (missingArgs.length > 0) {
|
|
117
|
-
errors.push(`Missing required arguments: ${missingArgs.join(
|
|
193
|
+
errors.push(`Missing required arguments: ${missingArgs.join(", ")}`);
|
|
118
194
|
}
|
|
119
195
|
}
|
|
120
196
|
}
|
|
121
197
|
}
|
|
122
198
|
for (const [optionName, value] of Object.entries(args.options)) {
|
|
123
|
-
const optionDef = commandDef.options.find(opt => opt.name === optionName);
|
|
199
|
+
const optionDef = commandDef.options.find((opt) => opt.name === optionName);
|
|
124
200
|
if (optionDef) {
|
|
125
201
|
const optionValidation = this.validateOptionValue(optionDef, value);
|
|
126
202
|
if (!optionValidation.valid) {
|
|
@@ -142,30 +218,21 @@ class ArgumentParser {
|
|
|
142
218
|
return {
|
|
143
219
|
valid: errors.length === 0,
|
|
144
220
|
errors,
|
|
145
|
-
warnings
|
|
221
|
+
warnings,
|
|
146
222
|
};
|
|
147
223
|
}
|
|
148
224
|
parseGlobalAndCommand(args) {
|
|
149
|
-
if (args.includes(
|
|
150
|
-
return { globalOptions: {}, commandName:
|
|
225
|
+
if (args.includes("--help")) {
|
|
226
|
+
return { globalOptions: {}, commandName: "help", commandArgs: [] };
|
|
151
227
|
}
|
|
152
228
|
const globalOptions = {};
|
|
153
|
-
let commandName =
|
|
229
|
+
let commandName = "help";
|
|
154
230
|
let commandArgs = [];
|
|
155
231
|
let i = 0;
|
|
156
|
-
const globalOptionDefs =
|
|
157
|
-
{ name: 'host', short: 'h', type: 'string', description: 'Chrome host address', default: 'localhost' },
|
|
158
|
-
{ name: 'port', short: 'p', type: 'number', description: 'DevTools port', default: 9222 },
|
|
159
|
-
{ name: 'format', short: 'f', type: 'string', description: 'Output format', choices: ['json', 'text'], default: 'text' },
|
|
160
|
-
{ name: 'verbose', short: 'v', type: 'boolean', description: 'Enable verbose logging', default: false },
|
|
161
|
-
{ name: 'quiet', short: 'q', type: 'boolean', description: 'Enable quiet mode', default: false },
|
|
162
|
-
{ name: 'timeout', short: 't', type: 'number', description: 'Command timeout in milliseconds', default: 30000 },
|
|
163
|
-
{ name: 'debug', short: 'd', type: 'boolean', description: 'Enable debug logging', default: false },
|
|
164
|
-
{ name: 'config', short: 'c', type: 'string', description: 'Configuration file path' }
|
|
165
|
-
];
|
|
232
|
+
const globalOptionDefs = this.globalOptionDefs;
|
|
166
233
|
while (i < args.length) {
|
|
167
234
|
const arg = args[i];
|
|
168
|
-
if (arg.startsWith(
|
|
235
|
+
if (arg.startsWith("--")) {
|
|
169
236
|
const { option, value, consumed } = this.parseLongOption(arg, args, i, globalOptionDefs);
|
|
170
237
|
if (option) {
|
|
171
238
|
globalOptions[option.name] = value;
|
|
@@ -184,7 +251,7 @@ class ArgumentParser {
|
|
|
184
251
|
break;
|
|
185
252
|
}
|
|
186
253
|
}
|
|
187
|
-
else if (arg.startsWith(
|
|
254
|
+
else if (arg.startsWith("-") && arg.length > 1) {
|
|
188
255
|
const { option, value, consumed } = this.parseShortOption(arg, args, i, globalOptionDefs);
|
|
189
256
|
if (option) {
|
|
190
257
|
globalOptions[option.name] = value;
|
|
@@ -221,25 +288,25 @@ class ArgumentParser {
|
|
|
221
288
|
let optionName = arg.substring(2);
|
|
222
289
|
let value;
|
|
223
290
|
let consumed = 1;
|
|
224
|
-
const equalIndex = optionName.indexOf(
|
|
291
|
+
const equalIndex = optionName.indexOf("=");
|
|
225
292
|
if (equalIndex !== -1) {
|
|
226
293
|
value = optionName.substring(equalIndex + 1);
|
|
227
294
|
optionName = optionName.substring(0, equalIndex);
|
|
228
295
|
}
|
|
229
296
|
let isNegated = false;
|
|
230
|
-
if (optionName.startsWith(
|
|
297
|
+
if (optionName.startsWith("no-")) {
|
|
231
298
|
isNegated = true;
|
|
232
299
|
optionName = optionName.substring(3);
|
|
233
300
|
}
|
|
234
|
-
const optionDef = optionDefs.find(opt => opt.name === optionName);
|
|
301
|
+
const optionDef = optionDefs.find((opt) => opt.name === optionName);
|
|
235
302
|
if (!optionDef) {
|
|
236
303
|
return { option: null, value: null, consumed: 0 };
|
|
237
304
|
}
|
|
238
|
-
if (optionDef.type ===
|
|
305
|
+
if (optionDef.type === "boolean") {
|
|
239
306
|
value = !isNegated;
|
|
240
307
|
}
|
|
241
308
|
else if (value === undefined) {
|
|
242
|
-
if (index + 1 < args.length && !args[index + 1].startsWith(
|
|
309
|
+
if (index + 1 < args.length && !args[index + 1].startsWith("-")) {
|
|
243
310
|
value = args[index + 1];
|
|
244
311
|
consumed = 2;
|
|
245
312
|
}
|
|
@@ -255,17 +322,17 @@ class ArgumentParser {
|
|
|
255
322
|
if (shortName.length > 1) {
|
|
256
323
|
return { option: null, value: null, consumed: 0 };
|
|
257
324
|
}
|
|
258
|
-
const optionDef = optionDefs.find(opt => opt.short === shortName);
|
|
325
|
+
const optionDef = optionDefs.find((opt) => opt.short === shortName);
|
|
259
326
|
if (!optionDef) {
|
|
260
327
|
return { option: null, value: null, consumed: 0 };
|
|
261
328
|
}
|
|
262
329
|
let value;
|
|
263
330
|
let consumed = 1;
|
|
264
|
-
if (optionDef.type ===
|
|
331
|
+
if (optionDef.type === "boolean") {
|
|
265
332
|
value = true;
|
|
266
333
|
}
|
|
267
334
|
else {
|
|
268
|
-
if (index + 1 < args.length && !args[index + 1].startsWith(
|
|
335
|
+
if (index + 1 < args.length && !args[index + 1].startsWith("-")) {
|
|
269
336
|
value = args[index + 1];
|
|
270
337
|
consumed = 2;
|
|
271
338
|
}
|
|
@@ -286,49 +353,54 @@ class ArgumentParser {
|
|
|
286
353
|
}
|
|
287
354
|
parseCommandArguments(commandDef, args) {
|
|
288
355
|
const options = {};
|
|
356
|
+
const lateGlobalOptions = {};
|
|
289
357
|
const arguments_ = [];
|
|
290
358
|
const errors = [];
|
|
291
359
|
let i = 0;
|
|
292
360
|
while (i < args.length) {
|
|
293
361
|
const arg = args[i];
|
|
294
|
-
if (arg.startsWith(
|
|
362
|
+
if (arg.startsWith("--")) {
|
|
295
363
|
try {
|
|
296
364
|
const { option, value, consumed } = this.parseLongOption(arg, args, i, commandDef.options);
|
|
297
365
|
if (option) {
|
|
298
366
|
options[option.name] = value;
|
|
299
|
-
|
|
300
|
-
|
|
367
|
+
i += consumed > 0 ? consumed : 1;
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
const { option: gOpt, value: gVal, consumed: gConsumed, } = this.parseLongOption(arg, args, i, this.globalOptionDefs);
|
|
371
|
+
if (gOpt) {
|
|
372
|
+
lateGlobalOptions[gOpt.name] = gVal;
|
|
373
|
+
i += gConsumed > 0 ? gConsumed : 1;
|
|
301
374
|
}
|
|
302
375
|
else {
|
|
376
|
+
errors.push(`Unknown option: ${arg}`);
|
|
303
377
|
i++;
|
|
304
378
|
}
|
|
305
379
|
}
|
|
306
|
-
else {
|
|
307
|
-
errors.push(`Unknown option: ${arg}`);
|
|
308
|
-
i++;
|
|
309
|
-
}
|
|
310
380
|
}
|
|
311
381
|
catch (error) {
|
|
312
382
|
errors.push(error instanceof Error ? error.message : String(error));
|
|
313
383
|
i++;
|
|
314
384
|
}
|
|
315
385
|
}
|
|
316
|
-
else if (arg.startsWith(
|
|
386
|
+
else if (arg.startsWith("-") && arg.length > 1) {
|
|
317
387
|
try {
|
|
318
388
|
const { option, value, consumed } = this.parseShortOption(arg, args, i, commandDef.options);
|
|
319
389
|
if (option) {
|
|
320
390
|
options[option.name] = value;
|
|
321
|
-
|
|
322
|
-
|
|
391
|
+
i += consumed > 0 ? consumed : 1;
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
const { option: gOpt, value: gVal, consumed: gConsumed, } = this.parseShortOption(arg, args, i, this.globalOptionDefs);
|
|
395
|
+
if (gOpt) {
|
|
396
|
+
lateGlobalOptions[gOpt.name] = gVal;
|
|
397
|
+
i += gConsumed > 0 ? gConsumed : 1;
|
|
323
398
|
}
|
|
324
399
|
else {
|
|
400
|
+
errors.push(`Unknown option: ${arg}`);
|
|
325
401
|
i++;
|
|
326
402
|
}
|
|
327
403
|
}
|
|
328
|
-
else {
|
|
329
|
-
errors.push(`Unknown option: ${arg}`);
|
|
330
|
-
i++;
|
|
331
|
-
}
|
|
332
404
|
}
|
|
333
405
|
catch (error) {
|
|
334
406
|
errors.push(error instanceof Error ? error.message : String(error));
|
|
@@ -340,7 +412,12 @@ class ArgumentParser {
|
|
|
340
412
|
i++;
|
|
341
413
|
}
|
|
342
414
|
}
|
|
343
|
-
return {
|
|
415
|
+
return {
|
|
416
|
+
options,
|
|
417
|
+
globalOptions: lateGlobalOptions,
|
|
418
|
+
arguments: arguments_,
|
|
419
|
+
errors,
|
|
420
|
+
};
|
|
344
421
|
}
|
|
345
422
|
convertOptionValue(optionDef, value) {
|
|
346
423
|
if (value === undefined || value === null) {
|
|
@@ -348,32 +425,36 @@ class ArgumentParser {
|
|
|
348
425
|
}
|
|
349
426
|
const stringValue = String(value);
|
|
350
427
|
switch (optionDef.type) {
|
|
351
|
-
case
|
|
428
|
+
case "number": {
|
|
352
429
|
const numValue = Number(stringValue);
|
|
353
430
|
if (isNaN(numValue)) {
|
|
354
431
|
throw new Error(`Option --${optionDef.name} must be a number, got: ${stringValue}`);
|
|
355
432
|
}
|
|
356
433
|
return numValue;
|
|
357
434
|
}
|
|
358
|
-
case
|
|
359
|
-
if (typeof value ===
|
|
435
|
+
case "boolean": {
|
|
436
|
+
if (typeof value === "boolean") {
|
|
360
437
|
return value;
|
|
361
438
|
}
|
|
362
439
|
const lowerValue = stringValue.toLowerCase();
|
|
363
|
-
if (lowerValue ===
|
|
440
|
+
if (lowerValue === "true" ||
|
|
441
|
+
lowerValue === "1" ||
|
|
442
|
+
lowerValue === "yes") {
|
|
364
443
|
return true;
|
|
365
444
|
}
|
|
366
|
-
if (lowerValue ===
|
|
445
|
+
if (lowerValue === "false" ||
|
|
446
|
+
lowerValue === "0" ||
|
|
447
|
+
lowerValue === "no") {
|
|
367
448
|
return false;
|
|
368
449
|
}
|
|
369
450
|
throw new Error(`Option --${optionDef.name} must be a boolean, got: ${stringValue}`);
|
|
370
451
|
}
|
|
371
|
-
case
|
|
452
|
+
case "array":
|
|
372
453
|
if (Array.isArray(value)) {
|
|
373
454
|
return value;
|
|
374
455
|
}
|
|
375
|
-
return stringValue.split(
|
|
376
|
-
case
|
|
456
|
+
return stringValue.split(",").map((s) => s.trim());
|
|
457
|
+
case "string":
|
|
377
458
|
default:
|
|
378
459
|
return stringValue;
|
|
379
460
|
}
|
|
@@ -383,7 +464,7 @@ class ArgumentParser {
|
|
|
383
464
|
const warnings = [];
|
|
384
465
|
if (optionDef.choices && optionDef.choices.length > 0) {
|
|
385
466
|
if (!optionDef.choices.includes(String(value))) {
|
|
386
|
-
errors.push(`Option --${optionDef.name} must be one of: ${optionDef.choices.join(
|
|
467
|
+
errors.push(`Option --${optionDef.name} must be one of: ${optionDef.choices.join(", ")}`);
|
|
387
468
|
}
|
|
388
469
|
}
|
|
389
470
|
if (optionDef.validator) {
|
|
@@ -396,24 +477,24 @@ class ArgumentParser {
|
|
|
396
477
|
return {
|
|
397
478
|
valid: errors.length === 0,
|
|
398
479
|
errors,
|
|
399
|
-
warnings
|
|
480
|
+
warnings,
|
|
400
481
|
};
|
|
401
482
|
}
|
|
402
483
|
validateArgumentValue(argDef, value) {
|
|
403
484
|
const errors = [];
|
|
404
485
|
const warnings = [];
|
|
405
486
|
switch (argDef.type) {
|
|
406
|
-
case
|
|
487
|
+
case "number":
|
|
407
488
|
if (isNaN(Number(value))) {
|
|
408
489
|
errors.push(`Argument ${argDef.name} must be a number, got: ${value}`);
|
|
409
490
|
}
|
|
410
491
|
break;
|
|
411
|
-
case
|
|
412
|
-
if (typeof value !==
|
|
492
|
+
case "file":
|
|
493
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
413
494
|
errors.push(`Argument ${argDef.name} must be a valid file path`);
|
|
414
495
|
}
|
|
415
496
|
break;
|
|
416
|
-
case
|
|
497
|
+
case "url":
|
|
417
498
|
try {
|
|
418
499
|
new URL(String(value));
|
|
419
500
|
}
|
|
@@ -432,7 +513,7 @@ class ArgumentParser {
|
|
|
432
513
|
return {
|
|
433
514
|
valid: errors.length === 0,
|
|
434
515
|
errors,
|
|
435
|
-
warnings
|
|
516
|
+
warnings,
|
|
436
517
|
};
|
|
437
518
|
}
|
|
438
519
|
resolveCommandName(commandName) {
|
|
@@ -440,41 +521,41 @@ class ArgumentParser {
|
|
|
440
521
|
}
|
|
441
522
|
validateCommandDefinition(command) {
|
|
442
523
|
const errors = [];
|
|
443
|
-
if (!command.name || typeof command.name !==
|
|
444
|
-
errors.push(
|
|
524
|
+
if (!command.name || typeof command.name !== "string") {
|
|
525
|
+
errors.push("Command name is required and must be a string");
|
|
445
526
|
}
|
|
446
|
-
if (!command.description || typeof command.description !==
|
|
447
|
-
errors.push(
|
|
527
|
+
if (!command.description || typeof command.description !== "string") {
|
|
528
|
+
errors.push("Command description is required and must be a string");
|
|
448
529
|
}
|
|
449
530
|
if (!Array.isArray(command.aliases)) {
|
|
450
|
-
errors.push(
|
|
531
|
+
errors.push("Command aliases must be an array");
|
|
451
532
|
}
|
|
452
533
|
if (!Array.isArray(command.options)) {
|
|
453
|
-
errors.push(
|
|
534
|
+
errors.push("Command options must be an array");
|
|
454
535
|
}
|
|
455
536
|
if (!Array.isArray(command.arguments)) {
|
|
456
|
-
errors.push(
|
|
537
|
+
errors.push("Command arguments must be an array");
|
|
457
538
|
}
|
|
458
539
|
for (const option of command.options) {
|
|
459
|
-
if (!option.name || typeof option.name !==
|
|
540
|
+
if (!option.name || typeof option.name !== "string") {
|
|
460
541
|
errors.push(`Option name is required and must be a string`);
|
|
461
542
|
}
|
|
462
|
-
if (![
|
|
543
|
+
if (!["string", "number", "boolean", "array"].includes(option.type)) {
|
|
463
544
|
errors.push(`Option ${option.name} has invalid type: ${option.type}`);
|
|
464
545
|
}
|
|
465
546
|
}
|
|
466
547
|
for (const arg of command.arguments) {
|
|
467
|
-
if (!arg.name || typeof arg.name !==
|
|
548
|
+
if (!arg.name || typeof arg.name !== "string") {
|
|
468
549
|
errors.push(`Argument name is required and must be a string`);
|
|
469
550
|
}
|
|
470
|
-
if (![
|
|
551
|
+
if (!["string", "number", "file", "url"].includes(arg.type)) {
|
|
471
552
|
errors.push(`Argument ${arg.name} has invalid type: ${arg.type}`);
|
|
472
553
|
}
|
|
473
554
|
}
|
|
474
555
|
return {
|
|
475
556
|
valid: errors.length === 0,
|
|
476
557
|
errors,
|
|
477
|
-
warnings: []
|
|
558
|
+
warnings: [],
|
|
478
559
|
};
|
|
479
560
|
}
|
|
480
561
|
createParseResult(command, options, errors, success, arguments_ = []) {
|
|
@@ -484,7 +565,7 @@ class ArgumentParser {
|
|
|
484
565
|
options,
|
|
485
566
|
arguments: arguments_,
|
|
486
567
|
errors,
|
|
487
|
-
warnings: []
|
|
568
|
+
warnings: [],
|
|
488
569
|
};
|
|
489
570
|
}
|
|
490
571
|
getCommands() {
|