UNPKG

sculptui-vscode

Version:

Visually edit your React component code from the browser

142 lines (129 loc) 4.87 kB
import * as vscode from 'vscode'; import TelemetryReporter from 'vscode-extension-telemetry'; import { ExtensionId } from './const/extension'; import { userInfo } from 'os'; import { sep } from 'path'; // telemetry reporter let reporter: TelemetryReporter | undefined = undefined; let commonProps: { [key: string]: string } = {}; /** Activate a telemetry reporting */ export function activate(context: vscode.ExtensionContext) { // create telemetry reporter on extension activation const extension = vscode.extensions.getExtension(ExtensionId)!; const extensionVersion = extension.packageJSON.version; // following key just allows you to send events to azure insights API // so it does not need to be protected // but obfuscating anyways - bots scan github for keys, but if you want my key you better work for it, damnit! const innocentKitten = Buffer.from('ODFhZGMzMGMtZDRmMC00NTg5LThlOGItMzYzNDdkZDU2ZGQ3', 'base64').toString(); reporter = new TelemetryReporter(ExtensionId, extensionVersion, innocentKitten); // ensure it gets properly disposed context.subscriptions.push(reporter); } /** Deactivate a telemetry reporting */ export function deactivate() { // This will ensure all pending events get flushed reporter && reporter.dispose(); } /** Add common properties that will be always sent when calling `sendEvent()` or `sendError()`. */ export function addCommonProperties(properties: { [name: string]: string | number | boolean | undefined | null }) { commonProps = { ...commonProps, ...convertToStrings(properties) }; } /** * Sends an event to telemetry reporting. */ export function sendEvent( /** Event name. * * To allow proper grouping and useful metrics, choose a small number of separate event names. For example, don't use a separate name for each generated instance of an event. * * Max. lenght: 512 characters */ eventName: string, /** Propeties to add to the common properties that will be sent for this event. */ properties?: { [name: string]: string | number | boolean | undefined | null }, /** Metrics to add to this event. */ measurements?: { [key: string]: number; }, ) { if (!reporter) { console.warn('Telemetry should be activated using activate() before being called.'); return; } reporter.sendTelemetryEvent(eventName, { ...commonProps, ...convertToStrings(properties) }, measurements); } /** * Sends an exception to telemetry reporting. */ export function sendError( error: Error, properties?: { [name: string]: string | number | boolean | undefined | null }, measurements?: { [key: string]: number; }, ) { if (!reporter) { console.warn('Telemetry should be activated using activate() before being called.'); return; } if (error.stack) { error.stack = anonymizePaths(error.stack); } reporter.sendTelemetryException(error, { ...commonProps, ...convertToStrings(properties) }, measurements); } /** * Sends an exception as an event to telemetry reporting. * * Note: Using `sendError()` is prefered unless you want it to appear in the list of custom events. */ export function sendErrorEvent( eventName: string, properties?: { [name: string]: string | number | boolean | undefined | null }, measurements?: { [key: string]: number; }, error?: Error, ) { if (!reporter) { console.warn('Telemetry should be activated using activate() before being called.'); return; } if (error && error.stack) { error.stack = anonymizePaths(error.stack); } reporter.sendTelemetryErrorEvent( eventName, { ...commonProps, ...properties, errorStack: error?.stack || '', errorMessage: error?.message || `${error}`, errorName: error?.name || '', }, measurements, [], ); } /** converts non-string value properties on object to strings */ function convertToStrings(properties?: { [name: string]: string | number | boolean | undefined | null; }): { [name: string]: string } { if (!properties) return {}; return Object.keys(properties).reduce((prevVal, current) => { let propVal = properties[current]; if (propVal === undefined) { propVal = '<undefined>'; } else if (propVal === null) { propVal = '<null>'; } else if (typeof propVal !== 'string') { propVal = propVal.toString(); } prevVal[current] = propVal; return prevVal; }, {} as { [name: string]: string }); } /** replace username with anon */ function anonymizePaths(input: string) { if (input == null) return input; return input.replace(new RegExp('\\' + sep + userInfo().username, 'g'), sep + 'anon'); } export default { activate, deactivate, addCommonProperties, sendError, sendEvent, sendErrorEvent };