1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const command_1 = require("@heroku-cli/command");
|
4 | const cli_ux_1 = require("cli-ux");
|
5 | const netrc_parser_1 = require("netrc-parser");
|
6 | const path = require("path");
|
7 | const deps_1 = require("./deps");
|
8 | const debug = require('debug')('heroku:analytics');
|
9 | class 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 | }
|
126 | exports.default = AnalyticsCommand;
|