1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const yargs_parser_1 = __importDefault(require("yargs-parser"));
|
7 | const Output_1 = require("../Output");
|
8 | class CliService {
|
9 | constructor(commandManager, config = {}) {
|
10 | this.programs = {};
|
11 | |
12 |
|
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 |
|
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 | }
|
134 | exports.CliService = CliService;
|
135 |
|
\ | No newline at end of file |