UNPKG

5.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Command = void 0;
4const cli_framework_1 = require("@ionic/cli-framework");
5const cli_framework_output_1 = require("@ionic/cli-framework-output");
6const utils_terminal_1 = require("@ionic/utils-terminal");
7const guards_1 = require("../guards");
8const color_1 = require("./color");
9const logger_1 = require("./utils/logger");
10class Command extends cli_framework_1.BaseCommand {
11 constructor(namespace) {
12 super(namespace);
13 this.namespace = namespace;
14 this.taskChains = [];
15 }
16 get env() {
17 return this.namespace.root.env;
18 }
19 get project() {
20 return this.namespace.root.project;
21 }
22 createTaskChain() {
23 let output;
24 const formatter = logger_1.createFormatter();
25 if (this.env.flags.interactive) {
26 output = new cli_framework_output_1.TTYOutputStrategy({ stream: process.stdout, colors: cli_framework_1.DEFAULT_COLORS });
27 this.env.log.handlers = new Set([new cli_framework_output_1.StreamHandler({ stream: output.stream, formatter })]);
28 }
29 else {
30 this.env.log.handlers = logger_1.createDefaultLoggerHandlers();
31 output = new cli_framework_output_1.StreamOutputStrategy({ stream: this.env.log.createWriteStream(cli_framework_output_1.LOGGER_LEVELS.INFO, false), colors: cli_framework_1.DEFAULT_COLORS });
32 }
33 const chain = output.createTaskChain();
34 this.taskChains.push(chain);
35 chain.on('end', () => {
36 this.env.log.handlers = logger_1.createDefaultLoggerHandlers();
37 });
38 return chain;
39 }
40 async execute(inputs, options, runinfo) {
41 if (guards_1.isCommandPreRun(this)) {
42 await this.preRun(inputs, options, runinfo);
43 }
44 try {
45 await this.validate(inputs);
46 }
47 catch (e) {
48 if (!this.env.flags.interactive) {
49 this.env.log.warn(`Command ran non-interactively due to ${color_1.input('--no-interactive')} flag, CI being detected, non-TTY, or a config setting.`);
50 }
51 throw e;
52 }
53 const runPromise = this.run(inputs, options, runinfo);
54 const telemetryPromise = (async () => {
55 if (this.env.config.get('telemetry') !== false && !utils_terminal_1.TERMINAL_INFO.ci && utils_terminal_1.TERMINAL_INFO.tty) {
56 const { Telemetry } = await Promise.resolve().then(() => require('./telemetry'));
57 let cmdInputs = [];
58 const metadata = await this.getMetadata();
59 if (metadata.name === 'login' || metadata.name === 'logout') {
60 // This is a hack to wait until the selected commands complete before
61 // sending telemetry data. These commands update `this.env` in some
62 // way, which is used in the `Telemetry` instance.
63 await runPromise;
64 }
65 else if (metadata.name === 'completion') {
66 // Ignore telemetry for these commands.
67 return;
68 }
69 else if (metadata.name === 'help') {
70 cmdInputs = inputs;
71 }
72 else {
73 cmdInputs = await this.getCleanInputsForTelemetry(inputs, options);
74 }
75 const cmd = this;
76 const path = await cli_framework_1.generateCommandPath(cmd);
77 const telemetry = new Telemetry({ client: this.env.client, config: this.env.config, getInfo: this.env.getInfo, ctx: this.env.ctx, project: this.project, session: this.env.session });
78 await telemetry.sendCommand(path.map(([p]) => p).join(' '), cmdInputs);
79 }
80 })();
81 await Promise.all([runPromise, telemetryPromise]);
82 }
83 async getCleanInputsForTelemetry(inputs, options) {
84 const initialOptions = { _: [] };
85 const metadata = await this.getMetadata();
86 const filteredInputs = inputs.map((input, i) => metadata.inputs && (metadata.inputs[i] && metadata.inputs[i].private) ? '*****' : input);
87 const filteredOptions = Object.keys(options)
88 .filter(optionName => {
89 if (optionName === '_') {
90 return false;
91 }
92 const metadataOption = metadata.options && metadata.options.find(o => {
93 return o.name === optionName || (typeof o.aliases !== 'undefined' && o.aliases.includes(optionName));
94 });
95 if (metadataOption && metadataOption.aliases && metadataOption.aliases.includes(optionName)) {
96 return false; // exclude aliases
97 }
98 if (!metadataOption) {
99 return true; // include unknown options
100 }
101 if (metadataOption.private) {
102 return false; // exclude private options
103 }
104 if (typeof metadataOption.default !== 'undefined' && metadataOption.default === options[optionName]) {
105 return false; // exclude options that match their default value (means it wasn't supplied by user)
106 }
107 return true;
108 })
109 .reduce((allOptions, optionName) => {
110 allOptions[optionName] = options[optionName];
111 return allOptions;
112 }, initialOptions);
113 const optionInputs = cli_framework_1.unparseArgs(filteredOptions, { useDoubleQuotes: true });
114 return filteredInputs.concat(optionInputs);
115 }
116}
117exports.Command = Command;