nativescript
Version:
Command-line interface for building NativeScript projects
219 lines • 11.6 kB
JavaScript
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DebugController = void 0;
const decorators_1 = require("../common/decorators");
const os_1 = require("os");
const url_1 = require("url");
const _ = require("lodash");
const constants_1 = require("../common/constants");
const constants_2 = require("../constants");
const events_1 = require("events");
const yok_1 = require("../common/yok");
const color_1 = require("../color");
class DebugController extends events_1.EventEmitter {
constructor($analyticsService, $debugDataService, $devicesService, $errors, $injector, $liveSyncProcessDataService, $logger, $mobileHelper, $projectDataService) {
super();
this.$analyticsService = $analyticsService;
this.$debugDataService = $debugDataService;
this.$devicesService = $devicesService;
this.$errors = $errors;
this.$injector = $injector;
this.$liveSyncProcessDataService = $liveSyncProcessDataService;
this.$logger = $logger;
this.$mobileHelper = $mobileHelper;
this.$projectDataService = $projectDataService;
this._platformDebugServices = {};
}
async startDebug(debugData) {
const { debugOptions: options } = debugData;
const device = this.$devicesService.getDeviceByIdentifier(debugData.deviceIdentifier);
if (!device) {
this.$errors.fail(`Cannot find device with identifier ${debugData.deviceIdentifier}.`);
}
if (device.deviceInfo.status !== constants_1.CONNECTED_STATUS) {
this.$errors.fail(`The device with identifier ${debugData.deviceIdentifier} is unreachable. Make sure it is Trusted and try again.`);
}
await this.$analyticsService.trackEventActionInGoogleAnalytics({
action: "Debug" /* TrackActionNames.Debug */,
device,
additionalData: this.$mobileHelper.isiOSPlatform(device.deviceInfo.platform) &&
options &&
options.inspector
? "Inspector" /* DebugTools.Inspector */
: "Chrome" /* DebugTools.Chrome */,
projectDir: debugData.projectDir,
});
if (!(await device.applicationManager.isApplicationInstalled(debugData.applicationIdentifier))) {
this.$errors.fail(`The application ${debugData.applicationIdentifier} is not installed on device with identifier ${debugData.deviceIdentifier}.`);
}
const debugService = this.getDeviceDebugService(device);
if (!debugService) {
this.$errors.fail(`Unsupported device OS: ${device.deviceInfo.platform}. You can debug your applications only on iOS or Android.`);
}
const debugOptions = _.cloneDeep(options);
const debugResultInfo = await debugService.debug(debugData, debugOptions);
return this.getDebugInformation(debugResultInfo, device.deviceInfo.identifier);
}
enableDebugging(enableDebuggingData) {
const { deviceIdentifiers } = enableDebuggingData;
return _.map(deviceIdentifiers, (deviceIdentifier) => this.enableDebuggingCore(enableDebuggingData.projectDir, deviceIdentifier, enableDebuggingData.debugOptions));
}
async disableDebugging(disableDebuggingData) {
const { deviceIdentifiers, projectDir } = disableDebuggingData;
for (const deviceIdentifier of deviceIdentifiers) {
const liveSyncProcessInfo = this.$liveSyncProcessDataService.getPersistedData(projectDir);
if (liveSyncProcessInfo.currentSyncAction) {
await liveSyncProcessInfo.currentSyncAction;
}
const currentDeviceDescriptor = this.getDeviceDescriptor(projectDir, deviceIdentifier);
if (currentDeviceDescriptor) {
currentDeviceDescriptor.debuggingEnabled = false;
}
else {
this.$errors.fail(`Couldn't disable debugging for ${deviceIdentifier}`);
}
const currentDevice = this.$devicesService.getDeviceByIdentifier(currentDeviceDescriptor.identifier);
if (!currentDevice) {
this.$errors.fail(`Couldn't disable debugging for ${deviceIdentifier}. Could not find device.`);
}
await this.stopDebug(currentDevice.deviceInfo.identifier);
this.emit(constants_2.DEBUGGER_DETACHED_EVENT_NAME, { deviceIdentifier });
}
}
async attachDebugger(attachDebuggerData) {
// Default values
if (attachDebuggerData.debugOptions) {
attachDebuggerData.debugOptions.chrome =
attachDebuggerData.debugOptions.chrome === undefined
? true
: attachDebuggerData.debugOptions.chrome;
attachDebuggerData.debugOptions.start =
attachDebuggerData.debugOptions.start === undefined
? true
: attachDebuggerData.debugOptions.start;
}
else {
attachDebuggerData.debugOptions = {
chrome: true,
start: true,
};
}
const projectData = this.$projectDataService.getProjectData(attachDebuggerData.projectDir);
const debugData = this.$debugDataService.getDebugData(attachDebuggerData.deviceIdentifier, projectData, attachDebuggerData.debugOptions);
// const platformData = this.$platformsDataService.getPlatformData(settings.platform, projectData);
// Of the properties below only `buildForDevice` and `release` are currently used.
// Leaving the others with placeholder values so that they may not be forgotten in future implementations.
const debugInfo = await this.startDebug(debugData);
const result = this.printDebugInformation(debugInfo, attachDebuggerData.debugOptions.forceDebuggerAttachedEvent);
return result;
}
async enableDebuggingCoreWithoutWaitingCurrentAction(projectDir, deviceIdentifier, debugOptions) {
const deviceDescriptor = this.getDeviceDescriptor(projectDir, deviceIdentifier);
if (!deviceDescriptor) {
this.$errors.fail(`Couldn't enable debugging for ${deviceIdentifier}`);
}
deviceDescriptor.debuggingEnabled = true;
deviceDescriptor.debugOptions = debugOptions;
const currentDeviceInstance = this.$devicesService.getDeviceByIdentifier(deviceIdentifier);
const attachDebuggerData = {
deviceIdentifier,
isEmulator: currentDeviceInstance.isEmulator,
outputPath: deviceDescriptor.buildData.outputPath,
platform: currentDeviceInstance.deviceInfo.platform,
projectDir,
debugOptions,
};
let debugInformation;
try {
debugInformation = await this.attachDebugger(attachDebuggerData);
}
catch (err) {
this.$logger.trace("Couldn't attach debugger, will modify options and try again.", err);
attachDebuggerData.debugOptions.start = false;
try {
debugInformation = await this.attachDebugger(attachDebuggerData);
}
catch (innerErr) {
this.$logger.trace("Couldn't attach debugger with modified options.", innerErr);
throw err;
}
}
return debugInformation;
}
printDebugInformation(debugInformation, fireDebuggerAttachedEvent = true) {
if (!!debugInformation.url) {
if (fireDebuggerAttachedEvent) {
this.emit(constants_2.DEBUGGER_ATTACHED_EVENT_NAME, debugInformation);
}
this.$logger.info(color_1.color.green(`To start debugging, open the following URL in Chrome:${os_1.EOL}${debugInformation.url}${os_1.EOL}`));
}
return debugInformation;
}
async stopDebug(deviceIdentifier) {
const device = this.$devicesService.getDeviceByIdentifier(deviceIdentifier);
const debugService = this.getDeviceDebugService(device);
await debugService.debugStop();
}
getDeviceDescriptor(projectDir, deviceIdentifier) {
const deviceDescriptors = this.$liveSyncProcessDataService.getDeviceDescriptors(projectDir);
const currentDeviceDescriptor = _.find(deviceDescriptors, (d) => d.identifier === deviceIdentifier);
return currentDeviceDescriptor;
}
getDeviceDebugService(device) {
if (!this._platformDebugServices[device.deviceInfo.identifier]) {
const devicePlatform = device.deviceInfo.platform;
if (this.$mobileHelper.isiOSPlatform(devicePlatform)) {
this._platformDebugServices[device.deviceInfo.identifier] = this.$injector.resolve("iOSDeviceDebugService", { device });
}
else if (this.$mobileHelper.isAndroidPlatform(devicePlatform)) {
this._platformDebugServices[device.deviceInfo.identifier] = this.$injector.resolve("androidDeviceDebugService", { device });
}
else {
this.$errors.fail(constants_2.DebugCommandErrors.UNSUPPORTED_DEVICE_OS_FOR_DEBUGGING);
}
this.attachConnectionErrorHandlers(this._platformDebugServices[device.deviceInfo.identifier]);
}
return this._platformDebugServices[device.deviceInfo.identifier];
}
attachConnectionErrorHandlers(platformDebugService) {
let connectionErrorHandler = (e) => this.emit(constants_2.CONNECTION_ERROR_EVENT_NAME, e);
connectionErrorHandler = connectionErrorHandler.bind(this);
platformDebugService.on(constants_2.CONNECTION_ERROR_EVENT_NAME, connectionErrorHandler);
}
getDebugInformation(debugResultInfo, deviceIdentifier) {
const debugInfo = {
url: debugResultInfo.debugUrl,
port: 0,
deviceIdentifier,
};
if (debugResultInfo.debugUrl) {
const parseQueryString = true;
const wsQueryParam = ((0, url_1.parse)(debugResultInfo.debugUrl, parseQueryString).query.ws);
const hostPortSplit = wsQueryParam && wsQueryParam.split(":");
debugInfo.port = hostPortSplit && +hostPortSplit[1];
}
return debugInfo;
}
async enableDebuggingCore(projectDir, deviceIdentifier, debugOptions) {
const liveSyncProcessInfo = this.$liveSyncProcessDataService.getPersistedData(projectDir);
if (liveSyncProcessInfo && liveSyncProcessInfo.currentSyncAction) {
await liveSyncProcessInfo.currentSyncAction;
}
return this.enableDebuggingCoreWithoutWaitingCurrentAction(projectDir, deviceIdentifier, debugOptions);
}
}
exports.DebugController = DebugController;
__decorate([
(0, decorators_1.performanceLog)()
], DebugController.prototype, "startDebug", null);
__decorate([
(0, decorators_1.performanceLog)()
], DebugController.prototype, "enableDebuggingCoreWithoutWaitingCurrentAction", null);
yok_1.injector.register("debugController", DebugController);
//# sourceMappingURL=debug-controller.js.map
;