UNPKG

4.22 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const command_1 = require("@heroku-cli/command");
4const cli_ux_1 = require("cli-ux");
5const netrc_parser_1 = require("netrc-parser");
6const path = require("path");
7const deps_1 = require("./deps");
8const debug = require('debug')('heroku:analytics');
9class AnalyticsCommand {
10 constructor(config) {
11 this.config = config;
12 this.http = deps_1.default.HTTP.create({
13 headers: { 'user-agent': config.userAgent },
14 });
15 }
16 _initialAnalyticsJSON() {
17 return {
18 schema: 1,
19 commands: [],
20 };
21 }
22 async record(opts) {
23 await this.init();
24 const plugin = opts.Command.plugin;
25 if (!plugin) {
26 debug('no plugin found for analytics');
27 return;
28 }
29 if (!this.user)
30 return;
31 let analyticsJSON = await this._readJSON();
32 analyticsJSON.commands.push({
33 command: opts.Command.id,
34 completion: await this._acAnalytics(),
35 version: this.config.version,
36 plugin: plugin.name,
37 plugin_version: plugin.version,
38 os: this.config.platform,
39 shell: this.config.shell,
40 valid: true,
41 language: 'node',
42 });
43 await this._writeJSON(analyticsJSON);
44 }
45 async submit() {
46 try {
47 await this.init();
48 let user = this.user;
49 if (!user)
50 return;
51 const local = await this._readJSON();
52 if (local.commands.length === 0)
53 return;
54 const body = {
55 schema: local.schema,
56 commands: local.commands,
57 user,
58 install: this.userConfig.install,
59 cli: this.config.name,
60 };
61 await this.http.post(this.url, { body });
62 await deps_1.default.file.remove(this.analyticsPath);
63 }
64 catch (err) {
65 debug(err);
66 await deps_1.default.file.remove(this.analyticsPath).catch(err => cli_ux_1.default.warn(err));
67 }
68 }
69 get url() {
70 return process.env.HEROKU_ANALYTICS_URL || 'https://cli-analytics.heroku.com/record';
71 }
72 get analyticsPath() {
73 return path.join(this.config.cacheDir, 'analytics.json');
74 }
75 get usingHerokuAPIKey() {
76 const k = process.env.HEROKU_API_KEY;
77 return !!(k && k.length > 0);
78 }
79 get netrcLogin() {
80 return netrc_parser_1.default.machines[command_1.vars.apiHost] && netrc_parser_1.default.machines[command_1.vars.apiHost].login;
81 }
82 get user() {
83 if (this.userConfig.skipAnalytics || this.usingHerokuAPIKey)
84 return;
85 return this.netrcLogin;
86 }
87 async _readJSON() {
88 try {
89 let analytics = await deps_1.default.file.readJSON(this.analyticsPath);
90 analytics.commands = analytics.commands || [];
91 return analytics;
92 }
93 catch (err) {
94 if (err.code !== 'ENOENT')
95 debug(err);
96 return this._initialAnalyticsJSON();
97 }
98 }
99 async _writeJSON(analyticsJSON) {
100 return deps_1.default.file.outputJSON(this.analyticsPath, analyticsJSON);
101 }
102 async _acAnalytics() {
103 let root = path.join(this.config.cacheDir, 'completions', 'completion_analytics');
104 let meta = {
105 cmd: deps_1.default.file.exists(path.join(root, 'command')),
106 flag: deps_1.default.file.exists(path.join(root, 'flag')),
107 value: deps_1.default.file.exists(path.join(root, 'value')),
108 };
109 let score = 0;
110 if (await meta.cmd)
111 score += 1;
112 if (await meta.flag)
113 score += 2;
114 if (await meta.value)
115 score += 4;
116 if (await deps_1.default.file.exists(root))
117 await deps_1.default.file.remove(root);
118 return score;
119 }
120 async init() {
121 await netrc_parser_1.default.load();
122 this.userConfig = new deps_1.default.UserConfig(this.config);
123 await this.userConfig.init();
124 }
125}
126exports.default = AnalyticsCommand;