UNPKG

appcenter-cli

Version:

Command line tool for Visual Studio App Center

210 lines (209 loc) 10.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; 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 ShowCommand_1; Object.defineProperty(exports, "__esModule", { value: true }); const commandline_1 = require("../../../util/commandline"); const interaction_1 = require("../../../util/interaction"); const util_1 = require("util"); const _ = require("lodash"); const date_parsing_helper_1 = require("../lib/date-parsing-helper"); const percent_change_helper_1 = require("../lib/percent-change-helper"); const analytics_constants_1 = require("../lib/analytics-constants"); const debug = require("debug")("appcenter-cli:commands:analytics:events:show"); const pLimit = require("p-limit"); let ShowCommand = ShowCommand_1 = class ShowCommand extends commandline_1.AppCommand { constructor(args) { super(args); interaction_1.supportsCsv(this.additionalSupportedOutputFormats); } run(client) { return __awaiter(this, void 0, void 0, function* () { const app = this.app; const appVersion = this.toArrayWithSingleElement(this.appVersion); const eventName = this.toArrayWithSingleElement(this.eventName); const startDate = date_parsing_helper_1.parseDate(this.startDate, new Date(new Date().setHours(0, 0, 0, 0)), `start date value ${this.startDate} is not a valid date string`); const endDate = date_parsing_helper_1.parseDate(this.endDate, new Date(), `end date value ${this.endDate} is not a valid date string`); const eventCount = this.getEventCount(); const events = yield interaction_1.out.progress(`Loading statistics...`, this.getEvents(client, app, startDate, endDate, eventCount, this.properties, appVersion, eventName)); this.outputStatistics(events); return commandline_1.success(); }); } toArrayWithSingleElement(value) { return !_.isNil(value) ? [value] : undefined; } getEventCount() { const eventCount = Number(this.eventCount); if (Number.isSafeInteger(eventCount) && eventCount >= 0) { return eventCount; } else { throw commandline_1.failure(commandline_1.ErrorCodes.InvalidParameter, "--number-of-events should be non-negative integer"); } } getEvents(client, app, startDate, endDate, eventCount, loadProperties, appVersions, eventNames) { return __awaiter(this, void 0, void 0, function* () { let eventsStatistics; try { const result = yield client.analytics.events(startDate, app.ownerName, app.appName, { end: endDate, versions: appVersions, orderby: "count desc", top: eventCount, skip: 0, eventName: eventNames, inlinecount: "allpages", }); eventsStatistics = result.events.map((event) => ({ name: event.name, count: event.count, countChange: percent_change_helper_1.calculatePercentChange(event.count, event.previousCount), users: event.deviceCount, userChange: percent_change_helper_1.calculatePercentChange(event.deviceCount, event.previousDeviceCount), perUser: event.countPerDevice, perSession: event.countPerSession, })); } catch (error) { debug(`Failed to get events statistics - ${util_1.inspect(error)}`); throw commandline_1.failure(commandline_1.ErrorCodes.Exception, "failed to get events statistics"); } if (loadProperties) { const limit = pLimit(ShowCommand_1.numberOfParallelRequests); const propertiesPromises = eventsStatistics.map((eventStats) => this.getProperties(client, app, eventStats.name, startDate, endDate, appVersions, limit)); (yield Promise.all(propertiesPromises)).forEach((properties, index) => (eventsStatistics[index].properties = properties)); } return eventsStatistics; }); } getProperties(client, app, eventName, startDate, endDate, appVersions, limit) { return __awaiter(this, void 0, void 0, function* () { let propertiesNames; try { const httpContent = yield limit(() => client.analytics.eventProperties(eventName, app.ownerName, app.appName)); propertiesNames = httpContent.eventProperties; } catch (error) { debug(`Failed to get event properties of event ${eventName} - ${util_1.inspect(error)}`); throw commandline_1.failure(commandline_1.ErrorCodes.Exception, `failed to get event properties of event ${eventName}`); } const valuesStatsPromises = propertiesNames.map((propertyName) => this.getPropertyValueStatistics(client, app, eventName, propertyName, startDate, endDate, appVersions, limit)); return (yield Promise.all(valuesStatsPromises)).map((valueStats, index) => ({ name: propertiesNames[index], valuesStatistics: valueStats, })); }); } getPropertyValueStatistics(client, app, eventName, eventPropertyName, startDate, endDate, appVersions, limit) { return __awaiter(this, void 0, void 0, function* () { try { const result = yield client.analytics.eventPropertyCounts(eventName, eventPropertyName, startDate, app.ownerName, app.appName, { end: endDate, versions: appVersions, }); return result.values.map((value) => ({ value: value.name, count: value.count, countChange: percent_change_helper_1.calculatePercentChange(value.count, value.previousCount), })); } catch (error) { debug(`Failed to get values of property ${eventPropertyName} of event ${eventName} - ${util_1.inspect(error)}`); throw commandline_1.failure(commandline_1.ErrorCodes.Exception, `failed to get values of property ${eventPropertyName} of event ${eventName}`); } }); } outputStatistics(statistics) { interaction_1.out.reportObjectAsTitledTables((events, numberFormatter, dateFormatter, percentageFormatter) => { const table = []; const eventsTable = { name: "Events", content: [["Name", "Count", "Count Change", "Users", "User Change", "Per User", "Per Session"]], }; table.push(eventsTable); for (const event of events) { eventsTable.content.push([ event.name, numberFormatter(event.count), percentageFormatter(event.countChange), numberFormatter(event.users), percentageFormatter(event.userChange), numberFormatter(event.perUser), numberFormatter(event.perSession), ]); if (event.properties) { for (const property of event.properties) { eventsTable.content.push({ name: property.name, content: [["Value", "Count", "Count Change"]].concat(property.valuesStatistics.map((valueStats) => [ valueStats.value, numberFormatter(valueStats.count), percentageFormatter(valueStats.countChange), ])), }); } } } return table; }, statistics); } }; ShowCommand.numberOfParallelRequests = 10; __decorate([ commandline_1.help("Show statistics about event properties"), commandline_1.longName("properties") ], ShowCommand.prototype, "properties", void 0); __decorate([ commandline_1.help(analytics_constants_1.startDateHelpMessage), commandline_1.shortName("s"), commandline_1.longName("start"), commandline_1.hasArg ], ShowCommand.prototype, "startDate", void 0); __decorate([ commandline_1.help(analytics_constants_1.endDateHelpMessage), commandline_1.shortName("e"), commandline_1.longName("end"), commandline_1.hasArg ], ShowCommand.prototype, "endDate", void 0); __decorate([ commandline_1.help("Filter the list of events by app version"), commandline_1.shortName("V"), commandline_1.longName("app-version"), commandline_1.hasArg ], ShowCommand.prototype, "appVersion", void 0); __decorate([ commandline_1.help("Introduce the number of events that are being displayed. By default, all the events will be shown"), commandline_1.shortName("c"), commandline_1.longName("number-of-events"), commandline_1.hasArg, commandline_1.defaultValue("200") ], ShowCommand.prototype, "eventCount", void 0); __decorate([ commandline_1.help("Filter the metrics to a specific event name"), commandline_1.shortName("n"), commandline_1.longName("event-name"), commandline_1.hasArg ], ShowCommand.prototype, "eventName", void 0); __decorate([ commandline_1.longName("output"), commandline_1.help("Format of output for this command: json, csv"), commandline_1.hasArg ], ShowCommand.prototype, "format", void 0); ShowCommand = ShowCommand_1 = __decorate([ commandline_1.help("Show statistics for events") ], ShowCommand); exports.default = ShowCommand;