Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion packages/office-addin-dev-settings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Provides the ability to configure developer settings for Office Add-ins.
* [source-bundle-url](#source-bundle-url)
* [unregister](#unregister)
* [webview](#webview)
* [configure-disk-manifests](#configure-disk-manifests)

#

Expand Down Expand Up @@ -256,4 +257,27 @@ Disable overriding the source bundle of an add-in.

Enable overriding the source bundle of an add-in.

#
#

### disk-manifests
Configures loading manifests from disk.

> This switch currently supports the following clients: classic Windows Outlook.

Syntax:

`office-addin-dev-settings configure-disk-manifests [options]`

Without options, displays whether loading manifests from disk is enabled.

Options:

`--disable`

Disable loading manifests from disk.

`--enable`

Enable loading manifests from disk.

#
7 changes: 7 additions & 0 deletions packages/office-addin-dev-settings/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ commander
.description("Configures overriding of the source bundle.")
.action(commands.sourceBundleOverrideFile);

commander
.command("disk-manifests")
.option("--enable [path]", `Enable loading manifests from disk.`)
.option("--disable", "Disable loading manifests from disk.")
.description("Configures loading manifests from disk.")
.action(commands.diskManifests);

// if the command is not known, display an error
commander.on("command:*", function () {
logErrorMessage(`The command syntax is not valid.\n`);
Expand Down
38 changes: 37 additions & 1 deletion packages/office-addin-dev-settings/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,4 +545,40 @@ export async function isSourceBundleOverriden(addInId: string) {
usageDataObject.reportException("isSourceBundleOverriden", err);
logErrorMessage(err);
}
}
}

export async function diskManifests(options: OptionValues) {
try {
if (options.enable) {
const path: string | undefined =
typeof options.enable === "string" ? options.enable : undefined;
await enableDiskManifests(path);
} else if (options.disable) {
await disableDiskManifests();
} else {
await areDiskManifestsEnabled();
}
usageDataObject.reportSuccess("diskManifests");
} catch (err: any) {
usageDataObject.reportException("diskManifests", err);
logErrorMessage(err);
}
}

export async function enableDiskManifests(path?: string) {
const diskManifestsPath = await devSettings.enableDiskManifests(path);
console.log(`Disk manifests have been enabled. Path: ${diskManifestsPath}`);
usageDataObject.reportSuccess("enableDiskManifests");
}

export async function disableDiskManifests() {
await devSettings.disableDiskManifests();
console.log("Disk manifests have been disabled.");
usageDataObject.reportSuccess("disableDiskManifests");
}

export async function areDiskManifestsEnabled() {
const res = await devSettings.areDiskManifestsEnabled();
console.log(res);
usageDataObject.reportSuccess("areDiskManifestsEnabled");
}
50 changes: 49 additions & 1 deletion packages/office-addin-dev-settings/src/dev-settings-windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import fspath from "path";
/* global process */

const DeveloperSettingsRegistryKey: string = `HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Office\\16.0\\Wef\\Developer`;
const ProvidersRegistryKey: string = `HKEY_CURRENT_USER\\Software\\Microsoft\\Office\\16.0\\WEF\\Providers`;

const OpenDevTools: string = "OpenDevTools";
export const OutlookSideloadManifestPath: string = "OutlookSideloadManifestPath";
Expand All @@ -40,8 +41,12 @@ const UseLiveReload: string = "UseLiveReload";
const UseProxyDebugger: string = "UseWebDebugger";
const WebViewSelection: string = "WebViewSelection";
const JsBundle: string = "JsBundle";
const Outlook: string = "Outlook";
const EnableDebugging: string = "EnableDebugging";
const OutlookDiskProvider: string = "OutlookDiskProvider";

export async function clearDevSettings(addinId: string): Promise<void> {
await disableDiskManifests();
return deleteDeveloperSettingsRegistryKey(addinId);
}

Expand Down Expand Up @@ -97,6 +102,10 @@ export function getDeveloperSettingsRegistryKey(addinId: string): registry.Regis
return new registry.RegistryKey(`${DeveloperSettingsRegistryKey}\\${addinId}`);
}

export function getProvidersRegistryKey(): registry.RegistryKey {
return new registry.RegistryKey(`${ProvidersRegistryKey}`);
}

export async function getEnabledDebuggingMethods(addinId: string): Promise<DebuggingMethod[]> {
const key: registry.RegistryKey = getDeveloperSettingsRegistryKey(addinId);
const methods: DebuggingMethod[] = [];
Expand Down Expand Up @@ -376,4 +385,43 @@ export async function getSourceBundleOverrideFilePath(addInId: string): Promise<
const developerSettingsRegKey = getDeveloperSettingsRegistryKey(addInId);
const sourceBundleOverridePath = await registry.getStringValue(developerSettingsRegKey, JsBundle);
return sourceBundleOverridePath;
}
}

export async function enableDiskManifests(path: string) {
const providersRegKey = getProvidersRegistryKey();
await registry.addStringValue(providersRegKey, OutlookDiskProvider, path);

const outlookDeveloperRegKey = getDeveloperSettingsRegistryKey(Outlook);
await registry.addNumberValue(outlookDeveloperRegKey, EnableDebugging, 1);
}

export async function disableDiskManifests() {
const providersRegKey = getProvidersRegistryKey();
await registry.deleteValue(providersRegKey, OutlookDiskProvider);

const outlookDeveloperRegKey = getDeveloperSettingsRegistryKey(Outlook);
await registry.deleteKey(outlookDeveloperRegKey);
}

export async function areDiskManifestsEnabled(): Promise<string> {
const diskManifestsPath = await getDiskManifestsPath();
const enableDebugging = await getOutlookEnableDebugging();

if (diskManifestsPath && enableDebugging && enableDebugging > 0) {
return "Disk manifests are enabled. Path = " + diskManifestsPath;
}

return "Disk manifests are disabled";
}

export async function getDiskManifestsPath(): Promise<string | undefined> {
const providersRegKey = getProvidersRegistryKey();
const diskManifestsPath = await registry.getStringValue(providersRegKey, OutlookDiskProvider);
return diskManifestsPath;
}

export async function getOutlookEnableDebugging(): Promise<number | undefined> {
const outlookDeveloperRegKey = getDeveloperSettingsRegistryKey(Outlook);
const enableDebugging = await registry.getNumberValue(outlookDeveloperRegKey, EnableDebugging);
return enableDebugging;
}
55 changes: 54 additions & 1 deletion packages/office-addin-dev-settings/src/dev-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,57 @@ export async function isSourceBundleOverriden(addInId: string) : Promise<string>

export async function getSourceBundleOverrideFilePath(addInId: string): Promise<string | undefined> {
return devSettingsWindows.getSourceBundleOverrideFilePath(addInId);
}
}

export async function enableDiskManifests(path?: string) : Promise<string> {
switch (process.platform) {
case "win32": {
const isValidPath = isValidDiskManifestsPath(path);
if (path && isValidPath) {
await devSettingsWindows.enableDiskManifests(path);
return path;
}
throw new ExpectedError("The disk manifests path is not specified or is invalid. Ensure that it is an existing directory path.");
}
default:
throw new ExpectedError(`Platform not supported: ${process.platform}.`);
}
}

function isValidDiskManifestsPath(path?: string) {
let isValid: boolean = false;
try {
if (path) {
const pathExists: boolean = fs.existsSync(path);
if (pathExists) {
const stat = fs.statSync(path);
isValid = stat.isDirectory();
}
}
} catch (err: any) {
console.log(err);
}
return isValid;
}

export async function disableDiskManifests() : Promise<void> {
switch (process.platform) {
case "win32":
return devSettingsWindows.disableDiskManifests();
default:
throw new ExpectedError(`Platform not supported: ${process.platform}.`);
}
}

export async function areDiskManifestsEnabled() : Promise<string> {
switch (process.platform) {
case "win32":
return devSettingsWindows.areDiskManifestsEnabled();
default:
throw new ExpectedError(`Platform not supported: ${process.platform}.`);
}
}

export async function getDiskManifestsPath(): Promise<string | undefined> {
return devSettingsWindows.getDiskManifestsPath();
}
87 changes: 85 additions & 2 deletions packages/office-addin-dev-settings/test/unit-tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,6 @@ describe("Sideload to web", function () {

describe("Source bundle override file", function() {
if (isWindows) {
let sourceBundleOverridePathBeforeTests: string | undefined;
const baseDirPath = process.cwd();
const jsBundleFileName = "bundle.js";
const testBundleOverrideFilePath = fspath.normalize(`${baseDirPath}/${jsBundleFileName}`);
Expand Down Expand Up @@ -706,4 +705,88 @@ describe("Source bundle override file", function() {
});
});
}
});
});

describe("Disk Manifests", function() {
if (isWindows) {
let diskManifestsPathBeforeTests: string | undefined;
const diskManifestsDisableStr = "Disk manifests are disabled";
const testExecDirName = "testExec";
const baseDirPath = process.cwd();
const testExecDirPath = fspath.normalize(`${baseDirPath}/${testExecDirName}`);
const enableDiskManifestsError = "The disk manifests path is not specified or is invalid. Ensure that it is an existing directory path.";
const diskManifestsEnabledPrefix = "Disk manifests are enabled. Path = ";

this.beforeAll(async function() {
await fsextra.remove(testExecDirPath);
await fsextra.mkdir(testExecDirPath);
diskManifestsPathBeforeTests = await devSettings.getDiskManifestsPath();
await devSettings.disableDiskManifests();
});

this.afterAll(async function() {
await fsextra.remove(testExecDirPath);
if (diskManifestsPathBeforeTests) {
await devSettings.enableDiskManifests(diskManifestsPathBeforeTests);
} else {
await devSettings.disableDiskManifests();
}
});

describe("validate before enabling disk manifests", function() {
it("disk manifests should NOT be enabled", async function() {
assert.strictEqual(await devSettings.areDiskManifestsEnabled(), diskManifestsDisableStr);
});
});

describe("validate enabling disk manifests", function() {
it("enable disk manifests with NO path", async function() {
assert.strictEqual(await devSettings.areDiskManifestsEnabled(), diskManifestsDisableStr);

let error;
try {
await devSettings.enableDiskManifests(undefined);
} catch (err: any) {
error = err;
}
assert.ok(error instanceof Error, "error expected");
assert.strictEqual(error.message, enableDiskManifestsError);
});

it("enable disk manifests with INVALID path", async function() {
assert.strictEqual(await devSettings.areDiskManifestsEnabled(), diskManifestsDisableStr);

const diskManifestsPath = fspath.join(testExecDirPath, "doesNotExist");

let error;
try {
await devSettings.enableDiskManifests(diskManifestsPath);
} catch (err: any) {
error = err;
}
assert.ok(error instanceof Error, "error expected");
assert.strictEqual(error.message, enableDiskManifestsError);
});

it("enable disk manifests with VALID path", async function() {
assert.strictEqual(await devSettings.areDiskManifestsEnabled(), diskManifestsDisableStr);

try {
const path = await devSettings.enableDiskManifests(testExecDirPath);
assert.strictEqual(path, testExecDirPath);
} catch (err: any) {
console.log(err);
assert.fail("unexpected error");
}
});
});

describe("validate disabling disk manifest", async function() {
it("disable disk manifests", async function() {
assert.strictEqual(await devSettings.areDiskManifestsEnabled(), diskManifestsEnabledPrefix + testExecDirPath);
await devSettings.disableDiskManifests();
assert.strictEqual(await devSettings.areDiskManifestsEnabled(), diskManifestsDisableStr);
})
});
}
});