UNPKG

4.72 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const yargs_parser_1 = __importDefault(require("yargs-parser"));
7const Output_1 = require("../Output");
8class CliService {
9 constructor(commandManager, config = {}) {
10 this.programs = {};
11 /**
12 * Lookup index linking to commands in programs.
13 */
14 this.commands = {};
15 this.config = config;
16 this.commandManager = commandManager;
17 if (config.commands) {
18 this.registerPrograms(config.commands);
19 }
20 }
21 resolveToken(args) {
22 if (args.help) {
23 return this.config.fallbackToken;
24 }
25 return args._.shift() || this.config.fallbackToken;
26 }
27 async execute(argv) {
28 const output = await this.resolve(argv);
29 output.send();
30 }
31 async resolve(argv) {
32 const parsed = yargs_parser_1.default(argv, { alias: { h: 'help' } });
33 const token = this.resolveToken(parsed);
34 const command = this.commands[token];
35 const output = new Output_1.Output();
36 // Remove the token so we're left with the arguments.
37 if (token === argv[0]) {
38 argv.splice(0, 1);
39 }
40 if (!command) {
41 return output.error(`Unknown command "${token}".`);
42 }
43 const commandInstance = this.commandManager.getCommand(command.Command);
44 try {
45 await commandInstance[command.action](output, this.validate(argv, command));
46 }
47 catch (error) {
48 output.error(error);
49 }
50 return output;
51 }
52 validate(argv, command) {
53 const alias = this.collectAliases(command);
54 const parsed = yargs_parser_1.default(argv, { alias });
55 const args = {};
56 if (Array.isArray(command.args)) {
57 command.args.forEach(({ required, name }, index) => {
58 if (required && !parsed._[index]) {
59 throw `Missing required argument "${name}".`;
60 }
61 if (parsed._[index]) {
62 args[name] = parsed._[index];
63 }
64 });
65 }
66 if (!command.config || !command.config.options) {
67 return args;
68 }
69 Object.keys(command.config.options).forEach(option => {
70 if (command.config.options[option].required && !parsed[option]) {
71 throw `Missing required option "${option}".`;
72 }
73 args[option] = parsed[option];
74 });
75 return args;
76 }
77 collectAliases({ config }) {
78 if (!config || !config.options) {
79 return {};
80 }
81 return Object.keys(config.options).reduce((aliases, name) => {
82 if (config.options[name].alias) {
83 aliases[name] = config.options[name].alias;
84 }
85 return aliases;
86 }, {});
87 }
88 getPrograms() {
89 return this.programs;
90 }
91 getCommands() {
92 return this.commands;
93 }
94 getCommand(command) {
95 return this.commands[command];
96 }
97 getConfig() {
98 return this.config;
99 }
100 registerPrograms(programs) {
101 programs.forEach((programEntry) => {
102 const programName = programEntry.program || this.config.defaultProgramName;
103 const programConfig = (programEntry.config || { commands: [programEntry] });
104 this.registerProgram(programName, programConfig);
105 });
106 }
107 registerProgram(program, { commands, examples }) {
108 if (!this.programs[program]) {
109 this.programs[program] = { program, examples, commands: {} };
110 }
111 commands.forEach((command) => {
112 const { token, args } = this.queParser(command.commandLine);
113 command.args = args;
114 command.token = token;
115 this.programs[program].commands[token] = command;
116 this.commands[token] = command;
117 });
118 }
119 queParser(commandLine) {
120 return commandLine.split(' ').reduce((parsed, value) => {
121 if (value[0] === '<' && value[value.length - 1] === '>') {
122 parsed.args.push({ required: true, name: value.slice(1, -1) });
123 }
124 else if (value[0] === '[' && value[value.length - 1] === ']') {
125 parsed.args.push({ required: false, name: value.slice(1, -1) });
126 }
127 else {
128 parsed.token = value;
129 }
130 return parsed;
131 }, { args: [] });
132 }
133}
134exports.CliService = CliService;
135//# sourceMappingURL=CliService.js.map
\No newline at end of file