UNPKG

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