Skip to content

Commit 2e54d5a

Browse files
authored
Merge pull request #312 from OfficeDev/user/jainsam/json-wxpo-new
Merging legacy Template branch json-wxpo-preview into master
2 parents adbacc6 + 9d09bbc commit 2e54d5a

26 files changed

+1106
-355
lines changed

.vscode/launch.json

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,6 @@
4949
"preLaunchTask": "Debug: Excel Desktop",
5050
"postDebugTask": "Stop Debug"
5151
},
52-
{
53-
"name": "Excel Desktop (Edge Legacy)",
54-
"type": "office-addin",
55-
"request": "attach",
56-
"url": "https://localhost:3000/taskpane.html?_host_Info=Excel$Win32$16.01$en-US$$$$0",
57-
"port": 9222,
58-
"timeout": 600000,
59-
"webRoot": "${workspaceRoot}",
60-
"preLaunchTask": "Debug: Excel Desktop",
61-
"postDebugTask": "Stop Debug"
62-
},
6352
{
6453
"name": "Outlook Desktop (Edge Chromium)",
6554
"type": "msedge",
@@ -70,17 +59,6 @@
7059
"preLaunchTask": "Debug: Outlook Desktop",
7160
"postDebugTask": "Stop Debug"
7261
},
73-
{
74-
"name": "Outlook Desktop (Edge Legacy)",
75-
"type": "office-addin",
76-
"request": "attach",
77-
"url": "https://localhost:3000/taskpane.html?_host_Info=Outlook$Win32$16.01$en-US$$$$0",
78-
"port": 9222,
79-
"timeout": 600000,
80-
"webRoot": "${workspaceRoot}",
81-
"preLaunchTask": "Debug: Outlook Desktop",
82-
"postDebugTask": "Stop Debug"
83-
},
8462
{
8563
"name": "PowerPoint Desktop (Edge Chromium)",
8664
"type": "msedge",
@@ -91,17 +69,6 @@
9169
"preLaunchTask": "Debug: PowerPoint Desktop",
9270
"postDebugTask": "Stop Debug"
9371
},
94-
{
95-
"name": "PowerPoint Desktop (Edge Legacy)",
96-
"type": "office-addin",
97-
"request": "attach",
98-
"url": "https://localhost:3000/taskpane.html?_host_Info=PowerPoint$Win32$16.01$en-US$$$$0",
99-
"port": 9222,
100-
"timeout": 600000,
101-
"webRoot": "${workspaceRoot}",
102-
"preLaunchTask": "Debug: PowerPoint Desktop",
103-
"postDebugTask": "Stop Debug"
104-
},
10572
{
10673
"name": "Word Desktop (Edge Chromium)",
10774
"type": "msedge",
@@ -111,17 +78,6 @@
11178
"webRoot": "${workspaceRoot}",
11279
"preLaunchTask": "Debug: Word Desktop",
11380
"postDebugTask": "Stop Debug"
114-
},
115-
{
116-
"name": "Word Desktop (Edge Legacy)",
117-
"type": "office-addin",
118-
"request": "attach",
119-
"url": "https://localhost:3000/taskpane.html?_host_Info=Word$Win32$16.01$en-US$$$$0",
120-
"port": 9222,
121-
"timeout": 600000,
122-
"webRoot": "${workspaceRoot}",
123-
"preLaunchTask": "Debug: Word Desktop",
124-
"postDebugTask": "Stop Debug"
12581
}
12682
]
12783
}

convertToSingleHost.js

Lines changed: 97 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const path = require("path");
55
const util = require("util");
66
const childProcess = require("child_process");
77
const hosts = ["excel", "onenote", "outlook", "powerpoint", "project", "word"];
8+
const commandsSupportedHosts = ["word", "excel", "powerpoint", "outlook", "wxpo"];
9+
810

911
if (process.argv.length <= 2) {
1012
const hostList = hosts.map((host) => `'${host}'`).join(", ");
@@ -19,7 +21,8 @@ if (process.argv.length <= 2) {
1921
}
2022

2123
const host = process.argv[2];
22-
const manifestType = process.argv[3];
24+
const targetHosts = host == "wxpo" ? ["excel", "word", "powerpoint", "outlook"] : [host];
25+
const manifestType = process.argv[3] || "xml";
2326
const projectName = process.argv[4];
2427
let appId = process.argv[5];
2528
const testPackages = [
@@ -36,32 +39,75 @@ const unlinkFileAsync = util.promisify(fs.unlink);
3639
const writeFileAsync = util.promisify(fs.writeFile);
3740

3841
async function modifyProjectForSingleHost(host) {
39-
if (!host) {
40-
throw new Error("The host was not provided.");
42+
if (!targetHosts || targetHosts.length === 0) {
43+
throw new Error("No target hosts were provided.");
44+
}
45+
46+
// Validate all target hosts
47+
for (const targetHost of targetHosts) {
48+
if (!hosts.includes(targetHost)) {
49+
throw new Error(`'${targetHost}' is not a supported host.`);
50+
}
4151
}
42-
if (!hosts.includes(host)) {
43-
throw new Error(`'${host}' is not a supported host.`);
52+
53+
// Check for unsupported combinations
54+
const unsupportedJSONHosts = targetHosts.filter(h => h === "onenote" || h === "project");
55+
if (manifestType === "json" && unsupportedJSONHosts.length > 0) {
56+
throw new Error(`'${unsupportedJSONHosts.join(", ")}' is not supported for ${manifestType} manifest.`);
57+
}
58+
if (manifestType === "xml" && targetHosts.length > 1) {
59+
throw new Error(`Multiple hosts are not supported for ${manifestType} manifest.`);
60+
}
61+
if (!commandsSupportedHosts.includes(host)) {
62+
throw new Error(`'${host}' does not support commands.`);
4463
}
45-
await convertProjectToSingleHost(host);
46-
await updatePackageJsonForSingleHost(host);
47-
await updateLaunchJsonFile(host);
48-
}
4964

50-
async function convertProjectToSingleHost(host) {
51-
// Copy host-specific manifest over manifest.xml
52-
const manifestContent = await readFileAsync(`./manifest.${host}.xml`, "utf8");
53-
await writeFileAsync(`./manifest.xml`, manifestContent);
65+
await convertProjectToSingleHost(host, manifestType);
5466

55-
// Copy over host-specific taskpane code to taskpane.ts
56-
const srcContent = await readFileAsync(`./src/taskpane/${host}.ts`, "utf8");
57-
await writeFileAsync(`./src/taskpane/taskpane.ts`, srcContent);
67+
await updatePackageJsonForSingleHost(host, manifestType);
68+
await updateLaunchJsonFile();
69+
}
5870

59-
// Delete all host-specific files
60-
hosts.forEach(async function (host) {
61-
await unlinkFileAsync(`./manifest.${host}.xml`);
62-
await unlinkFileAsync(`./src/taskpane/${host}.ts`);
63-
});
71+
async function convertProjectToSingleHost(host, manifestType) {
6472

73+
// Copy host-specific manifest over manifest file
74+
const manifestPath = `./manifest.${host}.${manifestType}`;
75+
if (fs.existsSync(manifestPath)) {
76+
let manifestContent = await readFileAsync(manifestPath, "utf8");
77+
await writeFileAsync(`./manifest.${manifestType}`, manifestContent);
78+
}
79+
80+
// Copy over host-specific taskpane code to taskpane.ts
81+
const taskpaneFilePath = "./src/taskpane/taskpane.ts";
82+
let taskpaneContent = await readFileAsync(taskpaneFilePath, "utf8");
83+
84+
// Copy over host-specific commands code to commands.ts
85+
const commandsFilePath = "./src/commands/commands.ts";
86+
let commandsContent = await readFileAsync(commandsFilePath, "utf8");
87+
88+
for (const hostName of hosts) {
89+
if (!targetHosts.includes(hostName)) {
90+
if (fs.existsSync(`./src/taskpane/${hostName}.ts`)) {
91+
await unlinkFileAsync(`./src/taskpane/${hostName}.ts`);
92+
}
93+
// remove unneeded imports from taskpane
94+
taskpaneContent = taskpaneContent.replace(`import "./${hostName}";`, "").replace(/^\s*[\r\n]/gm, "");
95+
96+
// remove unneeded commands files
97+
if (fs.existsSync(`./src/commands/commands.${hostName}.ts`)) {
98+
await unlinkFileAsync(`./src/commands/commands.${hostName}.ts`);
99+
}
100+
// remove unneeded imports from commands
101+
commandsContent = commandsContent.replace(`import "./commands.${hostName}";`, "").replace(/^\s*[\r\n]/gm, "");
102+
}
103+
// Remove unneeded manifest templates
104+
if (fs.existsSync(`./manifest.${hostName}.${manifestType}`)) {
105+
await unlinkFileAsync(`./manifest.${hostName}.${manifestType}`);
106+
}
107+
}
108+
109+
await writeFileAsync(taskpaneFilePath, taskpaneContent);
110+
await writeFileAsync(commandsFilePath, commandsContent);
65111
// Delete test folder
66112
deleteFolder(path.resolve(`./test`));
67113

@@ -75,73 +121,62 @@ async function convertProjectToSingleHost(host) {
75121
await deleteSupportFiles();
76122
}
77123

78-
async function updatePackageJsonForSingleHost(host) {
124+
async function updatePackageJsonForSingleHost(host, manifestType) {
79125
// Update package.json to reflect selected host
80126
const packageJson = `./package.json`;
81-
const data = await readFileAsync(packageJson, "utf8");
127+
let data = await readFileAsync(packageJson, "utf8");
128+
129+
if (manifestType === "json") {
130+
// Change manifest file name extension
131+
data = data.replace(/\.xml/g, ".json");
132+
}
133+
82134
let content = JSON.parse(data);
83135

84136
// Update 'config' section in package.json to use selected host
85-
content.config["app_to_debug"] = host;
137+
content.config["app_to_debug"] = targetHosts[0];
86138

87139
// Remove 'engines' section
88140
delete content.engines;
89141

90142
// Remove scripts that are unrelated to the selected host
91-
Object.keys(content.scripts).forEach(function (key) {
143+
for (const key of Object.keys(content.scripts)) {
92144
if (key === "convert-to-single-host") {
93145
delete content.scripts[key];
94146
}
95-
});
147+
}
96148

97149
// Remove test-related scripts
98-
Object.keys(content.scripts).forEach(function (key) {
150+
for (const key of Object.keys(content.scripts)) {
99151
if (key.includes("test")) {
100152
delete content.scripts[key];
101153
}
102-
});
154+
}
103155

104156
// Remove test-related packages
105-
Object.keys(content.devDependencies).forEach(function (key) {
157+
for (const key of Object.keys(content.devDependencies)) {
106158
if (testPackages.includes(key)) {
107159
delete content.devDependencies[key];
108160
}
109-
});
161+
}
110162

111163
// Write updated JSON to file
112164
await writeFileAsync(packageJson, JSON.stringify(content, null, 2));
113165
}
114166

115-
async function updateLaunchJsonFile(host) {
167+
async function updateLaunchJsonFile() {
116168
// Remove 'Debug Tests' configuration from launch.json
117169
const launchJson = `.vscode/launch.json`;
118170
const launchJsonContent = await readFileAsync(launchJson, "utf8");
119171
let content = JSON.parse(launchJsonContent);
120172
content.configurations = content.configurations.filter(function (config) {
121-
return config.name.startsWith(getHostName(host));
173+
return targetHosts.some((host) => {
174+
return config.name.toLowerCase().startsWith(host);
175+
});
122176
});
123177
await writeFileAsync(launchJson, JSON.stringify(content, null, 2));
124178
}
125179

126-
function getHostName(host) {
127-
switch (host) {
128-
case "excel":
129-
return "Excel";
130-
case "onenote":
131-
return "OneNote";
132-
case "outlook":
133-
return "Outlook";
134-
case "powerpoint":
135-
return "PowerPoint";
136-
case "project":
137-
return "Project";
138-
case "word":
139-
return "Word";
140-
default:
141-
throw new Error(`'${host}' is not a supported host.`);
142-
}
143-
}
144-
145180
function deleteFolder(folder) {
146181
try {
147182
if (fs.existsSync(folder)) {
@@ -173,72 +208,22 @@ async function deleteSupportFiles() {
173208

174209
async function deleteJSONManifestRelatedFiles() {
175210
await unlinkFileAsync("manifest.json");
211+
for (const host of hosts) {
212+
if (fs.existsSync(`./manifest.${host}.json`)) {
213+
await unlinkFileAsync(`manifest.${host}.json`);
214+
}
215+
}
176216
await unlinkFileAsync("assets/color.png");
177217
await unlinkFileAsync("assets/outline.png");
178218
}
179219

180220
async function deleteXMLManifestRelatedFiles() {
181221
await unlinkFileAsync("manifest.xml");
182-
}
183-
184-
async function updatePackageJsonForXMLManifest() {
185-
const packageJson = `./package.json`;
186-
const data = await readFileAsync(packageJson, "utf8");
187-
let content = JSON.parse(data);
188-
189-
// Write updated JSON to file
190-
await writeFileAsync(packageJson, JSON.stringify(content, null, 2));
191-
}
192-
193-
async function updatePackageJsonForJSONManifest() {
194-
const packageJson = `./package.json`;
195-
const data = await readFileAsync(packageJson, "utf8");
196-
let content = JSON.parse(data);
197-
198-
// Change manifest file name extension
199-
content.scripts.start = "office-addin-debugging start manifest.json";
200-
content.scripts.stop = "office-addin-debugging stop manifest.json";
201-
content.scripts.validate = "office-addin-manifest validate manifest.json";
202-
203-
// Write updated JSON to file
204-
await writeFileAsync(packageJson, JSON.stringify(content, null, 2));
205-
}
206-
207-
async function updateTasksJsonFileForJSONManifest() {
208-
const tasksJson = `.vscode/tasks.json`;
209-
const data = await readFileAsync(tasksJson, "utf8");
210-
let content = JSON.parse(data);
211-
212-
content.tasks.forEach(function (task) {
213-
if (task.label.startsWith("Build")) {
214-
task.dependsOn = ["Install"];
215-
}
216-
if (task.label === "Debug: Outlook Desktop") {
217-
task.script = "start";
218-
task.dependsOn = ["Check OS", "Install"];
222+
hosts.forEach(async function (host) {
223+
if (fs.existsSync(`./manifest.${host}.xml`)) {
224+
await unlinkFileAsync(`manifest.${host}.xml`);
219225
}
220226
});
221-
222-
const checkOSTask = {
223-
label: "Check OS",
224-
type: "shell",
225-
windows: {
226-
command: "echo 'Sideloading in Outlook on Windows is supported'",
227-
},
228-
linux: {
229-
command: "echo 'Sideloading on Linux is not supported' && exit 1",
230-
},
231-
osx: {
232-
command: "echo 'Sideloading in Outlook on Mac is not supported' && exit 1",
233-
},
234-
presentation: {
235-
clear: true,
236-
panel: "dedicated",
237-
},
238-
};
239-
240-
content.tasks.push(checkOSTask);
241-
await writeFileAsync(tasksJson, JSON.stringify(content, null, 2));
242227
}
243228

244229
async function updateWebpackConfigForJSONManifest() {
@@ -249,9 +234,7 @@ async function updateWebpackConfigForJSONManifest() {
249234
}
250235

251236
async function modifyProjectForJSONManifest() {
252-
await updatePackageJsonForJSONManifest();
253237
await updateWebpackConfigForJSONManifest();
254-
await updateTasksJsonFileForJSONManifest();
255238
await deleteXMLManifestRelatedFiles();
256239
}
257240

@@ -266,10 +249,9 @@ modifyProjectForSingleHost(host).catch((err) => {
266249

267250
let manifestPath = "manifest.xml";
268251

269-
if (host !== "outlook" || manifestType !== "json") {
252+
if (manifestType !== "json") {
270253
// Remove things that are only relevant to JSON manifest
271254
deleteJSONManifestRelatedFiles();
272-
updatePackageJsonForXMLManifest();
273255
} else {
274256
manifestPath = "manifest.json";
275257
modifyProjectForJSONManifest().catch((err) => {
@@ -289,8 +271,10 @@ if (projectName) {
289271
if (error) {
290272
console.error(`Error updating the manifest: ${error}`);
291273
process.exitCode = 1;
274+
Promise.reject(stdout);
292275
} else {
293276
console.log(stdout);
277+
Promise.resolve();
294278
}
295279
});
296280
}

0 commit comments

Comments
 (0)