UNPKG

office-addin-debugging

Version:
385 lines 18 kB
"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.waitUntilPackagerIsRunning = exports.waitUntilDevServerIsRunning = exports.waitUntil = exports.startDebugging = exports.runPackager = exports.runNodeDebugger = exports.runDevServer = exports.parsePlatform = exports.parseDebuggingMethod = exports.isPackagerRunning = exports.isDevServerRunning = exports.Platform = exports.AppType = void 0; const adm_zip_1 = __importDefault(require("adm-zip")); const node_fetch_1 = __importDefault(require("node-fetch")); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const devCerts = __importStar(require("office-addin-dev-certs")); const devSettings = __importStar(require("office-addin-dev-settings")); const os_1 = __importDefault(require("os")); const office_addin_dev_settings_1 = require("office-addin-dev-settings"); const office_addin_manifest_1 = require("office-addin-manifest"); const nodeDebugger = __importStar(require("office-addin-node-debugger")); const debugInfo = __importStar(require("./debugInfo")); const port_1 = require("./port"); const process_1 = require("./process"); const defaults_1 = require("./defaults"); const office_addin_usage_data_1 = require("office-addin-usage-data"); /* global console process setTimeout */ var AppType; (function (AppType) { AppType["Desktop"] = "desktop"; AppType["Web"] = "web"; })(AppType = exports.AppType || (exports.AppType = {})); var Platform; (function (Platform) { Platform["Android"] = "android"; Platform["Desktop"] = "desktop"; Platform["iOS"] = "ios"; Platform["MacOS"] = "macos"; Platform["Win32"] = "win32"; Platform["Web"] = "web"; })(Platform = exports.Platform || (exports.Platform = {})); function defaultDebuggingMethod() { return office_addin_dev_settings_1.DebuggingMethod.Direct; } function delay(milliseconds) { return new Promise((resolve) => { setTimeout(resolve, milliseconds); }); } function isDevServerRunning(port) { return __awaiter(this, void 0, void 0, function* () { // isPortInUse(port) will return false when webpack-dev-server is running. // it should be fixed, but for now, use getProcessIdsForPort(port) const processIds = yield (0, port_1.getProcessIdsForPort)(port); const isRunning = processIds.length > 0; return isRunning; }); } exports.isDevServerRunning = isDevServerRunning; function isPackagerRunning(statusUrl) { return __awaiter(this, void 0, void 0, function* () { const statusRunningResponse = `packager-status:running`; try { const response = yield node_fetch_1.default.default(statusUrl); console.log(`packager: ${response.status} ${response.statusText}`); const text = yield response.text(); console.log(`packager: ${text}`); return statusRunningResponse === text; } catch (_a) { return false; } }); } exports.isPackagerRunning = isPackagerRunning; function parseDebuggingMethod(text) { switch (text) { case "direct": return office_addin_dev_settings_1.DebuggingMethod.Direct; case "proxy": return office_addin_dev_settings_1.DebuggingMethod.Proxy; default: return undefined; } } exports.parseDebuggingMethod = parseDebuggingMethod; function parsePlatform(text) { if (text === AppType.Desktop) { text = process.platform; } switch (text) { case "android": return Platform.Android; case "darwin": return Platform.MacOS; case "ios": return Platform.iOS; case "macos": return Platform.MacOS; case "web": return Platform.Web; case "win32": return Platform.Win32; default: throw new office_addin_usage_data_1.ExpectedError(`The current platform is not supported: ${text}`); } } exports.parsePlatform = parsePlatform; function runDevServer(commandLine, port) { return __awaiter(this, void 0, void 0, function* () { if (commandLine) { // if the dev server is running if (port !== undefined && (yield isDevServerRunning(port))) { console.log(`The dev server is already running on port ${port}.`); } else { // On non-Windows platforms, prompt for installing the dev certs before starting the dev server. // This is a workaround for the fact that the detached process does not show a window on Mac, // therefore the user cannot enter the password when prompted. if (process.platform !== "win32") { if (!devCerts.verifyCertificates()) { yield devCerts.ensureCertificatesAreInstalled(); } } // start the dev server console.log(`Starting the dev server... (${commandLine})`); const devServerProcess = (0, process_1.startDetachedProcess)(commandLine); yield debugInfo.saveDevServerProcessId(devServerProcess.pid); if (port !== undefined) { // wait until the dev server is running const isRunning = yield waitUntilDevServerIsRunning(port); if (isRunning) { console.log(`The dev server is running on port ${port}. Process id: ${devServerProcess.pid}`); } else { throw new Error(`The dev server is not running on port ${port}.`); } } } } }); } exports.runDevServer = runDevServer; function runNodeDebugger(host, port) { return __awaiter(this, void 0, void 0, function* () { nodeDebugger.run(host, port); console.log("The node debugger is running."); }); } exports.runNodeDebugger = runNodeDebugger; function runPackager(commandLine, host = "localhost", port = "8081") { return __awaiter(this, void 0, void 0, function* () { if (commandLine) { // eslint-disable-next-line @microsoft/sdl/no-insecure-url const packagerUrl = `http://${host}:${port}`; const statusUrl = `${packagerUrl}/status`; // if the packager is running if (yield isPackagerRunning(statusUrl)) { console.log(`The packager is already running. ${packagerUrl}`); } else { // start the packager console.log(`Starting the packager... (${commandLine})`); yield (0, process_1.startDetachedProcess)(commandLine); // wait until the packager is running if (yield waitUntilPackagerIsRunning(statusUrl)) { console.log(`The packager is running. ${packagerUrl}`); } else { throw new Error(`The packager is not running. ${packagerUrl}`); } } } }); } exports.runPackager = runPackager; /** * Start debugging * @param options startDebugging options. */ function startDebugging(manifestPath, options) { var _a, _b, _c; return __awaiter(this, void 0, void 0, function* () { const { appType, app, debuggingMethod, sourceBundleUrlComponents, devServerCommandLine, devServerPort, packagerCommandLine, packagerHost, packagerPort, enableDebugging, enableLiveReload, enableSideload, openDevTools, document, } = Object.assign(Object.assign({}, options), { // Defaults when variable is undefined. debuggingMethod: options.debuggingMethod || defaultDebuggingMethod(), enableDebugging: (_a = options.enableDebugging) !== null && _a !== void 0 ? _a : true, enableSideload: (_b = options.enableSideload) !== null && _b !== void 0 ? _b : true, enableLiveReload: (_c = options.enableLiveReload) !== null && _c !== void 0 ? _c : true }); try { if (appType === undefined) { throw new office_addin_usage_data_1.ExpectedError("Please specify the application type to debug."); } const isWindowsPlatform = process.platform === "win32"; const isDesktopAppType = appType === AppType.Desktop; const isProxyDebuggingMethod = debuggingMethod === office_addin_dev_settings_1.DebuggingMethod.Proxy; // live reload can only be enabled for the desktop app type // when using proxy debugging and the packager const canEnableLiveReload = isDesktopAppType && isProxyDebuggingMethod && !!packagerCommandLine; // only use live reload if enabled and it can be enabled const useLiveReload = enableLiveReload && canEnableLiveReload; console.log(enableDebugging ? "Debugging is being started..." : "Starting without debugging..."); console.log(`App type: ${appType}`); if (manifestPath.endsWith(".zip")) { manifestPath = yield extractManifest(manifestPath); } const manifestInfo = yield office_addin_manifest_1.OfficeAddinManifest.readManifestFile(manifestPath); if (!manifestInfo.id) { throw new office_addin_usage_data_1.ExpectedError("Manifest does not contain the id for the Office Add-in."); } // enable loopback for Edge if (isWindowsPlatform && parseInt(os_1.default.release(), 10) === 10) { const name = isDesktopAppType ? "EdgeWebView" : "EdgeWebBrowser"; try { yield devSettings.ensureLoopbackIsEnabled(name); } catch (err) { // if add loopback exemption failed, report the error then continue console.error(err); console.warn("Failed to add loopback exemption.\nWill try to sideload the Office Add-in without the loopback exemption, but it might not load correctly from localhost.\n"); defaults_1.usageDataObject.reportException("startDebugging()", err, { app: app, document: document, appType: appType, }); } } // enable debugging if (isDesktopAppType && isWindowsPlatform) { yield devSettings.enableDebugging(manifestInfo.id, enableDebugging, debuggingMethod, openDevTools); if (enableDebugging) { console.log(`Enabled debugging for add-in ${manifestInfo.id}.`); } } // enable runtimelogging if (isDesktopAppType && isWindowsPlatform) { const path = yield devSettings.getRuntimeLoggingPath(); if (path) { console.log(`Runtime logging is enabled. File: ${path}`); } else { console.log("Enabling runtime logging.."); yield devSettings.enableRuntimeLogging(path); const logPath = yield devSettings.getRuntimeLoggingPath(); console.log(`Runtime logging has been enabled. File: ${logPath}`); } } // enable live reload if (isDesktopAppType && isWindowsPlatform) { yield devSettings.enableLiveReload(manifestInfo.id, useLiveReload); if (useLiveReload) { console.log(`Enabled live-reload for add-in ${manifestInfo.id}.`); } } // set source bundle url if (isDesktopAppType && isWindowsPlatform) { if (sourceBundleUrlComponents) { yield devSettings.setSourceBundleUrl(manifestInfo.id, sourceBundleUrlComponents); } } // Run packager and dev server at the same time and wait for them to complete. let packagerPromise; let devServerPromise; if (packagerCommandLine && isProxyDebuggingMethod && isDesktopAppType) { packagerPromise = runPackager(packagerCommandLine, packagerHost, packagerPort); } if (devServerCommandLine) { devServerPromise = runDevServer(devServerCommandLine, devServerPort); } if (packagerPromise !== undefined) { try { yield packagerPromise; } catch (err) { console.log(`Unable to start the packager. ${err}`); } } if (devServerPromise !== undefined) { try { yield devServerPromise; } catch (err) { console.log(`Unable to start the dev server. ${err}`); } } if (enableDebugging && isProxyDebuggingMethod && isDesktopAppType) { try { yield runNodeDebugger(); } catch (err) { console.log(`Unable to start the node debugger. ${err}`); } } if (enableSideload) { try { console.log(`Sideloading the Office Add-in...`); yield (0, office_addin_dev_settings_1.sideloadAddIn)(manifestPath, app, true, appType, document); } catch (err) { throw new Error(`Unable to sideload the Office Add-in. \n${err}`); } } console.log(enableDebugging ? "Debugging started." : "Started."); defaults_1.usageDataObject.reportSuccess("startDebugging()", { app: app, document: document, appType: appType, }); } catch (err) { defaults_1.usageDataObject.reportException("startDebugging()", err, { app: app, document: document, appType: appType, }); throw err; } }); } exports.startDebugging = startDebugging; function waitUntil(callback, retryCount, retryDelay) { return __awaiter(this, void 0, void 0, function* () { let done = yield callback(); while (!done && retryCount) { --retryCount; yield delay(retryDelay); done = yield callback(); } return done; }); } exports.waitUntil = waitUntil; function waitUntilDevServerIsRunning(port, retryCount = 30, retryDelay = 1000) { return __awaiter(this, void 0, void 0, function* () { return waitUntil(() => __awaiter(this, void 0, void 0, function* () { return yield isDevServerRunning(port); }), retryCount, retryDelay); }); } exports.waitUntilDevServerIsRunning = waitUntilDevServerIsRunning; function waitUntilPackagerIsRunning(statusUrl, retryCount = 30, retryDelay = 1000) { return __awaiter(this, void 0, void 0, function* () { return waitUntil(() => __awaiter(this, void 0, void 0, function* () { return yield isPackagerRunning(statusUrl); }), retryCount, retryDelay); }); } exports.waitUntilPackagerIsRunning = waitUntilPackagerIsRunning; function extractManifest(zipPath) { return __awaiter(this, void 0, void 0, function* () { const targetPath = path_1.default.join(process.env.TEMP, "addinManifest"); const zip = new adm_zip_1.default(zipPath); // reading archives zip.extractAllTo(targetPath, true); // overwrite const manifestPath = path_1.default.join(targetPath, "manifest.json"); if (fs_1.default.existsSync(manifestPath)) { return manifestPath; } else { throw new Error(`The zip file '${zipPath}' does not contain a "manifest.json" file`); } }); } //# sourceMappingURL=start.js.map