first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
#!/usr/bin/env node
export {};
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env node
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = require("commander");
const log_1 = require("./log");
const commands = __importStar(require("./command"));
/* global process */
const commander = new commander_1.Command();
commander.name("office-addin-usage-data");
commander.version(process.env.npm_package_version || "(version not available)");
commander
.command(`list`)
.description(`Display the current usage data settings.`)
.action(commands.listUsageDataSettings);
commander
.command(`off`)
.description(`Turn off reporting of anonymous usage data.`)
.action(commands.turnUsageDataOff);
commander
.command(`on`)
.description(`Turn on reporting of anonymous usage data.`)
.action(commands.turnUsageDataOn);
// if the command is not known, display an error
commander.on("command:*", function () {
(0, log_1.logErrorMessage)(`The command syntax is not valid.\n`);
process.exitCode = 1;
commander.help();
});
if (process.argv.length > 2) {
commander.parse(process.argv);
}
else {
commander.help();
}
//# sourceMappingURL=cli.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AAEA,4DAA4D;AAC5D,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;AAElC,yCAAoC;AACpC,+BAAwC;AACxC,oDAAsC;AAEtC,oBAAoB;AAEpB,MAAM,SAAS,GAAG,IAAI,mBAAO,EAAE,CAAC;AAEhC,SAAS,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AAC1C,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,yBAAyB,CAAC,CAAC;AAEhF,SAAS;KACN,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;AAE1C,SAAS;KACN,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAErC,SAAS;KACN,OAAO,CAAC,IAAI,CAAC;KACb,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AAEpC,gDAAgD;AAChD,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE;IACxB,IAAA,qBAAe,EAAC,oCAAoC,CAAC,CAAC;IACtD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACrB,SAAS,CAAC,IAAI,EAAE,CAAC;AACnB,CAAC,CAAC,CAAC;AAEH,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;IAC3B,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;KAAM;IACL,SAAS,CAAC,IAAI,EAAE,CAAC;CAClB"}
+3
View File
@@ -0,0 +1,3 @@
export declare function listUsageDataSettings(): void;
export declare function turnUsageDataOff(): void;
export declare function turnUsageDataOn(): void;
+69
View File
@@ -0,0 +1,69 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.turnUsageDataOn = exports.turnUsageDataOff = exports.listUsageDataSettings = void 0;
const defaults = __importStar(require("./defaults"));
const usageData_1 = require("./usageData");
const jsonData = __importStar(require("./usageDataSettings"));
/* global console */
function listUsageDataSettings() {
const usageDataSettings = jsonData.readUsageDataSettings(defaults.groupName);
if (usageDataSettings) {
for (const value of Object.keys(usageDataSettings)) {
console.log(`${value}: ${usageDataSettings[value]}\n`);
}
}
else {
console.log(`No usage data settings.`);
}
}
exports.listUsageDataSettings = listUsageDataSettings;
function turnUsageDataOff() {
setUsageDataLevel(usageData_1.UsageDataLevel.off);
}
exports.turnUsageDataOff = turnUsageDataOff;
function turnUsageDataOn() {
setUsageDataLevel(usageData_1.UsageDataLevel.on);
}
exports.turnUsageDataOn = turnUsageDataOn;
function setUsageDataLevel(level) {
try {
jsonData.modifyUsageDataJsonData(defaults.groupName, "usageDataLevel", level);
switch (level) {
case usageData_1.UsageDataLevel.off:
console.log("Usage data has been turned off.");
break;
case usageData_1.UsageDataLevel.on:
console.log("Usage data has been turned on.");
break;
}
}
catch (err) {
throw new Error(`Unable to set the usage data level.\n${err}`);
}
}
//# sourceMappingURL=command.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;AAElC,qDAAuC;AACvC,2CAA6C;AAC7C,8DAAgD;AAEhD,oBAAoB;AAEpB,SAAgB,qBAAqB;IACnC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE7E,IAAI,iBAAiB,EAAE;QACrB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE;YAClD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,KAAK,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SACxD;KACF;SAAM;QACL,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;KACxC;AACH,CAAC;AAVD,sDAUC;AAED,SAAgB,gBAAgB;IAC9B,iBAAiB,CAAC,0BAAc,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC;AAFD,4CAEC;AAED,SAAgB,eAAe;IAC7B,iBAAiB,CAAC,0BAAc,CAAC,EAAE,CAAC,CAAC;AACvC,CAAC;AAFD,0CAEC;AAED,SAAS,iBAAiB,CAAC,KAAqB;IAC9C,IAAI;QACF,QAAQ,CAAC,uBAAuB,CAAC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAE9E,QAAQ,KAAK,EAAE;YACb,KAAK,0BAAc,CAAC,GAAG;gBACrB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;gBAC/C,MAAM;YACR,KAAK,0BAAc,CAAC,EAAE;gBACpB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;gBAC9C,MAAM;SACT;KACF;IAAC,OAAO,GAAG,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;KAChE;AACH,CAAC"}
+4
View File
@@ -0,0 +1,4 @@
export declare const usageDataJsonFilePath: string;
export declare const groupName: string;
export declare const instrumentationKeyForOfficeAddinCLITools: string;
export declare const generatorOffice: string;
+15
View File
@@ -0,0 +1,15 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generatorOffice = exports.instrumentationKeyForOfficeAddinCLITools = exports.groupName = exports.usageDataJsonFilePath = void 0;
const os_1 = __importDefault(require("os"));
const path_1 = __importDefault(require("path"));
exports.usageDataJsonFilePath = path_1.default.join(os_1.default.homedir(), "/office-addin-usage-data.json");
exports.groupName = "office-addin-usage-data";
exports.instrumentationKeyForOfficeAddinCLITools = "de0d9e7c-1f46-4552-bc21-4e43e489a015";
exports.generatorOffice = "generator-office";
//# sourceMappingURL=defaults.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;;;;AAElC,4CAAoB;AACpB,gDAAwB;AAEX,QAAA,qBAAqB,GAAW,cAAI,CAAC,IAAI,CACpD,YAAE,CAAC,OAAO,EAAE,EACZ,+BAA+B,CAChC,CAAC;AACW,QAAA,SAAS,GAAW,yBAAyB,CAAC;AAC9C,QAAA,wCAAwC,GACnD,sCAAsC,CAAC;AAC5B,QAAA,eAAe,GAAW,kBAAkB,CAAC"}
+5
View File
@@ -0,0 +1,5 @@
/**
* Logs an error message
* @param err The error to be logged
*/
export declare function logErrorMessage(err: any): void;
+15
View File
@@ -0,0 +1,15 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.logErrorMessage = void 0;
/* global console */
/**
* Logs an error message
* @param err The error to be logged
*/
function logErrorMessage(err) {
console.error(`Error: ${err instanceof Error ? err.message : err}`);
}
exports.logErrorMessage = logErrorMessage;
//# sourceMappingURL=log.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAElC,oBAAoB;AAEpB;;;GAGG;AACH,SAAgB,eAAe,CAAC,GAAQ;IACtC,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AACtE,CAAC;AAFD,0CAEC"}
+4
View File
@@ -0,0 +1,4 @@
export * from "./defaults";
export * from "./log";
export * from "./usageData";
export * from "./usageDataSettings";
+23
View File
@@ -0,0 +1,23 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./defaults"), exports);
__exportStar(require("./log"), exports);
__exportStar(require("./usageData"), exports);
__exportStar(require("./usageDataSettings"), exports);
//# sourceMappingURL=main.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;;;;;;;;;;;;;;AAElC,6CAA2B;AAC3B,wCAAsB;AACtB,8CAA4B;AAC5B,sDAAoC"}
+181
View File
@@ -0,0 +1,181 @@
/**
* Specifies the usage data infrastructure the user wishes to use
* @enum Application Insights: Microsoft Azure service used to collect and query through data
*/
export declare enum UsageDataReportingMethod {
applicationInsights = "applicationInsights"
}
/**
* Level controlling what type of usage data is being sent
* @enum off: off level of usage data, sends no usage data
* @enum on: on level of usage data, sends errors and events
*/
export declare enum UsageDataLevel {
off = "off",
on = "on"
}
/**
* Defines an error that is expected to happen given some situation
* @member message Message to be logged in the error
*/
export declare class ExpectedError extends Error {
constructor(message: string | undefined);
}
/**
* UpdateData options
* @member groupName Group name for usage data settings (Optional)
* @member projectName The name of the project that is using the usage data package.
* @member instrumentationKey Instrumentation key for usage data resource
* @member promptQuestion Question displayed to user over opt-in for usage data (Optional)
* @member raisePrompt Specifies whether to raise usage data prompt (this allows for using a custom prompt) (Optional)
* @member usageDataLevel User's response to the prompt for usage data (Optional)
* @member method The desired method to use for reporting usage data. (Optional)
* @member isForTesting True if the data is just for testing, false for actual data that should be reported. (Optional)
*/
export interface IUsageDataOptions {
groupName?: string;
projectName: string;
instrumentationKey: string;
promptQuestion?: string;
raisePrompt?: boolean;
usageDataLevel?: UsageDataLevel;
method?: UsageDataReportingMethod;
isForTesting?: boolean;
deviceID?: string;
}
/**
* Creates and initializes member variables while prompting user for usage data collection when necessary
* @param usageDataObject
*/
export declare class OfficeAddinUsageData {
private usageDataClient;
private eventsSent;
private exceptionsSent;
private options;
private defaultData;
constructor(usageDataOptions: IUsageDataOptions);
/**
* Reports custom event object to usage data structure
* @param eventName Event name sent to usage data structure
* @param data Data object sent to usage data structure
*/
reportEvent(eventName: string, data: object): Promise<void>;
/**
* Reports custom event object to Application Insights
* @param eventName Event name sent to Application Insights
* @param data Data object sent to Application Insights
*/
reportEventApplicationInsights(eventName: string, data: object): Promise<void>;
/**
* Reports error to usage data structure
* @param errorName Error name sent to usage data structure
* @param err Error sent to usage data structure
*/
reportError(errorName: string, err: Error): Promise<void>;
/**
* Reports error to Application Insights
* @param errorName Error name sent to Application Insights
* @param err Error sent to Application Insights
*/
reportErrorApplicationInsights(errorName: string, err: Error): Promise<void>;
/**
* Prompts user for usage data participation once and records response
* @param testData Specifies whether test code is calling this method
* @param testReponse Specifies test response
*/
usageDataOptIn(testData?: boolean, testResponse?: string): void;
/**
* Stops usage data from being sent, by default usage data will be on
*/
setUsageDataOff(): void;
/**
* Starts sending usage data, by default usage data will be on
*/
setUsageDataOn(): void;
/**
* Returns whether the usage data is currently on or off
* @returns Whether usage data is turned on or off
*/
isUsageDataOn(): boolean;
/**
* Returns the instrumentation key associated with the resource
* @returns The usage data instrumentation key
*/
getUsageDataKey(): string;
/**
* Transform the project name by adddin '-test' suffix to it if necessary
*/
private getEventName;
/**
* Returns the amount of events that have been sent
* @returns The count of events sent
*/
getEventsSent(): any;
/**
* Returns the amount of exceptions that have been sent
* @returns The count of exceptions sent
*/
getExceptionsSent(): any;
/**
* Get the usage data level
* @returns the usage data level
*/
getUsageDataLevel(): string;
/**
* Returns parsed file path, scrubbing file names and sensitive information
* @returns Error after removing PII
*/
maskFilePaths(err: Error): Error;
/**
* Removes sensitive information fields from ApplicationInsights data
*/
private removeApplicationInsightsSensitiveInformation;
/**
* Reports custom exception event object to Application Insights
* @param method Method name sent to Application Insights
* @param err Error or message about error sent to Application Insights
* @param data Data object(s) sent to Application Insights
*/
reportException(method: string, err: Error | string, data?: object): void;
/**
* Reports custom expected exception event object to Application Insights
* @param method Method name sent to Application Insights
* @param err Error or message about error sent to Application Insights
* @param data Data object(s) sent to Application Insights
*/
reportExpectedException(method: string, err: Error | string, data?: object): void;
/**
* Reports custom success event object to Application Insights
* @param method Method name sent to Application Insights
* @param data Data object(s) sent to Application Insights
*/
reportSuccess(method: string, data?: object): void;
/**
* Reports custom exception event object to Application Insights
* @param method Method name sent to Application Insights
* @param err Error or message about error sent to Application Insights
* @param data Data object(s) sent to Application Insights
* @deprecated Use `reportUnexpectedError` instead.
*/
sendUsageDataException(method: string, err: Error | string, data?: object): void;
/**
* Reports custom success event object to Application Insights
* @param method Method name sent to Application Insights
* @param data Data object(s) sent to Application Insights
* @deprecated Use `reportSuccess` instead.
*/
sendUsageDataSuccessEvent(method: string, data?: object): void;
/**
* Reports custom successful fail event object to Application Insights
* "Successful fail" means that there was an error as a result of user error, but our code worked properly
* @param method Method name sent to Application Insights
* @param data Data object(s) sent to Application Insights
* @deprecated Use `reportExpectedError` instead.
*/
sendUsageDataSuccessfulFailEvent(method: string, data?: object): void;
/**
* Reports custom event object to Application Insights
* @param data Data object(s) sent to Application Insights
*/
sendUsageDataEvent(data?: object): void;
}
+423
View File
@@ -0,0 +1,423 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OfficeAddinUsageData = exports.ExpectedError = exports.UsageDataLevel = exports.UsageDataReportingMethod = void 0;
const appInsights = __importStar(require("applicationinsights"));
const readline_sync_1 = __importDefault(require("readline-sync"));
const jsonData = __importStar(require("./usageDataSettings"));
const defaults = __importStar(require("./defaults"));
/* global process */
/**
* Specifies the usage data infrastructure the user wishes to use
* @enum Application Insights: Microsoft Azure service used to collect and query through data
*/
var UsageDataReportingMethod;
(function (UsageDataReportingMethod) {
UsageDataReportingMethod["applicationInsights"] = "applicationInsights";
})(UsageDataReportingMethod = exports.UsageDataReportingMethod || (exports.UsageDataReportingMethod = {}));
/**
* Level controlling what type of usage data is being sent
* @enum off: off level of usage data, sends no usage data
* @enum on: on level of usage data, sends errors and events
*/
var UsageDataLevel;
(function (UsageDataLevel) {
UsageDataLevel["off"] = "off";
UsageDataLevel["on"] = "on";
})(UsageDataLevel = exports.UsageDataLevel || (exports.UsageDataLevel = {}));
/**
* Defines an error that is expected to happen given some situation
* @member message Message to be logged in the error
*/
class ExpectedError extends Error {
constructor(message) {
super(message);
// need to adjust the prototype after super()
// See https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(this, ExpectedError.prototype);
}
}
exports.ExpectedError = ExpectedError;
/**
* Creates and initializes member variables while prompting user for usage data collection when necessary
* @param usageDataObject
*/
class OfficeAddinUsageData {
constructor(usageDataOptions) {
this.usageDataClient = appInsights.defaultClient;
this.eventsSent = 0;
this.exceptionsSent = 0;
this.defaultData = {
Platform: process.platform,
NodeVersion: process.version,
};
try {
this.options = Object.assign({ groupName: defaults.groupName, promptQuestion: "", raisePrompt: true, usageDataLevel: UsageDataLevel.off, method: UsageDataReportingMethod.applicationInsights, isForTesting: false }, usageDataOptions);
if (this.options.instrumentationKey === undefined) {
throw new Error("Instrumentation Key not defined - cannot create usage data object");
}
if (this.options.groupName === undefined) {
throw new Error("Group Name not defined - cannot create usage data object");
}
if (jsonData.groupNameExists(this.options.groupName)) {
this.options.usageDataLevel = jsonData.readUsageDataLevel(this.options.groupName);
}
// Generator-office will not raise a prompt because the yeoman generator creates the prompt. If the projectName
// is defaults.generatorOffice and a office-addin-usage-data file hasn't been written yet, write one out.
if (this.options.projectName === defaults.generatorOffice &&
this.options.instrumentationKey === defaults.instrumentationKeyForOfficeAddinCLITools &&
jsonData.needToPromptForUsageData(this.options.groupName)) {
jsonData.writeUsageDataJsonData(this.options.groupName, this.options.usageDataLevel);
}
if (!this.options.isForTesting &&
this.options.raisePrompt &&
jsonData.needToPromptForUsageData(this.options.groupName)) {
this.usageDataOptIn();
}
this.options.deviceID = jsonData.readDeviceID();
if (this.options.usageDataLevel === UsageDataLevel.on) {
appInsights.setup(this.options.instrumentationKey).setAutoCollectExceptions(false).start();
this.usageDataClient = appInsights.defaultClient;
this.removeApplicationInsightsSensitiveInformation();
}
}
catch (err) {
throw new Error(err);
}
}
/**
* Reports custom event object to usage data structure
* @param eventName Event name sent to usage data structure
* @param data Data object sent to usage data structure
*/
reportEvent(eventName, data) {
return __awaiter(this, void 0, void 0, function* () {
if (this.getUsageDataLevel() === UsageDataLevel.on) {
this.reportEventApplicationInsights(eventName, data);
}
});
}
/**
* Reports custom event object to Application Insights
* @param eventName Event name sent to Application Insights
* @param data Data object sent to Application Insights
*/
reportEventApplicationInsights(eventName, data) {
return __awaiter(this, void 0, void 0, function* () {
if (this.getUsageDataLevel() === UsageDataLevel.on) {
const usageDataEvent = new appInsights.Contracts.EventData();
usageDataEvent.name = this.options.isForTesting ? `${eventName}-test` : eventName;
try {
for (const [key, [value, elapsedTime]] of Object.entries(data)) {
usageDataEvent.properties[key] = value;
usageDataEvent.measurements[key + " durationElapsed"] = elapsedTime;
}
usageDataEvent.properties["deviceID"] = this.options.deviceID;
this.usageDataClient.trackEvent(usageDataEvent);
this.eventsSent++;
}
catch (err) {
this.reportError("sendUsageDataEvents", err);
throw new Error(err);
}
}
});
}
/**
* Reports error to usage data structure
* @param errorName Error name sent to usage data structure
* @param err Error sent to usage data structure
*/
reportError(errorName, err) {
return __awaiter(this, void 0, void 0, function* () {
if (this.getUsageDataLevel() === UsageDataLevel.on) {
this.reportErrorApplicationInsights(errorName, err);
}
});
}
/**
* Reports error to Application Insights
* @param errorName Error name sent to Application Insights
* @param err Error sent to Application Insights
*/
reportErrorApplicationInsights(errorName, err) {
return __awaiter(this, void 0, void 0, function* () {
if (this.getUsageDataLevel() === UsageDataLevel.on) {
let error = Object.create(err);
error.name = this.options.isForTesting ? `${errorName}-test` : errorName;
this.usageDataClient.trackException({
exception: this.maskFilePaths(error),
});
this.exceptionsSent++;
}
});
}
/**
* Prompts user for usage data participation once and records response
* @param testData Specifies whether test code is calling this method
* @param testReponse Specifies test response
*/
usageDataOptIn(testData = this.options.isForTesting, testResponse = "") {
try {
let response = "";
if (testData) {
response = testResponse;
}
else {
response = readline_sync_1.default.question(`${this.options.promptQuestion}\n`);
}
if (response.toLowerCase() === "y") {
this.options.usageDataLevel = UsageDataLevel.on;
}
else {
this.options.usageDataLevel = UsageDataLevel.off;
}
jsonData.writeUsageDataJsonData(this.options.groupName, this.options.usageDataLevel);
}
catch (err) {
this.reportError("UsageDataOptIn", err);
throw new Error(err);
}
}
/**
* Stops usage data from being sent, by default usage data will be on
*/
setUsageDataOff() {
appInsights.defaultClient.config.samplingPercentage = 0;
}
/**
* Starts sending usage data, by default usage data will be on
*/
setUsageDataOn() {
appInsights.defaultClient.config.samplingPercentage = 100;
}
/**
* Returns whether the usage data is currently on or off
* @returns Whether usage data is turned on or off
*/
isUsageDataOn() {
return appInsights.defaultClient.config.samplingPercentage === 100;
}
/**
* Returns the instrumentation key associated with the resource
* @returns The usage data instrumentation key
*/
getUsageDataKey() {
return this.options.instrumentationKey;
}
/**
* Transform the project name by adddin '-test' suffix to it if necessary
*/
getEventName() {
return this.options.isForTesting
? `${this.options.projectName}-test`
: this.options.projectName;
}
/**
* Returns the amount of events that have been sent
* @returns The count of events sent
*/
getEventsSent() {
return this.eventsSent;
}
/**
* Returns the amount of exceptions that have been sent
* @returns The count of exceptions sent
*/
getExceptionsSent() {
return this.exceptionsSent;
}
/**
* Get the usage data level
* @returns the usage data level
*/
getUsageDataLevel() {
return this.options.usageDataLevel;
}
/**
* Returns parsed file path, scrubbing file names and sensitive information
* @returns Error after removing PII
*/
maskFilePaths(err) {
try {
const regexRemoveUserFilePaths = /(\w:)*[/\\](.*[/\\]+)*(.+\.)+[a-zA-Z]+/gim;
const maskToken = "<filepath>";
err.message = err.message.replace(regexRemoveUserFilePaths, maskToken);
err.stack = err.stack.replace(regexRemoveUserFilePaths, maskToken);
return err;
}
catch (err) {
this.reportError("maskFilePaths", err);
throw new Error(err);
}
}
/**
* Removes sensitive information fields from ApplicationInsights data
*/
removeApplicationInsightsSensitiveInformation() {
delete this.usageDataClient.context.tags["ai.cloud.roleInstance"]; // cloud name
delete this.usageDataClient.context.tags["ai.device.id"]; // machine name
delete this.usageDataClient.context.tags["ai.user.accountId"]; // subscription
}
/**
* Reports custom exception event object to Application Insights
* @param method Method name sent to Application Insights
* @param err Error or message about error sent to Application Insights
* @param data Data object(s) sent to Application Insights
*/
reportException(method, err, data = {}) {
if (this.getUsageDataLevel() === UsageDataLevel.on) {
try {
if (err instanceof ExpectedError) {
this.reportExpectedException(method, err, data);
return;
}
let error = err instanceof Error
? Object.create(err)
: new Error(`${this.options.projectName} error: ${err}`);
error.name = this.getEventName();
let exceptionTelemetryObj = {
exception: this.maskFilePaths(error),
properties: {},
};
Object.entries(Object.assign(Object.assign(Object.assign({ Succeeded: false, Method: method, ExpectedError: false }, this.defaultData), data), { deviceID: this.options.deviceID })).forEach((entry) => {
exceptionTelemetryObj.properties[entry[0]] = JSON.stringify(entry[1]);
});
this.usageDataClient.trackException(exceptionTelemetryObj);
this.exceptionsSent++;
}
catch (e) {
this.reportError("reportException", e);
throw e;
}
}
}
/**
* Reports custom expected exception event object to Application Insights
* @param method Method name sent to Application Insights
* @param err Error or message about error sent to Application Insights
* @param data Data object(s) sent to Application Insights
*/
reportExpectedException(method, err, data = {}) {
let error = err instanceof Error
? Object.create(err)
: new Error(`${this.options.projectName} error: ${err}`);
error.name = this.getEventName();
this.maskFilePaths(error);
const errorMessage = error instanceof Error ? error.message : error;
this.sendUsageDataEvent(Object.assign({ Succeeded: true, Method: method, ExpectedError: true, Error: errorMessage }, data));
}
/**
* Reports custom success event object to Application Insights
* @param method Method name sent to Application Insights
* @param data Data object(s) sent to Application Insights
*/
reportSuccess(method, data = {}) {
this.sendUsageDataEvent(Object.assign({ Succeeded: true, Method: method, ExpectedError: false }, data));
}
/**
* Reports custom exception event object to Application Insights
* @param method Method name sent to Application Insights
* @param err Error or message about error sent to Application Insights
* @param data Data object(s) sent to Application Insights
* @deprecated Use `reportUnexpectedError` instead.
*/
sendUsageDataException(method, err, data = {}) {
if (this.getUsageDataLevel() === UsageDataLevel.on) {
try {
let error = err instanceof Error
? Object.create(err)
: new Error(`${this.options.projectName} error: ${err}`);
error.name = this.getEventName();
let exceptionTelemetryObj = {
exception: this.maskFilePaths(error),
properties: {},
};
Object.entries(Object.assign(Object.assign({ Succeeded: false, Method: method }, this.defaultData), data)).forEach((entry) => {
exceptionTelemetryObj.properties[entry[0]] = JSON.stringify(entry[1]);
});
this.usageDataClient.trackException(exceptionTelemetryObj);
this.exceptionsSent++;
}
catch (e) {
this.reportError("sendUsageDataException", e);
throw e;
}
}
}
/**
* Reports custom success event object to Application Insights
* @param method Method name sent to Application Insights
* @param data Data object(s) sent to Application Insights
* @deprecated Use `reportSuccess` instead.
*/
sendUsageDataSuccessEvent(method, data = {}) {
this.sendUsageDataEvent(Object.assign({ Succeeded: true, Method: method, Pass: true }, data));
}
/**
* Reports custom successful fail event object to Application Insights
* "Successful fail" means that there was an error as a result of user error, but our code worked properly
* @param method Method name sent to Application Insights
* @param data Data object(s) sent to Application Insights
* @deprecated Use `reportExpectedError` instead.
*/
sendUsageDataSuccessfulFailEvent(method, data = {}) {
this.sendUsageDataEvent(Object.assign({ Succeeded: true, Method: method, Pass: false }, data));
}
/**
* Reports custom event object to Application Insights
* @param data Data object(s) sent to Application Insights
*/
sendUsageDataEvent(data = {}) {
if (this.getUsageDataLevel() === UsageDataLevel.on) {
try {
let eventTelemetryObj = new appInsights.Contracts.EventData();
eventTelemetryObj.name = this.getEventName();
eventTelemetryObj.properties = Object.assign(Object.assign(Object.assign({}, this.defaultData), data), { deviceID: this.options.deviceID });
this.usageDataClient.trackEvent(eventTelemetryObj);
this.eventsSent++;
}
catch (e) {
this.reportError("sendUsageDataEvent", e);
}
}
}
}
exports.OfficeAddinUsageData = OfficeAddinUsageData;
//# sourceMappingURL=usageData.js.map
File diff suppressed because one or more lines are too long
+54
View File
@@ -0,0 +1,54 @@
import { UsageDataLevel } from "./usageData";
/**
* Allows developer to check if the program has already prompted before
* @param groupName Group name of the usage data object
* @returns Boolean of whether the program should prompt
*/
export declare function needToPromptForUsageData(groupName: string): boolean;
/**
* Allows developer to add or modify a specific property to the group
* @param groupName Group name of property
* @param property Property that will be created or modified
* @param value Property's value that will be assigned
*/
export declare function modifyUsageDataJsonData(groupName: string, property: any, value: any): void;
/**
* Returns the session identifier
* @returns The uuid of the session identifier
*/
export declare function readDeviceID(): string;
/**
* Reads data from the usage data json config file
* @returns Parsed object from json file if it exists
*/
export declare function readUsageDataJsonData(): any;
/**
* Returns whether usage data is enabled on the usage data object
* @param groupName Group name to search for in the specified json data
* @returns Whether usage data is enabled specific to the group name
*/
export declare function readUsageDataLevel(groupName: string): UsageDataLevel;
/**
* Returns whether usage data is enabled on the usage data object
* @param groupName Group name to search for in the specified json data
* @param propertyName Property name that will be used to access and return the associated value
* @returns Property of the specific group name
*/
export declare function readUsageDataObjectProperty(groupName: string, propertyName: string): any;
/**
* Writes to usage data config file either appending to already existing file or creating new file
* @param groupName Group name of usage data object
* @param level usageDataLevel Whether user is sending none or full usage data
*/
export declare function writeUsageDataJsonData(groupName: string, level: UsageDataLevel): void;
/**
* Checks to see if the given group name exists in the specified json data
* @param groupName Group name to search for in the specified json data
* @returns Boolean of whether group name exists
*/
export declare function groupNameExists(groupName: string): boolean;
/**
* Reads usage data settings from the usage data json config file for a specific group
* @returns Settings for the specified group
*/
export declare function readUsageDataSettings(groupName?: string): object | undefined;
+185
View File
@@ -0,0 +1,185 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.readUsageDataSettings = exports.groupNameExists = exports.writeUsageDataJsonData = exports.readUsageDataObjectProperty = exports.readUsageDataLevel = exports.readUsageDataJsonData = exports.readDeviceID = exports.modifyUsageDataJsonData = exports.needToPromptForUsageData = void 0;
const fs_1 = __importDefault(require("fs"));
const defaults = __importStar(require("./defaults"));
const uuid_1 = require("uuid");
/**
* Allows developer to check if the program has already prompted before
* @param groupName Group name of the usage data object
* @returns Boolean of whether the program should prompt
*/
function needToPromptForUsageData(groupName) {
return !groupNameExists(groupName);
}
exports.needToPromptForUsageData = needToPromptForUsageData;
/**
* Allows developer to add or modify a specific property to the group
* @param groupName Group name of property
* @param property Property that will be created or modified
* @param value Property's value that will be assigned
*/
function modifyUsageDataJsonData(groupName, property, value) {
try {
if (readUsageDataJsonData()) {
const usageDataJsonData = readUsageDataJsonData();
if (!groupNameExists(groupName)) {
usageDataJsonData.usageDataInstances[groupName] = {
usageDataLevel: String,
};
}
usageDataJsonData.usageDataInstances[groupName][property] = value;
if (!usageDataJsonData.usageDataInstances["deviceID"]) {
usageDataJsonData.usageDataInstances["deviceID"] = (0, uuid_1.v4)();
}
fs_1.default.writeFileSync(defaults.usageDataJsonFilePath, JSON.stringify(usageDataJsonData, null, 2));
}
else {
let usageDataJsonData = {};
usageDataJsonData[groupName] = value;
usageDataJsonData = { usageDataInstances: usageDataJsonData };
usageDataJsonData = {
usageDataInstances: { [groupName]: { [property]: value }, deviceID: (0, uuid_1.v4)() },
};
fs_1.default.writeFileSync(defaults.usageDataJsonFilePath, JSON.stringify(usageDataJsonData, null, 2));
}
}
catch (err) {
throw new Error(err);
}
}
exports.modifyUsageDataJsonData = modifyUsageDataJsonData;
/**
* Returns the session identifier
* @returns The uuid of the session identifier
*/
function readDeviceID() {
var _a;
const jsonData = readUsageDataJsonData();
return (_a = jsonData === null || jsonData === void 0 ? void 0 : jsonData.usageDataInstances.deviceID) !== null && _a !== void 0 ? _a : "";
}
exports.readDeviceID = readDeviceID;
/**
* Reads data from the usage data json config file
* @returns Parsed object from json file if it exists
*/
function readUsageDataJsonData() {
if (fs_1.default.existsSync(defaults.usageDataJsonFilePath)) {
const jsonData = fs_1.default.readFileSync(defaults.usageDataJsonFilePath, "utf8");
return JSON.parse(jsonData.toString());
}
}
exports.readUsageDataJsonData = readUsageDataJsonData;
/**
* Returns whether usage data is enabled on the usage data object
* @param groupName Group name to search for in the specified json data
* @returns Whether usage data is enabled specific to the group name
*/
function readUsageDataLevel(groupName) {
const jsonData = readUsageDataJsonData();
return jsonData.usageDataInstances[groupName].usageDataLevel;
}
exports.readUsageDataLevel = readUsageDataLevel;
/**
* Returns whether usage data is enabled on the usage data object
* @param groupName Group name to search for in the specified json data
* @param propertyName Property name that will be used to access and return the associated value
* @returns Property of the specific group name
*/
function readUsageDataObjectProperty(groupName, propertyName) {
const jsonData = readUsageDataJsonData();
return jsonData.usageDataInstances[groupName][propertyName];
}
exports.readUsageDataObjectProperty = readUsageDataObjectProperty;
/**
* Writes to usage data config file either appending to already existing file or creating new file
* @param groupName Group name of usage data object
* @param level usageDataLevel Whether user is sending none or full usage data
*/
function writeUsageDataJsonData(groupName, level) {
if (fs_1.default.existsSync(defaults.usageDataJsonFilePath) &&
fs_1.default.readFileSync(defaults.usageDataJsonFilePath, "utf8") !== "" &&
fs_1.default.readFileSync(defaults.usageDataJsonFilePath, "utf8") !== "undefined") {
if (groupNameExists(groupName)) {
modifyUsageDataJsonData(groupName, "usageDataLevel", level);
}
else {
const usageDataJsonData = readUsageDataJsonData();
usageDataJsonData.usageDataInstances[groupName] = {
usageDataLevel: String,
};
usageDataJsonData.usageDataInstances[groupName].usageDataLevel = level;
if (!usageDataJsonData.usageDataInstances["deviceID"]) {
usageDataJsonData.usageDataInstances["deviceID"] = (0, uuid_1.v4)();
}
fs_1.default.writeFileSync(defaults.usageDataJsonFilePath, JSON.stringify(usageDataJsonData, null, 2));
}
}
else {
let usageDataJsonData = {};
usageDataJsonData[groupName] = level;
usageDataJsonData = { usageDataInstances: usageDataJsonData };
usageDataJsonData = {
usageDataInstances: { [groupName]: { ["usageDataLevel"]: level }, deviceID: (0, uuid_1.v4)() },
};
fs_1.default.writeFileSync(defaults.usageDataJsonFilePath, JSON.stringify(usageDataJsonData, null, 2));
}
}
exports.writeUsageDataJsonData = writeUsageDataJsonData;
/**
* Checks to see if the given group name exists in the specified json data
* @param groupName Group name to search for in the specified json data
* @returns Boolean of whether group name exists
*/
function groupNameExists(groupName) {
if (fs_1.default.existsSync(defaults.usageDataJsonFilePath) &&
fs_1.default.readFileSync(defaults.usageDataJsonFilePath, "utf8") !== "" &&
fs_1.default.readFileSync(defaults.usageDataJsonFilePath, "utf8") !== "undefined") {
const jsonData = readUsageDataJsonData();
return Object.getOwnPropertyNames(jsonData.usageDataInstances).includes(groupName);
}
return false;
}
exports.groupNameExists = groupNameExists;
/**
* Reads usage data settings from the usage data json config file for a specific group
* @returns Settings for the specified group
*/
function readUsageDataSettings(groupName = defaults.groupName) {
if (fs_1.default.existsSync(defaults.usageDataJsonFilePath)) {
return readUsageDataJsonData().usageDataInstances[groupName];
}
else {
return undefined;
}
}
exports.readUsageDataSettings = readUsageDataSettings;
//# sourceMappingURL=usageDataSettings.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"usageDataSettings.js","sourceRoot":"","sources":["../src/usageDataSettings.ts"],"names":[],"mappings":"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"}