@react-native-windows/telemetry 0.76.0-preview.2 → 0.76.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  * @format
5
5
  */
6
- import * as appInsights from 'applicationinsights';
6
+ import * as coreOneDS from '@microsoft/1ds-core-js';
7
7
  import * as errorUtils from './utils/errorUtils';
8
8
  import * as projectUtils from './utils/projectUtils';
9
9
  export interface TelemetryOptions {
@@ -35,38 +35,26 @@ export declare const NuGetPackagesWeTrack: string[];
35
35
  * The Telemetry class is responsible for reporting telemetry for RNW CLI.
36
36
  */
37
37
  export declare class Telemetry {
38
- protected static client?: appInsights.TelemetryClient;
38
+ protected static appInsightsCore?: coreOneDS.AppInsightsCore;
39
39
  protected static options: TelemetryOptions;
40
- protected static isTest: boolean;
40
+ protected static isTestEnvironment: boolean;
41
41
  protected static commandInfo: CommandInfo;
42
42
  protected static versionsProp: Record<string, string>;
43
43
  protected static projectProp?: projectUtils.AppProjectInfo | projectUtils.DependencyProjectInfo;
44
+ protected static commonProperties: {
45
+ [key: string]: string;
46
+ };
44
47
  protected static getDefaultSetupString(): string;
45
48
  protected static reset(): void;
46
49
  static isEnabled(): boolean;
47
50
  static getSessionId(): string;
48
51
  /** Sets up the Telemetry static to be used elsewhere. */
49
52
  static setup(options?: Partial<TelemetryOptions>): Promise<void>;
50
- /** Sets up Telemetry.client. */
53
+ private static basicTelemetryInitializer;
54
+ /** Sets up Telemetry.appInsightsCore. */
51
55
  private static setupClient;
52
56
  /** Sets up any base properties that all telemetry events require. */
53
57
  private static setupBaseProperties;
54
- /** Sets up any telemetry processors. */
55
- private static setupTelemetryProcessors;
56
- /**
57
- * Performs the processing necessary (mostly PII sanitization) for all events.
58
- * @param envelope The ApplicationInsights event envelope.
59
- * @param _contextObjects An optional context object.
60
- * @returns Whether to kee
61
- */
62
- private static basicTelemetryProcessor;
63
- /**
64
- * Performs the processing necessary (mostly PII sanitization) for error events.
65
- * @param envelope
66
- * @param _contextObjects
67
- * @returns
68
- */
69
- private static errorTelemetryProcessor;
70
58
  /** Tries to update the version of the named package/tool by calling getValue(). */
71
59
  static tryUpdateVersionsProp(name: string, getValue: () => Promise<string | null>, forceRefresh?: boolean): Promise<boolean>;
72
60
  /** Populates the versions property of tools we care to track. */
@@ -78,7 +66,10 @@ export declare class Telemetry {
78
66
  static setProjectInfo(info: projectUtils.AppProjectInfo | projectUtils.DependencyProjectInfo): void;
79
67
  static startCommand(info: CommandStartInfo): void;
80
68
  static endCommand(info: CommandEndInfo, extraProps?: Record<string, any>): void;
69
+ private static trackEvent;
81
70
  private static trackCommandEvent;
82
71
  static trackException(error: Error, extraProps?: Record<string, any>): void;
72
+ static convertErrorIntoExceptionData(error: Error): Record<string, any>;
73
+ static sanitizeAny(data: any): any;
83
74
  }
84
75
  export {};
@@ -29,12 +29,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
31
  exports.Telemetry = exports.NuGetPackagesWeTrack = exports.NpmPackagesWeTrack = exports.EventNamesWeTrack = exports.CodedErrorEventName = exports.CommandEventName = void 0;
32
- const appInsights = __importStar(require("applicationinsights"));
32
+ const coreOneDS = __importStar(require("@microsoft/1ds-core-js"));
33
+ const _1ds_post_js_1 = require("@microsoft/1ds-post-js");
33
34
  const basePropUtils = __importStar(require("./utils/basePropUtils"));
34
35
  const versionUtils = __importStar(require("./utils/versionUtils"));
35
36
  const errorUtils = __importStar(require("./utils/errorUtils"));
36
- // This is our key with the AI backend
37
- const RNWSetupString = '795006ca-cf54-40ee-8bc6-03deb91401c3';
37
+ const nameUtils = __importStar(require("./utils/nameUtils"));
38
+ // 1DS instrumentation key
39
+ const RNW_1DS_INSTRUMENTATION_KEY = '49ff6d3ef12f4578a7b75a2573d9dba8-026332b2-2d50-452f-ad0d-50f921c97a9d-7145';
38
40
  // Environment variable to override the default setup string
39
41
  const ENV_SETUP_OVERRIDE = 'RNW_TELEMETRY_SETUP';
40
42
  // Environment variable to override the http proxy (such as http://localhost:8888 for Fiddler debugging)
@@ -70,13 +72,13 @@ class Telemetry {
70
72
  static getDefaultSetupString() {
71
73
  var _a;
72
74
  // Enable overriding the default setup string via an environment variable
73
- return (_a = process.env[ENV_SETUP_OVERRIDE]) !== null && _a !== void 0 ? _a : RNWSetupString;
75
+ return (_a = process.env[ENV_SETUP_OVERRIDE]) !== null && _a !== void 0 ? _a : RNW_1DS_INSTRUMENTATION_KEY;
74
76
  }
75
77
  static reset() {
76
78
  // Reset client
77
- if (Telemetry.client) {
78
- Telemetry.client.flush();
79
- Telemetry.client = undefined;
79
+ if (Telemetry.appInsightsCore) {
80
+ Telemetry.appInsightsCore.flush();
81
+ Telemetry.appInsightsCore = undefined;
80
82
  }
81
83
  // Reset local members
82
84
  Telemetry.options = {
@@ -89,146 +91,104 @@ class Telemetry {
89
91
  Telemetry.projectProp = undefined;
90
92
  }
91
93
  static isEnabled() {
92
- return Telemetry.client !== undefined;
94
+ return Telemetry.appInsightsCore !== undefined;
93
95
  }
94
96
  static getSessionId() {
95
97
  return basePropUtils.getSessionId();
96
98
  }
97
99
  /** Sets up the Telemetry static to be used elsewhere. */
98
100
  static async setup(options) {
99
- if (Telemetry.client) {
101
+ if (Telemetry.appInsightsCore) {
100
102
  // Bail since we've already setup
101
103
  return;
102
104
  }
103
105
  // Bail if we're in CI and not capturing CI
104
- if (!this.isTest && basePropUtils.isCI() && !basePropUtils.captureCI()) {
106
+ if (!Telemetry.isTestEnvironment &&
107
+ basePropUtils.isCI() &&
108
+ !basePropUtils.captureCI()) {
105
109
  return;
106
110
  }
107
111
  // Save off options for later
108
112
  Object.assign(Telemetry.options, options);
109
113
  Telemetry.setupClient();
110
114
  await Telemetry.setupBaseProperties();
111
- Telemetry.setupTelemetryProcessors();
112
115
  }
113
- /** Sets up Telemetry.client. */
116
+ static basicTelemetryInitializer(envelope) {
117
+ // Filter out "legacy" events from older stable branches
118
+ if (envelope.name && exports.EventNamesWeTrack.includes(envelope.name)) {
119
+ return true;
120
+ }
121
+ return false;
122
+ }
123
+ /** Sets up Telemetry.appInsightsCore. */
114
124
  static setupClient() {
115
- var _a;
116
- appInsights.Configuration.setInternalLogging(false, false);
117
- Telemetry.client = new appInsights.TelemetryClient(Telemetry.options.setupString);
118
- // Allow overriding the proxy server via an environment variable
119
- const proxyServer = process.env[ENV_PROXY_OVERRIDE];
120
- if (proxyServer) {
121
- Telemetry.client.config.proxyHttpUrl = proxyServer;
122
- Telemetry.client.config.proxyHttpsUrl = proxyServer;
125
+ const postChannel = new _1ds_post_js_1.PostChannel();
126
+ const coreConfiguration = {
127
+ instrumentationKey: Telemetry.getDefaultSetupString(),
128
+ };
129
+ const postChannelConfig = {
130
+ eventsLimitInMem: 5000,
131
+ };
132
+ coreConfiguration.extensionConfig = {};
133
+ coreConfiguration.extensionConfig[postChannel.identifier] =
134
+ postChannelConfig;
135
+ // Allow overriding the endpoint URL via an environment variable.
136
+ if (process.env[ENV_PROXY_OVERRIDE] !== undefined) {
137
+ coreConfiguration.endpointUrl = process.env[ENV_PROXY_OVERRIDE];
123
138
  }
124
- Telemetry.client.config.disableAppInsights = Telemetry.isTest;
125
- Telemetry.client.config.disableStatsbeat = true;
126
- // Despite trying to disable the statsbeat, it might still be running: https://github.com/microsoft/ApplicationInsights-node.js/issues/943
127
- // So we want to disable it, and despite the method's typing, getStatsbeat() _can_ return undefined
128
- (_a = Telemetry.client.getStatsbeat()) === null || _a === void 0 ? void 0 : _a.enable(false);
129
- Telemetry.client.channel.setUseDiskRetryCaching(!Telemetry.isTest);
139
+ Telemetry.appInsightsCore = new coreOneDS.AppInsightsCore();
140
+ Telemetry.appInsightsCore.initialize(coreConfiguration, [postChannel] /* extensions */);
141
+ Telemetry.appInsightsCore.addTelemetryInitializer(Telemetry.basicTelemetryInitializer);
130
142
  }
131
143
  /** Sets up any base properties that all telemetry events require. */
132
144
  static async setupBaseProperties() {
133
- Telemetry.client.commonProperties.deviceId =
134
- await basePropUtils.deviceId();
135
- Telemetry.client.commonProperties.deviceArchitecture =
145
+ Telemetry.commonProperties.deviceId = await basePropUtils.deviceId();
146
+ Telemetry.commonProperties.fullBuildInfo =
147
+ await basePropUtils.fullBuildInfo();
148
+ Telemetry.commonProperties.deviceArchitecture =
136
149
  basePropUtils.deviceArchitecture();
137
- Telemetry.client.commonProperties.nodeArchitecture =
150
+ Telemetry.commonProperties.nodeArchitecture =
138
151
  basePropUtils.nodeArchitecture();
139
- Telemetry.client.commonProperties.devicePlatform =
140
- basePropUtils.devicePlatform();
141
- Telemetry.client.commonProperties.deviceLocale =
152
+ Telemetry.commonProperties.nodePlatform = basePropUtils.nodePlatform();
153
+ Telemetry.commonProperties.deviceClass = basePropUtils.deviceClass();
154
+ Telemetry.commonProperties.deviceLocale =
142
155
  await basePropUtils.deviceLocale();
143
- Telemetry.client.commonProperties.deviceNumCPUs = basePropUtils
156
+ Telemetry.commonProperties.deviceNumCPUs = basePropUtils
144
157
  .deviceNumCPUs()
145
158
  .toString();
146
- Telemetry.client.commonProperties.deviceTotalMemory = basePropUtils
159
+ Telemetry.commonProperties.deviceTotalMemory = basePropUtils
147
160
  .deviceTotalMemory()
148
161
  .toString();
149
- Telemetry.client.commonProperties.deviceDiskFreeSpace = basePropUtils
162
+ Telemetry.commonProperties.deviceDiskFreeSpace = basePropUtils
150
163
  .deviceDiskFreeSpace()
151
164
  .toString();
152
- Telemetry.client.commonProperties.ciCaptured = basePropUtils
165
+ Telemetry.commonProperties.ciCaptured = basePropUtils
153
166
  .captureCI()
154
167
  .toString();
155
- Telemetry.client.commonProperties.ciType = basePropUtils.ciType();
156
- Telemetry.client.commonProperties.isMsftInternal = basePropUtils
168
+ Telemetry.commonProperties.ciType = basePropUtils.ciType();
169
+ Telemetry.commonProperties.isMsftInternal = basePropUtils
157
170
  .isMsftInternal()
158
171
  .toString();
159
- Telemetry.client.commonProperties.sampleRate = basePropUtils
160
- .sampleRate()
161
- .toString();
162
- Telemetry.client.commonProperties.isTest = Telemetry.isTest.toString();
163
- Telemetry.client.commonProperties.sessionId = Telemetry.getSessionId();
164
- Telemetry.client.config.samplingPercentage = basePropUtils.sampleRate();
172
+ Telemetry.commonProperties.isTest = Telemetry.isTestEnvironment.toString();
173
+ Telemetry.commonProperties.sessionId = Telemetry.getSessionId();
165
174
  await Telemetry.populateToolsVersions();
166
175
  if (Telemetry.options.populateNpmPackageVersions) {
167
176
  await Telemetry.populateNpmPackageVersions();
168
177
  }
169
178
  }
170
- /** Sets up any telemetry processors. */
171
- static setupTelemetryProcessors() {
172
- Telemetry.client.addTelemetryProcessor(Telemetry.basicTelemetryProcessor);
173
- Telemetry.client.addTelemetryProcessor(Telemetry.errorTelemetryProcessor);
174
- }
175
- /**
176
- * Performs the processing necessary (mostly PII sanitization) for all events.
177
- * @param envelope The ApplicationInsights event envelope.
178
- * @param _contextObjects An optional context object.
179
- * @returns Whether to kee
180
- */
181
- static basicTelemetryProcessor(envelope, _contextObjects) {
182
- var _a;
183
- delete envelope.tags['ai.cloud.roleInstance'];
184
- // Filter out "legacy" events from older stable branches
185
- const properties = (_a = envelope.data.baseData) === null || _a === void 0 ? void 0 : _a.properties;
186
- if ((properties === null || properties === void 0 ? void 0 : properties.eventName) &&
187
- exports.EventNamesWeTrack.includes(properties.eventName)) {
188
- return true;
189
- }
190
- return false;
191
- }
192
- /**
193
- * Performs the processing necessary (mostly PII sanitization) for error events.
194
- * @param envelope
195
- * @param _contextObjects
196
- * @returns
197
- */
198
- static errorTelemetryProcessor(envelope, _contextObjects) {
199
- if (envelope.data.baseType === 'ExceptionData') {
200
- const data = envelope.data.baseData;
201
- if (data === null || data === void 0 ? void 0 : data.exceptions) {
202
- for (const exception of data.exceptions) {
203
- for (const frame of exception.parsedStack) {
204
- errorUtils.sanitizeErrorStackFrame(frame);
205
- }
206
- // Exception message must never be blank, or AI will reject it
207
- exception.message = exception.message || '[None]';
208
- // CodedError has non-PII information in its 'type' member, plus optionally some more info in its 'data'.
209
- // The message may contain PII information. This can be sanitized, but for now delete it.
210
- // Note that the type of data.exceptions[0] is always going to be ExceptionDetails. It is not the original thrown exception.
211
- // https://github.com/microsoft/ApplicationInsights-node.js/issues/707
212
- if (Telemetry.options.preserveErrorMessages) {
213
- exception.message = errorUtils.sanitizeErrorMessage(exception.message);
214
- }
215
- else {
216
- exception.message = '[Removed]';
217
- }
218
- }
219
- }
220
- }
221
- return true;
222
- }
223
179
  /** Tries to update the version of the named package/tool by calling getValue(). */
224
180
  static async tryUpdateVersionsProp(name, getValue, forceRefresh) {
225
- if (!Telemetry.client) {
181
+ if (!Telemetry.appInsightsCore) {
226
182
  return true;
227
183
  }
228
- if (forceRefresh === true || !Telemetry.versionsProp[name]) {
184
+ // Process the package name to comply with the backend requirements
185
+ const packageName = nameUtils.isValidTelemetryPackageName(name)
186
+ ? name
187
+ : nameUtils.cleanTelemetryPackageName(name);
188
+ if (forceRefresh === true || !Telemetry.versionsProp[packageName]) {
229
189
  const value = await getValue();
230
190
  if (value) {
231
- Telemetry.versionsProp[name] = value;
191
+ Telemetry.versionsProp[packageName] = value;
232
192
  return true;
233
193
  }
234
194
  }
@@ -255,27 +215,29 @@ class Telemetry {
255
215
  }
256
216
  }
257
217
  static setProjectInfo(info) {
258
- if (!Telemetry.client) {
218
+ if (!Telemetry.appInsightsCore) {
259
219
  return;
260
220
  }
261
221
  Telemetry.projectProp = info;
262
222
  }
263
223
  static startCommand(info) {
264
- if (!Telemetry.client) {
224
+ if (!Telemetry.appInsightsCore) {
265
225
  return;
266
226
  }
227
+ // startCommand() was called before invoking endCommand(), bail out.
267
228
  if (Telemetry.commandInfo.startInfo) {
268
229
  return;
269
230
  }
270
231
  Telemetry.commandInfo.startTime = Date.now();
271
232
  Telemetry.commandInfo.startInfo = info;
272
233
  // Set common command props
273
- Telemetry.client.commonProperties.commandName = info.commandName;
234
+ Telemetry.commonProperties.commandName = info.commandName;
274
235
  }
275
236
  static endCommand(info, extraProps) {
276
- if (!Telemetry.client) {
237
+ if (!Telemetry.appInsightsCore) {
277
238
  return;
278
239
  }
240
+ // startCommand() wasn't called, bail out.
279
241
  if (!Telemetry.commandInfo.startInfo) {
280
242
  return;
281
243
  }
@@ -283,13 +245,52 @@ class Telemetry {
283
245
  Telemetry.commandInfo.endInfo = info;
284
246
  Telemetry.trackCommandEvent(extraProps);
285
247
  }
248
+ static trackEvent(telemetryItem) {
249
+ // Populate Part A
250
+ telemetryItem.ver = '4.0'; // Current Common Schema version
251
+ telemetryItem.time = new Date().toISOString();
252
+ telemetryItem.iKey = RNW_1DS_INSTRUMENTATION_KEY;
253
+ // Populate Part A extensions
254
+ telemetryItem.ext = {};
255
+ telemetryItem.ext.device = {
256
+ id: Telemetry.commonProperties.deviceId,
257
+ deviceClass: Telemetry.commonProperties.deviceClass,
258
+ };
259
+ telemetryItem.ext.os = {
260
+ locale: Telemetry.commonProperties.deviceLocale,
261
+ ver: Telemetry.commonProperties.fullBuildInfo,
262
+ };
263
+ // Populate most of "common" properties into Part B.
264
+ telemetryItem.baseData = {
265
+ common: {
266
+ device: {
267
+ architecture: Telemetry.commonProperties.deviceArchitecture,
268
+ numCPUs: Telemetry.commonProperties.numCPUs,
269
+ totalMemory: Telemetry.commonProperties.totalMemory,
270
+ diskFreeSpace: Telemetry.commonProperties.deviceDiskFreeSpace,
271
+ },
272
+ nodePlatform: Telemetry.commonProperties.nodePlatform,
273
+ nodeArchitecture: Telemetry.commonProperties.nodeArchitecture,
274
+ ciCaptured: Telemetry.commonProperties.ciCaptured,
275
+ ciType: Telemetry.commonProperties.ciType,
276
+ isMsftInternal: Telemetry.commonProperties.isMsftInternal,
277
+ isCliTest: Telemetry.commonProperties.isTest,
278
+ sessionId: Telemetry.commonProperties.sessionId,
279
+ commandName: Telemetry.commonProperties.commandName,
280
+ },
281
+ // Set project and versions props, belonging to Part B.
282
+ project: Telemetry.projectProp,
283
+ versions: Telemetry.versionsProp,
284
+ };
285
+ // Send and post the telemetry event!
286
+ Telemetry.appInsightsCore.track(telemetryItem);
287
+ Telemetry.appInsightsCore.flush();
288
+ }
286
289
  static trackCommandEvent(extraProps) {
287
290
  var _a, _b, _c, _d;
288
- const props = {
289
- eventName: exports.CommandEventName,
290
- };
291
- // Set command props
292
- props.command = {
291
+ const telemetryItem = { name: exports.CommandEventName };
292
+ // This is logged in Part C.
293
+ const command = {
293
294
  options: (_a = Telemetry.commandInfo.startInfo) === null || _a === void 0 ? void 0 : _a.options,
294
295
  defaultOptions: (_b = Telemetry.commandInfo.startInfo) === null || _b === void 0 ? void 0 : _b.defaultOptions,
295
296
  args: (_c = Telemetry.commandInfo.startInfo) === null || _c === void 0 ? void 0 : _c.args,
@@ -297,41 +298,38 @@ class Telemetry {
297
298
  1000,
298
299
  resultCode: (_d = Telemetry.commandInfo.endInfo) === null || _d === void 0 ? void 0 : _d.resultCode,
299
300
  };
300
- // Set remaining common props
301
- props.project = Telemetry.projectProp;
302
- props.versions = Telemetry.versionsProp;
303
- // Set extra props
304
- props.extraProps = {};
305
- Object.assign(props.extraProps, extraProps);
306
- // Fire event
307
- Telemetry.client.trackEvent({ name: props.eventName, properties: props });
308
- Telemetry.client.flush();
301
+ telemetryItem.data = {
302
+ command: command,
303
+ };
304
+ if (extraProps) {
305
+ telemetryItem.data.additionalData = extraProps;
306
+ }
307
+ // Populate common properties and fire event
308
+ Telemetry.trackEvent(telemetryItem);
309
309
  }
310
310
  static trackException(error, extraProps) {
311
311
  var _a, _b;
312
- if (!Telemetry.client) {
312
+ if (!Telemetry.appInsightsCore) {
313
313
  return;
314
314
  }
315
- const props = {
316
- eventName: exports.CodedErrorEventName,
317
- };
318
- // Save off CodedError info
315
+ const telemetryItem = { name: exports.CodedErrorEventName };
316
+ // Save off CodedError info in Part C.
319
317
  const codedError = error instanceof errorUtils.CodedError
320
318
  ? error
321
319
  : null;
322
- props.codedError = {
320
+ const codedErrorStruct = {
323
321
  type: (_a = codedError === null || codedError === void 0 ? void 0 : codedError.type) !== null && _a !== void 0 ? _a : 'Unknown',
324
322
  data: (_b = codedError === null || codedError === void 0 ? void 0 : codedError.data) !== null && _b !== void 0 ? _b : {},
325
323
  };
326
324
  // Copy msBuildErrorMessages into the codedError.data object
327
325
  if (error.msBuildErrorMessages) {
328
326
  // Always grab MSBuild error codes if possible
329
- props.codedError.data.msBuildErrors = error.msBuildErrorMessages
327
+ codedErrorStruct.data.msBuildErrors = error.msBuildErrorMessages
330
328
  .map(errorUtils.tryGetErrorCode)
331
329
  .filter((msg) => msg);
332
330
  // Grab sanitized MSBuild error messages if we're preserving them
333
331
  if (Telemetry.options.preserveErrorMessages) {
334
- props.codedError.data.msBuildErrorMessages = error.msBuildErrorMessages
332
+ codedErrorStruct.data.msBuildErrorMessages = error.msBuildErrorMessages
335
333
  .map(errorUtils.sanitizeErrorMessage)
336
334
  .filter((msg) => msg);
337
335
  }
@@ -340,32 +338,97 @@ class Telemetry {
340
338
  const syscallExceptionFieldsToCopy = ['errno', 'syscall', 'code'];
341
339
  for (const f of syscallExceptionFieldsToCopy) {
342
340
  if (error[f]) {
343
- props.codedError.data[f] = error[f];
341
+ codedErrorStruct.data[f] = error[f];
344
342
  }
345
343
  }
346
- // Set remaining common props
347
- props.project = Telemetry.projectProp;
348
- props.versions = Telemetry.versionsProp;
349
- // Set extra props
350
- props.extraProps = {};
351
- Object.assign(props.extraProps, extraProps);
352
- // Fire event
353
- Telemetry.client.trackException({
354
- exception: error,
355
- properties: props,
344
+ // Scrub any potential PII present in codedError.data array, as long as the data is a string.
345
+ codedErrorStruct.data = Telemetry.sanitizeAny(codedErrorStruct.data);
346
+ // Break down TS Error object into Exception Data
347
+ const exceptionData = Telemetry.convertErrorIntoExceptionData(error);
348
+ telemetryItem.data = {
349
+ codedError: codedErrorStruct,
350
+ exceptionData: exceptionData,
351
+ };
352
+ Telemetry.trackEvent(telemetryItem);
353
+ }
354
+ static convertErrorIntoExceptionData(error) {
355
+ var _a;
356
+ const exceptionData = {
357
+ hasFullStack: false,
358
+ message: error.message,
359
+ parsedStack: {},
360
+ };
361
+ exceptionData.message = exceptionData.message || '[None]';
362
+ // CodedError has non-PII information in its 'type' member, plus optionally some more info in its 'data'.
363
+ // The message may contain PII information. This can be sanitized, but for now delete it.
364
+ if (Telemetry.options.preserveErrorMessages) {
365
+ exceptionData.message = errorUtils.sanitizeErrorMessage(exceptionData.message);
366
+ }
367
+ else {
368
+ exceptionData.message = '[Removed]';
369
+ }
370
+ const lines = (_a = error.stack) === null || _a === void 0 ? void 0 : _a.split('\n');
371
+ const parsedStack = lines === null || lines === void 0 ? void 0 : lines.slice(1).map(line => {
372
+ const errorStackFrame = {};
373
+ const match = line
374
+ .trim()
375
+ .match(/^\s*at\s+(?:(.*?)\s+\((.*):(\d+):(\d+)\)|(.*):(\d+):(\d+))$/);
376
+ if (match) {
377
+ errorStackFrame.functionName = match[1] || 'N/A'; // Use a default value if no function name
378
+ errorStackFrame.filePath = match[2] || match[5];
379
+ errorStackFrame.lineNumber =
380
+ parseInt(match[3], 10) || parseInt(match[6], 10);
381
+ errorStackFrame.columnNumber =
382
+ parseInt(match[4], 10) || parseInt(match[7], 10);
383
+ }
384
+ return errorStackFrame;
356
385
  });
357
- Telemetry.client.flush();
386
+ if (parsedStack) {
387
+ parsedStack.filter(Boolean);
388
+ // Sanitize parsed error stack frames
389
+ for (const frame of parsedStack) {
390
+ errorUtils.sanitizeErrorStackFrame(frame);
391
+ }
392
+ exceptionData.hasFullStack = true;
393
+ exceptionData.parsedStack = parsedStack;
394
+ }
395
+ return exceptionData;
396
+ }
397
+ static sanitizeAny(data) {
398
+ if (Array.isArray(data)) {
399
+ // This is an array, sanitize each element recursively.
400
+ return data.map(item => Telemetry.sanitizeAny(item));
401
+ }
402
+ else if (typeof data === 'object' && data !== null) {
403
+ // This is an object, sanitize each field recursively.
404
+ const sanitizedObject = {};
405
+ for (const key in data) {
406
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
407
+ sanitizedObject[key] = Telemetry.sanitizeAny(data[key]);
408
+ }
409
+ }
410
+ return sanitizedObject;
411
+ }
412
+ else if (typeof data === 'string') {
413
+ // The base case: this is a string, sanitize it.
414
+ return errorUtils.sanitizeErrorMessage(data);
415
+ }
416
+ // Not a string, return the data unchanged.
417
+ return data;
358
418
  }
359
419
  }
360
- Telemetry.client = undefined;
420
+ Telemetry.appInsightsCore = undefined;
361
421
  Telemetry.options = {
362
422
  setupString: Telemetry.getDefaultSetupString(),
363
423
  preserveErrorMessages: false,
364
424
  populateNpmPackageVersions: true,
365
425
  };
366
- Telemetry.isTest = basePropUtils.isCliTest();
426
+ Telemetry.isTestEnvironment = basePropUtils.isCliTest();
367
427
  Telemetry.commandInfo = {};
428
+ // Stores the version of a list of packages used by the RNW app project.
368
429
  Telemetry.versionsProp = {};
369
430
  Telemetry.projectProp = undefined;
431
+ // Store "Common Properties" in a single object. This will be logged in all telemetry events.
432
+ Telemetry.commonProperties = {};
370
433
  exports.Telemetry = Telemetry;
371
434
  //# sourceMappingURL=telemetry.js.map