This commit is contained in:
parent
55470c090d
commit
6947a1adba
1260 changed files with 111297 additions and 0 deletions
130
@capacitor/cli/dist/telemetry.js
vendored
Normal file
130
@capacitor/cli/dist/telemetry.js
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.sendMetric = exports.telemetryAction = exports.THANK_YOU = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const commander_1 = require("commander");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
||||
const ipc_1 = require("./ipc");
|
||||
const log_1 = require("./log");
|
||||
const sysconfig_1 = require("./sysconfig");
|
||||
const subprocess_1 = require("./util/subprocess");
|
||||
const term_1 = require("./util/term");
|
||||
const debug = (0, debug_1.default)('capacitor:telemetry');
|
||||
exports.THANK_YOU = `\nThank you for helping to make Capacitor better! 💖` +
|
||||
`\nInformation about the data we collect is available on our website: ${colors_1.default.strong('https://capacitorjs.com/telemetry')}\n`;
|
||||
function telemetryAction(config, action) {
|
||||
return async (...actionArgs) => {
|
||||
const start = new Date();
|
||||
// This is how commanderjs works--the command object is either the last
|
||||
// element or second to last if there are additional options (via `.allowUnknownOption()`)
|
||||
const lastArg = actionArgs[actionArgs.length - 1];
|
||||
const cmd = lastArg instanceof commander_1.Command ? lastArg : actionArgs[actionArgs.length - 2];
|
||||
const command = getFullCommandName(cmd);
|
||||
let error;
|
||||
try {
|
||||
await action(...actionArgs);
|
||||
}
|
||||
catch (e) {
|
||||
error = e;
|
||||
}
|
||||
const end = new Date();
|
||||
const duration = end.getTime() - start.getTime();
|
||||
const packages = Object.entries({
|
||||
...config.app.package.devDependencies,
|
||||
...config.app.package.dependencies,
|
||||
});
|
||||
// Only collect packages in the capacitor org:
|
||||
// https://www.npmjs.com/org/capacitor
|
||||
const capacitorPackages = packages.filter(([k]) => k.startsWith('@capacitor/'));
|
||||
const versions = capacitorPackages.map(([k, v]) => [
|
||||
`${k.replace(/^@capacitor\//, '').replace(/-/g, '_')}_version`,
|
||||
v,
|
||||
]);
|
||||
const data = {
|
||||
app_id: await getAppIdentifier(config),
|
||||
command,
|
||||
arguments: cmd.args.join(' '),
|
||||
options: JSON.stringify(cmd.opts()),
|
||||
duration,
|
||||
error: error ? (error.message ? error.message : String(error)) : null,
|
||||
node_version: process.version,
|
||||
os: config.cli.os,
|
||||
...Object.fromEntries(versions),
|
||||
};
|
||||
if ((0, term_1.isInteractive)()) {
|
||||
let sysconfig = await (0, sysconfig_1.readConfig)();
|
||||
if (!error && typeof sysconfig.telemetry === 'undefined') {
|
||||
const confirm = await promptForTelemetry();
|
||||
sysconfig = { ...sysconfig, telemetry: confirm };
|
||||
await (0, sysconfig_1.writeConfig)(sysconfig);
|
||||
}
|
||||
await sendMetric(sysconfig, 'capacitor_cli_command', data);
|
||||
}
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
exports.telemetryAction = telemetryAction;
|
||||
/**
|
||||
* If telemetry is enabled, send a metric via IPC to a forked process for uploading.
|
||||
*/
|
||||
async function sendMetric(sysconfig, name, data) {
|
||||
if (sysconfig.telemetry && (0, term_1.isInteractive)()) {
|
||||
const message = {
|
||||
name,
|
||||
timestamp: new Date().toISOString(),
|
||||
session_id: sysconfig.machine,
|
||||
source: 'capacitor_cli',
|
||||
value: data,
|
||||
};
|
||||
await (0, ipc_1.send)({ type: 'telemetry', data: message });
|
||||
}
|
||||
else {
|
||||
debug('Telemetry is off (user choice, non-interactive terminal, or CI)--not sending metric');
|
||||
}
|
||||
}
|
||||
exports.sendMetric = sendMetric;
|
||||
async function promptForTelemetry() {
|
||||
const { confirm } = await (0, log_1.logPrompt)(`${colors_1.default.strong('Would you like to help improve Capacitor by sharing anonymous usage data? 💖')}\n` +
|
||||
`Read more about what is being collected and why here: ${colors_1.default.strong('https://capacitorjs.com/telemetry')}. You can change your mind at any time by using the ${colors_1.default.input('npx cap telemetry')} command.`, {
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: 'Share anonymous usage data?',
|
||||
initial: true,
|
||||
});
|
||||
if (confirm) {
|
||||
log_1.output.write(exports.THANK_YOU);
|
||||
}
|
||||
return confirm;
|
||||
}
|
||||
/**
|
||||
* Get a unique anonymous identifier for this app.
|
||||
*/
|
||||
async function getAppIdentifier(config) {
|
||||
const { createHash } = await Promise.resolve().then(() => tslib_1.__importStar(require('crypto')));
|
||||
// get the first commit hash, which should be universally unique
|
||||
const output = await (0, subprocess_1.getCommandOutput)('git', ['rev-list', '--max-parents=0', 'HEAD'], { cwd: config.app.rootDir });
|
||||
const firstLine = output === null || output === void 0 ? void 0 : output.split('\n')[0];
|
||||
if (!firstLine) {
|
||||
debug('Could not obtain unique app identifier');
|
||||
return null;
|
||||
}
|
||||
// use sha1 to create a one-way hash to anonymize
|
||||
const id = createHash('sha1').update(firstLine).digest('hex');
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Walk through the command's parent tree and construct a space-separated name.
|
||||
*
|
||||
* Probably overkill because we don't have nested commands, but whatever.
|
||||
*/
|
||||
function getFullCommandName(cmd) {
|
||||
const names = [];
|
||||
while (cmd.parent !== null) {
|
||||
names.push(cmd.name());
|
||||
cmd = cmd.parent;
|
||||
}
|
||||
return names.reverse().join(' ');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue