Outlook_Addin_LLM/node_modules/office-addin-debugging/lib/start.js

344 lines
16 KiB
JavaScript

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
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());
});
};
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 AdmZip = require("adm-zip");
const fetch = require("node-fetch");
const fs = require("fs");
const fspath = require("path");
const devCerts = require("office-addin-dev-certs");
const devSettings = require("office-addin-dev-settings");
const os = require("os");
const office_addin_dev_settings_1 = require("office-addin-dev-settings");
const office_addin_manifest_1 = require("office-addin-manifest");
const nodeDebugger = require("office-addin-node-debugger");
const debugInfo = 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 process, console, 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 fetch.default(statusUrl);
console.log(`packager: ${response.status} ${response.statusText}`);
const text = yield response.text();
console.log(`packager: ${text}`);
return statusRunningResponse === text;
}
catch (err) {
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) {
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.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 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 = fspath.join(process.env.TEMP, "addinManifest");
const zip = new AdmZip(zipPath); // reading archives
zip.extractAllTo(targetPath, true); // overwrite
const manifestPath = fspath.join(targetPath, "manifest.json");
if (fs.existsSync(manifestPath)) {
return manifestPath;
}
else {
throw new Error(`The zip file '${zipPath}' does not contain a "manifest.json" file`);
}
});
}
//# sourceMappingURL=start.js.map