firebase-tools
Version:
Command-Line Interface for Firebase
195 lines (194 loc) • 7.19 kB
JavaScript
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.cliSession = exports.vscodeSession = exports.emulatorSession = exports.trackVSCode = exports.trackEmulator = exports.trackGA4 = exports.usageEnabled = exports.GA4_PROPERTIES = void 0;
const node_fetch_1 = require("node-fetch");
const uuid_1 = require("uuid");
const auth_1 = require("./auth");
const configstore_1 = require("./configstore");
const logger_1 = require("./logger");
const pkg = require("../package.json");
exports.GA4_PROPERTIES = {
cli: {
measurementId: process.env.FIREBASE_CLI_GA4_MEASUREMENT_ID || "G-PDN0QWHQJR",
apiSecret: process.env.FIREBASE_CLI_GA4_API_SECRET || "LSw5lNxhSFSWeB6aIzJS2w",
clientIdKey: "analytics-uuid",
},
emulator: {
measurementId: process.env.FIREBASE_EMULATOR_GA4_MEASUREMENT_ID || "G-KYP2JMPFC0",
apiSecret: process.env.FIREBASE_EMULATOR_GA4_API_SECRET || "2V_zBYc4TdeoppzDaIu0zw",
clientIdKey: "emulator-analytics-clientId",
},
vscode: {
measurementId: process.env.FIREBASE_VSCODE_GA4_MEASUREMENT_ID || "G-FYJ489XM2T",
apiSecret: process.env.FIREBASE_VSCODE_GA4_API_SECRET || "XAEWKHe7RM-ygCK44N52Ww",
clientIdKey: "vscode-analytics-clientId",
},
};
function usageEnabled() {
return ((!!process.env.IS_FIREBASE_CLI || !!process.env.IS_FIREBASE_MCP) && !!configstore_1.configstore.get("usage"));
}
exports.usageEnabled = usageEnabled;
const GA4_USER_PROPS = {
node_platform: {
value: process.platform,
},
node_version: {
value: process.version,
},
cli_version: {
value: pkg.version,
},
firepit_version: {
value: process.env.FIREPIT_VERSION || "none",
},
is_firebase_studio: {
value: (_a = process.env.MONOSPACE_ENV) !== null && _a !== void 0 ? _a : "false",
},
};
async function trackGA4(eventName, params, duration = 1) {
const session = cliSession();
if (!session) {
return;
}
return _ga4Track({
session,
apiSecret: exports.GA4_PROPERTIES.cli.apiSecret,
eventName,
params,
duration,
});
}
exports.trackGA4 = trackGA4;
async function trackEmulator(eventName, params) {
const session = emulatorSession();
if (!session) {
return;
}
const oldTotalEngagementSeconds = session.totalEngagementSeconds;
session.totalEngagementSeconds = process.uptime();
const duration = session.totalEngagementSeconds - oldTotalEngagementSeconds;
return _ga4Track({
session,
apiSecret: exports.GA4_PROPERTIES.emulator.apiSecret,
eventName,
params,
duration,
});
}
exports.trackEmulator = trackEmulator;
async function trackVSCode(eventName, params) {
const session = vscodeSession();
if (!session) {
return;
}
session.debugMode = process.env.VSCODE_DEBUG_MODE === "true";
const oldTotalEngagementSeconds = session.totalEngagementSeconds;
session.totalEngagementSeconds = process.uptime();
const duration = session.totalEngagementSeconds - oldTotalEngagementSeconds;
return _ga4Track({
session,
apiSecret: exports.GA4_PROPERTIES.vscode.apiSecret,
eventName,
params,
duration,
});
}
exports.trackVSCode = trackVSCode;
async function _ga4Track(args) {
const { session, apiSecret, eventName, params, duration } = args;
session.commandName = (params === null || params === void 0 ? void 0 : params.command_name) || session.commandName;
const search = `?api_secret=${apiSecret}&measurement_id=${session.measurementId}`;
const validate = session.validateOnly ? "debug/" : "";
const url = `https://www.google-analytics.com/${validate}mp/collect${search}`;
const body = {
timestamp_micros: `${Date.now()}000`,
client_id: session.clientId,
user_properties: Object.assign(Object.assign({}, GA4_USER_PROPS), { java_major_version: session.javaMajorVersion
? { value: session.javaMajorVersion }
: undefined }),
validationBehavior: session.validateOnly ? "ENFORCE_RECOMMENDATIONS" : undefined,
events: [
{
name: eventName,
params: Object.assign({ session_id: session.sessionId, engagement_time_msec: (duration !== null && duration !== void 0 ? duration : 0).toFixed(3).replace(".", "").replace(/^0+/, ""), debug_mode: session.debugMode ? true : undefined, command_name: session.commandName }, params),
},
],
};
if (session.validateOnly) {
logger_1.logger.info(`Sending Analytics for event ${eventName} to property ${session.measurementId}`, params, body);
}
try {
const response = await (0, node_fetch_1.default)(url, {
method: "POST",
headers: {
"content-type": "application/json;charset=UTF-8",
},
body: JSON.stringify(body),
});
if (session.validateOnly) {
if (!response.ok) {
logger_1.logger.warn(`Analytics validation HTTP error: ${response.status}`);
}
const respBody = await response.text();
logger_1.logger.info(`Analytics validation result: ${respBody}`);
}
}
catch (e) {
if (session.validateOnly) {
throw e;
}
return;
}
}
function emulatorSession() {
return session("emulator");
}
exports.emulatorSession = emulatorSession;
function vscodeSession() {
return session("vscode");
}
exports.vscodeSession = vscodeSession;
function cliSession() {
return session("cli");
}
exports.cliSession = cliSession;
function session(propertyName) {
const validateOnly = !!process.env.FIREBASE_CLI_MP_VALIDATE;
if (!usageEnabled() && propertyName !== "vscode") {
if (validateOnly) {
logger_1.logger.debug("Google Analytics is DISABLED. To enable, (re)login and opt in to collection.");
}
return;
}
const property = exports.GA4_PROPERTIES[propertyName];
if (!property.currentSession) {
let clientId = configstore_1.configstore.get(property.clientIdKey);
if (!clientId) {
clientId = (0, uuid_1.v4)();
configstore_1.configstore.set(property.clientIdKey, clientId);
}
property.currentSession = {
measurementId: property.measurementId,
clientId,
sessionId: (Math.random() * Number.MAX_SAFE_INTEGER).toFixed(0),
totalEngagementSeconds: 0,
debugMode: isDebugMode(),
validateOnly,
};
}
return property.currentSession;
}
function isDebugMode() {
const account = (0, auth_1.getGlobalDefaultAccount)();
if (account === null || account === void 0 ? void 0 : account.user.email.endsWith("@google.com")) {
try {
require("../tsconfig.json");
logger_1.logger.debug(`Using Google Analytics in DEBUG mode. Emulators (+ UI) events will be shown in GA Debug View only.`);
return true;
}
catch (_a) {
}
}
return false;
}
;