Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 1x 1x 1x 1x 2x 2x 2x 1x 1x 2x 1x 1x 1x 2x 1x 1x 1x 2x 2x 2x 2x | import {ShellCommandContext} from '../Shell'; export interface ArgType { name: string; description?: string; choices?: string[]; regex?: RegExp; isOptional?: boolean; } export abstract class BaseCommand { abstract getArgTypes(): ArgType[]; autocomplete(args: string[]): string[] { const argTypes = this.getArgTypes(); const lastArgType = argTypes[args.length - 1]; Iif (!lastArgType) { return [args.join(' ')]; } const lastArg = args[args.length - 1]; Iif (lastArgType.choices) { return lastArgType.choices.filter((s) => s.startsWith(lastArg)); } return []; } abstract run(context: ShellCommandContext): Promise<void>; validateArgs(context: ShellCommandContext): boolean { let isValid = true; const argTypes = this.getArgTypes(); argTypes.forEach((argType: ArgType, argIndex: number) => { const arg = context.args[argIndex + 1]; if (!arg) { if (!argType.isOptional) { context.putString(`${argType.name} is not optional\n`); isValid = false; } return; } Iif (argType.regex) { Iif (!argType.regex.exec(arg)) { context.putString( `For ${argType.name}, "${arg}" is not valid\n` + `Must match: ${argType.regex}\n`, ); isValid = false; } } Iif (argType.choices) { Iif (!argType.choices.some((choice) => choice === arg)) { context.putString( `For ${argType.name}, "${arg}" is not a valid choice\n` + `Valid choices: ${argType.choices.join(', ')}\n`, ); isValid = false; } } }); return isValid; } printUsage(context: ShellCommandContext): void { const argTypes = this.getArgTypes(); const argUsage = argTypes .map((argType: ArgType) => `[${argType.name}]${argType.isOptional ? '?' : ''}`) .join(' '); const usageTitle = `Usage: ${context.args[0]} ${argUsage}`; context.putString(`${usageTitle}\n`); argTypes.forEach((argType: ArgType) => { const choicesString = argType.choices ? argType.choices.join(', ') : ''; const descriptionString = argType.description || ''; const argUsageDescription = `${descriptionString}${choicesString}`; context.putString(`${argType.name}: ${argUsageDescription}\n`); }); } } |