nw-builder 4.9.0 → 4.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2021-2023 NW.js Utilities
3
+ Copyright (c) 2021-2024 NW.js Utilities
4
4
  Copyright (c) 2014-2021 Steffen Müller
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy of
package/README.md CHANGED
@@ -286,6 +286,7 @@ This object defines additional properties used for building for a specific platf
286
286
  | CFBundleVersion | `string` | The version of the build that identifies an iteration of the bundle. |
287
287
  | CFBundleShortVersionString | `string` | The release or version number of the bundle. |
288
288
  | NSHumanReadableCopyright | `string` | A human-readable copyright notice for the bundle. |
289
+ | NSLocalNetworkUsageDescription | `string` | A human-readable description of why the application needs access to the local network. |
289
290
 
290
291
 
291
292
  ## Guides
@@ -375,7 +376,6 @@ nwbuild({
375
376
  ### Features
376
377
 
377
378
  - feat(get): support canary releases
378
- - feat(bld): rename MacOS Helper apps
379
379
  - feat(pkg): add `AppImage` installer
380
380
  - feat(pkg): add `NSIS` installer
381
381
  - feat(pkg): add `DMG` installer
@@ -389,7 +389,6 @@ nwbuild({
389
389
  - chore: annotate file paths as `fs.PathLike` instead of `string`.
390
390
  - chore(bld): factor out core build step
391
391
  - chore(bld): factor out linux config
392
- - chore(bld): factor out macos config
393
392
  - chore(bld): factor out windows config
394
393
  - chore(bld): factor out native addon
395
394
  - chore(bld): factor out compressing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nw-builder",
3
- "version": "4.9.0",
3
+ "version": "4.11.0",
4
4
  "description": "Build NW.js desktop applications for MacOS, Windows and Linux.",
5
5
  "keywords": [
6
6
  "NW.js",
@@ -9,7 +9,7 @@
9
9
  "Application"
10
10
  ],
11
11
  "author": {
12
- "name": "Steffen Müller",
12
+ "name": "Steffen Muller",
13
13
  "url": "https://www.mllrsohn.com/"
14
14
  },
15
15
  "maintainers": [
@@ -42,39 +42,35 @@
42
42
  },
43
43
  "scripts": {
44
44
  "postinstall": "node ./src/postinstall.js",
45
- "lint": "eslint ./src/**/*.js ./test/**/*.js",
46
- "lint:fix": "eslint --fix ./src/**/*.js ./test/**/*.js",
47
- "markdown:fix": "markdownlint --fix ./README.md",
48
- "docs": "jsdoc -d docs ./README.md ./src/index.js ./src/get.js ./src/run.js ./src/bld.js",
45
+ "lint": "eslint ./src ./tests",
46
+ "lint:fix": "eslint --fix ./src ./tests",
49
47
  "test": "vitest run --coverage",
50
48
  "test:cov": "vitest --coverage.enabled true",
51
- "demo": "cd test/fixture && node demo.js",
52
- "license-check": "jsgl --local ."
49
+ "demo:bld": "node ./tests/fixtures/demo.js",
50
+ "demo:exe": "./tests/fixtures/out/nwapp.app/Contents/MacOS/nwapp",
51
+ "demo:cli": "nwbuild --mode run ./src ./app/**"
53
52
  },
54
53
  "devDependencies": {
55
- "@stylistic/eslint-plugin-js": "^2.6.2",
56
- "@vitest/coverage-v8": "^2.0.5",
54
+ "@eslint/js": "^9.10.0",
55
+ "@vitest/coverage-v8": "^2.1.1",
57
56
  "base-volta-off-of-nwjs": "^1.0.5",
58
- "eslint": "^9.9.0",
59
- "eslint-config-tjw-jsdoc": "^1.0.5",
60
- "eslint-plugin-jsdoc": "^50.2.2",
61
- "eslint-plugin-markdown": "^5.0.0",
62
- "js-green-licenses": "^4.0.0",
63
- "jsdoc": "^4.0.3",
64
- "nw": "^0.90.0",
65
- "selenium-webdriver": "^4.23.0",
57
+ "eslint": "^9.10.0",
58
+ "eslint-plugin-jsdoc": "^50.2.4",
59
+ "globals": "^15.9.0",
60
+ "nw": "^0.91.0",
61
+ "selenium-webdriver": "^4.24.1",
66
62
  "vitest": "^2.0.4"
67
63
  },
68
64
  "dependencies": {
69
65
  "archiver": "^7.0.1",
70
- "axios": "^1.7.4",
66
+ "axios": "^1.7.7",
67
+ "commander": "^12.1.0",
71
68
  "glob": "^11.0.0",
72
69
  "node-gyp": "^10.2.0",
73
70
  "plist": "^3.1.0",
74
71
  "resedit": "^2.0.2",
75
72
  "semver": "^7.6.3",
76
73
  "tar": "^7.4.3",
77
- "yargs": "^17.7.2",
78
74
  "yauzl-promise": "^4.0.0"
79
75
  },
80
76
  "volta": {
package/src/bld/osx.js ADDED
@@ -0,0 +1,190 @@
1
+ import console from 'node:console';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import process from 'node:process';
5
+
6
+ import plist from 'plist';
7
+
8
+ /**
9
+ * Function to update Helper App Plist Files
10
+ * @param {string} plistPath - Path to Helper App Plist File
11
+ * @param {string} helperName - Helper App Name
12
+ * @param {string} helperId - Helper App ID
13
+ * @param {string} appCFBundleIdentifier - options.app.CFBundleIdentifier
14
+ */
15
+ async function updateHelperPlist (plistPath, helperName, helperId, appCFBundleIdentifier) {
16
+ const plistFullPath = path.resolve(plistPath, 'Contents/Info.plist');
17
+ const plistJson = plist.parse(await fs.promises.readFile(plistFullPath, 'utf-8'));
18
+ plistJson.CFBundleDisplayName = helperName;
19
+ plistJson.CFBundleName = helperName;
20
+ plistJson.CFBundleExecutable = helperName;
21
+ plistJson.CFBundleIdentifier = `${appCFBundleIdentifier}.${helperId}`;
22
+ await fs.promises.writeFile(plistFullPath, plist.build(plistJson));
23
+ }
24
+
25
+ /**
26
+ *
27
+ * @param {object} options - Options.
28
+ * @param {object} options.app - Application configuration.
29
+ * @param {string} options.outDir - Output directory.
30
+ * @param {string} options.releaseInfo - Release information.
31
+ * @returns {Promise<void>} - Promise.
32
+ */
33
+ export default async function setOsxConfig({ app, outDir, releaseInfo }) {
34
+ if (process.platform === 'win32') {
35
+ console.warn(
36
+ 'MacOS apps built on Windows platform do not preserve all file permissions. See #716',
37
+ );
38
+ }
39
+
40
+ try {
41
+ /**
42
+ * @type {string | null}
43
+ */
44
+ const chromiumVersion = releaseInfo?.components?.chromium;
45
+ if (!chromiumVersion) {
46
+ throw new Error('Chromium version is missing.');
47
+ }
48
+ /**
49
+ * Path to MacOS application.
50
+ * @type {string}
51
+ */
52
+ const nwjsApp = path.resolve(outDir, 'nwjs.app');
53
+
54
+ /**
55
+ * Path to renamed MacOS application.
56
+ * @type {string}
57
+ */
58
+ const outApp = path.resolve(outDir, `${app.name}.app`);
59
+
60
+ /* Rename `nwjs.app` to `${app.name}.app` */
61
+ await fs.promises.rename(nwjsApp, outApp);
62
+
63
+ /* Rename `Contents/MacOS/nwjs` to `Contents/MacOS/${app.name}` */
64
+ await fs.promises.rename(
65
+ path.resolve(outApp, 'Contents', 'MacOS', 'nwjs'),
66
+ path.resolve(outApp, 'Contents', 'MacOS', app.name),
67
+ );
68
+
69
+ /* Rename all Helper apps */
70
+ const helperBaseDir = path.resolve(
71
+ outApp,
72
+ 'Contents/Frameworks/nwjs Framework.framework/Versions',
73
+ chromiumVersion,
74
+ 'Helpers/'
75
+ );
76
+
77
+ const helperApps = [
78
+ { name: 'nwjs Helper (Alerts).app', id: 'helper.alert' },
79
+ { name: 'nwjs Helper (GPU).app', id: 'helper.gpu' },
80
+ { name: 'nwjs Helper (Plugin).app', id: 'helper.plugin' },
81
+ { name: 'nwjs Helper (Renderer).app', id: 'helper.renderer' },
82
+ { name: 'nwjs Helper.app', id: 'helper' },
83
+ ];
84
+
85
+ for (const helperApp of helperApps) {
86
+ const newHelperAppName = helperApp.name.replace(/^nwjs/, app.name);
87
+ const oldPath = path.resolve(helperBaseDir, helperApp.name);
88
+ const newPath = path.resolve(helperBaseDir, newHelperAppName);
89
+
90
+ // Rename Helper base directory
91
+ await fs.promises.rename(oldPath, newPath);
92
+
93
+ // Rename Helper sub-directory
94
+ const helperBaseName = helperApp.name.replace(/.app$/, '');
95
+ const subPathBase = path.resolve(newPath, 'Contents/MacOS/');
96
+ const oldSubPath = path.resolve(subPathBase, helperBaseName);
97
+ const newSubPath = path.resolve(subPathBase, helperBaseName.replace(/^nwjs/, app.name));
98
+ await fs.promises.rename(oldSubPath, newSubPath);
99
+
100
+ // Update Helper Plist file
101
+ await updateHelperPlist(newPath, newHelperAppName.replace(/.app$/, ''), helperApp.id, app.CFBundleIdentifier);
102
+ }
103
+
104
+ /* Replace default icon with user defined icon if specified. */
105
+ if (app.icon !== undefined) {
106
+ await fs.promises.copyFile(
107
+ path.resolve(app.icon),
108
+ path.resolve(outApp, 'Contents', 'Resources', 'app.icns'),
109
+ );
110
+ }
111
+
112
+ /**
113
+ * Path to `nwjs.app/Contents/Info.plist`
114
+ * @type {string}
115
+ */
116
+ const contentsInfoPlistPath = path.resolve(
117
+ outApp,
118
+ 'Contents',
119
+ 'Info.plist'
120
+ );
121
+
122
+ /**
123
+ * Path to `nwjs.app/Contents/Resources/en.lproj/InfoPlist.settings`
124
+ * @type {string}
125
+ */
126
+ const contentsResourcesEnLprojInfoPlistStringsPath = path.resolve(
127
+ outApp,
128
+ 'Contents',
129
+ 'Resources',
130
+ 'en.lproj',
131
+ 'InfoPlist.strings',
132
+ );
133
+
134
+ /**
135
+ * JSON from `nwjs.app/Contents/Info.plist`
136
+ * @type {object}
137
+ */
138
+ const contentsInfoPlistJson = plist.parse(
139
+ await fs.promises.readFile(
140
+ contentsInfoPlistPath,
141
+ 'utf-8'
142
+ )
143
+ );
144
+
145
+ /* Update Plist with user defined values. */
146
+ contentsInfoPlistJson.LSApplicationCategoryType = app.LSApplicationCategoryType;
147
+ contentsInfoPlistJson.CFBundleIdentifier = app.CFBundleIdentifier;
148
+ contentsInfoPlistJson.CFBundleName = app.CFBundleName;
149
+ contentsInfoPlistJson.CFBundleDisplayName = app.CFBundleDisplayName;
150
+ contentsInfoPlistJson.CFBundleSpokenName = app.CFBundleSpokenName;
151
+ contentsInfoPlistJson.CFBundleVersion = app.CFBundleVersion;
152
+ contentsInfoPlistJson.CFBundleShortVersionString = app.CFBundleShortVersionString;
153
+ contentsInfoPlistJson.CFBundleExecutable = app.name;
154
+ contentsInfoPlistJson.NSLocalNetworkUsageDescription = app.NSLocalNetworkUsageDescription;
155
+
156
+ /* Remove properties that were not updated by the user. */
157
+ Object.keys(contentsInfoPlistJson).forEach((option) => {
158
+ if (contentsInfoPlistJson[option] === undefined) {
159
+ delete contentsInfoPlistJson[option];
160
+ }
161
+ });
162
+
163
+ /**
164
+ * Data from `nwjs.app/Contents/Resources/en.lproj/InfoPlist.settings`
165
+ * @type {string[]}
166
+ */
167
+ const contentsResourcesEnLprojInfoPlistStringsArray = (await fs.promises.readFile(
168
+ contentsResourcesEnLprojInfoPlistStringsPath,
169
+ 'utf-8',
170
+ )).split('\n');
171
+ contentsResourcesEnLprojInfoPlistStringsArray.forEach((line, idx, arr) => {
172
+ if (line.includes('NSHumanReadableCopyright')) {
173
+ arr[idx] =
174
+ `NSHumanReadableCopyright = "${app.NSHumanReadableCopyright}";`;
175
+ }
176
+ });
177
+
178
+ /* Write the updated values to their config files. */
179
+ await fs.promises.writeFile(
180
+ contentsInfoPlistPath,
181
+ plist.build(contentsInfoPlistJson));
182
+ await fs.promises.writeFile(
183
+ contentsResourcesEnLprojInfoPlistStringsPath,
184
+ contentsResourcesEnLprojInfoPlistStringsArray.toString().replace(/,/g, '\n'),
185
+ );
186
+
187
+ } catch (error) {
188
+ console.error(error);
189
+ }
190
+ };
package/src/bld.js CHANGED
@@ -1,22 +1,21 @@
1
- import child_process from "node:child_process";
2
- import console from "node:console";
3
- import fs from "node:fs";
4
- import path from "node:path";
5
- import process from "node:process";
6
-
7
- import archiver from "archiver";
8
- import * as resedit from "resedit";
1
+ import child_process from 'node:child_process';
2
+ import console from 'node:console';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import process from 'node:process';
6
+
7
+ import archiver from 'archiver';
8
+ import * as resedit from 'resedit';
9
9
  // pe-library is a direct dependency of resedit
10
10
  import * as peLibrary from 'pe-library';
11
- import plist from "plist";
12
11
  import * as tar from 'tar';
13
12
 
14
- import util from "./util.js";
13
+ import util from './util.js';
14
+ import setOsxConfig from './bld/osx.js';
15
15
 
16
16
  /**
17
17
  * References:
18
18
  * https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
19
- *
20
19
  * @typedef {object} LinuxRc Linux configuration options
21
20
  * @property {string} name Name of the application
22
21
  * @property {string} genericName Generic name of the application
@@ -45,18 +44,18 @@ import util from "./util.js";
45
44
  /**
46
45
  * References:
47
46
  * https://developer.apple.com/documentation/bundleresources/information_property_list
48
- *
49
- * @typedef {object} OsxRc OSX resource configuration options
50
- * @property {string} name The name of the application
51
- * @property {string} icon The path to the icon file. It should be a .icns file.
52
- * @property {string} LSApplicationCategoryType The category that best describes your app for the App Store.
53
- * @property {string} CFBundleIdentifier A unique identifier for a bundle usually in reverse DNS format.
54
- * @property {string} CFBundleName A user-visible short name for the bundle.
55
- * @property {string} CFBundleDisplayName The user-visible name for the bundle.
56
- * @property {string} CFBundleSpokenName A replacement for the app name in text-to-speech operations.
57
- * @property {string} CFBundleVersion The version of the build that identifies an iteration of the bundle.
58
- * @property {string} CFBundleShortVersionString The release or version number of the bundle.
59
- * @property {string} NSHumanReadableCopyright A human-readable copyright notice for the bundle.
47
+ * @typedef {object} OsxRc OSX resource configuration options
48
+ * @property {string} name The name of the application
49
+ * @property {string} icon The path to the icon file. It should be a .icns file.
50
+ * @property {string} LSApplicationCategoryType The category that best describes your app for the App Store.
51
+ * @property {string} CFBundleIdentifier A unique identifier for a bundle usually in reverse DNS format.
52
+ * @property {string} CFBundleName A user-visible short name for the bundle.
53
+ * @property {string} CFBundleDisplayName The user-visible name for the bundle.
54
+ * @property {string} CFBundleSpokenName A replacement for the app name in text-to-speech operations.
55
+ * @property {string} CFBundleVersion The version of the build that identifies an iteration of the bundle.
56
+ * @property {string} CFBundleShortVersionString The release or version number of the bundle.
57
+ * @property {string} NSHumanReadableCopyright A human-readable copyright notice for the bundle.
58
+ * @property {string} NSLocalNetworkUsageDescription A human-readable description of why the application needs access to the local network.
60
59
  */
61
60
 
62
61
  /**
@@ -65,7 +64,6 @@ import util from "./util.js";
65
64
  * https://learn.microsoft.com/en-gb/windows/win32/sbscs/application-manifests
66
65
  * https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/deployment/trustinfo-element-clickonce-application?view=vs-2015#requestedexecutionlevel
67
66
  * https://learn.microsoft.com/en-gb/windows/win32/menurc/versioninfo-resource
68
- *
69
67
  * @typedef {object} WinRc Windows configuration options. More info
70
68
  * @property {string} name The name of the application
71
69
  * @property {string} version @deprecated Use {@link fileVersion} instead. The version of the application
@@ -100,34 +98,34 @@ import util from "./util.js";
100
98
  * @property {boolean | string | object} [managedManifest = false] Manage manifest
101
99
  * @property {false | "gyp"} [nativeAddon = false] Rebuild native modules
102
100
  * @property {false | "zip" | "tar" | "tgz"} [zip = false] Compress built artifacts
101
+ * @property {object} [releaseInfo = {}] Version specific release metadata.
103
102
  */
104
103
 
105
104
  /**
106
105
  * Build NW.js application.
107
- *
108
106
  * @async
109
107
  * @function
110
108
  * @param {BuildOptions} options - Build options
111
- * @return {Promise<void>}
109
+ * @returns {Promise<void>}
112
110
  */
113
111
  async function bld({
114
- version = "latest",
115
- flavor = "normal",
112
+ version = 'latest',
113
+ flavor = 'normal',
116
114
  platform = util.PLATFORM_KV[process.platform],
117
115
  arch = util.ARCH_KV[process.arch],
118
- manifestUrl = "https://nwjs.io/versions",
119
- srcDir = "./src",
120
- cacheDir = "./cache",
121
- outDir = "./out",
116
+ srcDir = './src',
117
+ cacheDir = './cache',
118
+ outDir = './out',
122
119
  app,
123
120
  glob = true,
124
121
  managedManifest = false,
125
122
  nativeAddon = false,
126
123
  zip = false,
124
+ releaseInfo = {},
127
125
  }) {
128
126
  const nwDir = path.resolve(
129
127
  cacheDir,
130
- `nwjs${flavor === "sdk" ? "-sdk" : ""}-v${version}-${platform
128
+ `nwjs${flavor === 'sdk' ? '-sdk' : ''}-v${version}-${platform
131
129
  }-${arch}`,
132
130
  );
133
131
 
@@ -143,9 +141,9 @@ async function bld({
143
141
  file,
144
142
  path.resolve(
145
143
  outDir,
146
- platform !== "osx"
147
- ? "package.nw"
148
- : "nwjs.app/Contents/Resources/app.nw",
144
+ platform !== 'osx'
145
+ ? 'package.nw'
146
+ : 'nwjs.app/Contents/Resources/app.nw',
149
147
  file,
150
148
  ),
151
149
  { recursive: true, verbatimSymlinks: true },
@@ -156,40 +154,33 @@ async function bld({
156
154
  files,
157
155
  path.resolve(
158
156
  outDir,
159
- platform !== "osx"
160
- ? "package.nw"
161
- : "nwjs.app/Contents/Resources/app.nw",
157
+ platform !== 'osx'
158
+ ? 'package.nw'
159
+ : 'nwjs.app/Contents/Resources/app.nw',
162
160
  ),
163
161
  { recursive: true, verbatimSymlinks: true },
164
162
  );
165
163
  }
166
164
 
167
- const releaseInfo = await util.getReleaseInfo(
168
- version,
169
- platform,
170
- arch,
171
- cacheDir,
172
- manifestUrl,
173
- );
174
165
  const nodeVersion = releaseInfo.components.node;
175
166
 
176
167
  if (
177
168
  managedManifest === true ||
178
- typeof managedManifest === "object" ||
179
- typeof managedManifest === "string"
169
+ typeof managedManifest === 'object' ||
170
+ typeof managedManifest === 'string'
180
171
  ) {
181
172
  await manageManifest({ nwPkg: manifest, managedManifest, outDir, platform });
182
173
  }
183
174
 
184
- if (platform === "linux") {
175
+ if (platform === 'linux') {
185
176
  await setLinuxConfig({ app, outDir });
186
- } else if (platform === "win") {
177
+ } else if (platform === 'win') {
187
178
  await setWinConfig({ app, outDir });
188
- } else if (platform === "osx") {
189
- await setOsxConfig({ platform, outDir, app });
179
+ } else if (platform === 'osx') {
180
+ await setOsxConfig({ app, outDir, releaseInfo });
190
181
  }
191
182
 
192
- if (nativeAddon === "gyp") {
183
+ if (nativeAddon === 'gyp') {
193
184
  buildNativeAddon({ cacheDir, version, platform, arch, outDir, nodeVersion });
194
185
  }
195
186
 
@@ -205,56 +196,56 @@ const manageManifest = async ({ nwPkg, managedManifest, outDir, platform }) => {
205
196
  manifest = nwPkg;
206
197
  }
207
198
 
208
- if (typeof managedManifest === "object") {
199
+ if (typeof managedManifest === 'object') {
209
200
  manifest = managedManifest;
210
201
  }
211
202
 
212
- if (typeof managedManifest === "string") {
203
+ if (typeof managedManifest === 'string') {
213
204
  manifest = JSON.parse(await fs.promises.readFile(managedManifest));
214
205
  }
215
206
 
216
207
  if (manifest.devDependencies) {
217
208
  manifest.devDependencies = undefined;
218
209
  }
219
- manifest.packageManager = manifest.packageManager ?? "npm@*";
210
+ manifest.packageManager = manifest.packageManager ?? 'npm@*';
220
211
 
221
212
  await fs.promises.writeFile(
222
213
  path.resolve(
223
214
  outDir,
224
- platform !== "osx"
225
- ? "package.nw"
226
- : "nwjs.app/Contents/Resources/app.nw",
227
- "package.json",
215
+ platform !== 'osx'
216
+ ? 'package.nw'
217
+ : 'nwjs.app/Contents/Resources/app.nw',
218
+ 'package.json',
228
219
  ),
229
220
  JSON.stringify(manifest, null, 2),
230
- "utf8",
221
+ 'utf8',
231
222
  );
232
223
 
233
224
  const cwd = path.resolve(
234
225
  outDir,
235
- platform !== "osx"
236
- ? "package.nw"
237
- : "nwjs.app/Contents/Resources/app.nw",
226
+ platform !== 'osx'
227
+ ? 'package.nw'
228
+ : 'nwjs.app/Contents/Resources/app.nw',
238
229
  );
239
230
 
240
- if (manifest.packageManager.startsWith("npm")) {
241
- child_process.execSync(`npm install`, { cwd });
242
- } else if (manifest.packageManager.startsWith("yarn")) {
243
- child_process.execSync(`yarn install`, { cwd });
244
- } else if (manifest.packageManager.startsWith("pnpm")) {
245
- child_process.execSync(`pnpm install`, { cwd });
231
+ if (manifest.packageManager.startsWith('npm')) {
232
+ child_process.execSync('npm install', { cwd });
233
+ } else if (manifest.packageManager.startsWith('yarn')) {
234
+ child_process.execSync('yarn install', { cwd });
235
+ } else if (manifest.packageManager.startsWith('pnpm')) {
236
+ child_process.execSync('pnpm install', { cwd });
246
237
  }
247
238
  };
248
239
 
249
240
  const setLinuxConfig = async ({ app, outDir }) => {
250
- if (process.platform === "win32") {
241
+ if (process.platform === 'win32') {
251
242
  console.warn(
252
- "Linux apps built on Windows platform do not preserve all file permissions. See #716",
243
+ 'Linux apps built on Windows platform do not preserve all file permissions. See #716',
253
244
  );
254
245
  }
255
246
  let desktopEntryFile = {
256
- Type: "Application",
257
- Version: "1.5",
247
+ Type: 'Application',
248
+ Version: '1.5',
258
249
  Name: app.name,
259
250
  GenericName: app.genericName,
260
251
  NoDisplay: app.noDisplay,
@@ -281,7 +272,7 @@ const setLinuxConfig = async ({ app, outDir }) => {
281
272
 
282
273
  await fs.promises.rename(`${outDir}/nw`, `${outDir}/${app.name}`);
283
274
 
284
- let fileContent = `[Desktop Entry]\n`;
275
+ let fileContent = '[Desktop Entry]\n';
285
276
  Object.keys(desktopEntryFile).forEach((key) => {
286
277
  if (desktopEntryFile[key] !== undefined) {
287
278
  fileContent += `${key}=${desktopEntryFile[key]}\n`;
@@ -314,7 +305,7 @@ const setWinConfig = async ({ app, outDir }) => {
314
305
  });
315
306
 
316
307
  const outDirAppExe = path.resolve(outDir, `${app.name}.exe`);
317
- await fs.promises.rename(path.resolve(outDir, "nw.exe"), outDirAppExe);
308
+ await fs.promises.rename(path.resolve(outDir, 'nw.exe'), outDirAppExe);
318
309
  const exe = peLibrary.NtExecutable.from(await fs.promises.readFile(outDirAppExe));
319
310
  const res = peLibrary.NtExecutableResource.from(exe);
320
311
  // English (United States)
@@ -351,78 +342,13 @@ const setWinConfig = async ({ app, outDir }) => {
351
342
  await fs.promises.writeFile(outDirAppExe, outBuffer);
352
343
  };
353
344
 
354
- const setOsxConfig = async ({ outDir, app }) => {
355
- if (process.platform === "win32") {
356
- console.warn(
357
- "MacOS apps built on Windows platform do not preserve all file permissions. See #716",
358
- );
359
- }
360
-
361
- try {
362
- const outApp = path.resolve(outDir, `${app.name}.app`);
363
- await fs.promises.rename(path.resolve(outDir, "nwjs.app"), outApp);
364
- if (app.icon !== undefined) {
365
- await fs.promises.copyFile(
366
- path.resolve(app.icon),
367
- path.resolve(outApp, "Contents", "Resources", "app.icns"),
368
- );
369
- }
370
-
371
- const infoPlistPath = path.resolve(outApp, "Contents", "Info.plist");
372
- const infoPlistJson = plist.parse(await fs.promises.readFile(infoPlistPath, "utf-8"));
373
-
374
- const infoPlistStringsPath = path.resolve(
375
- outApp,
376
- "Contents",
377
- "Resources",
378
- "en.lproj",
379
- "InfoPlist.strings",
380
- );
381
- const infoPlistStringsData = await fs.promises.readFile(
382
- infoPlistStringsPath,
383
- "utf-8",
384
- );
385
-
386
- let infoPlistStringsDataArray = infoPlistStringsData.split("\n");
387
-
388
- infoPlistStringsDataArray.forEach((line, idx, arr) => {
389
- if (line.includes("NSHumanReadableCopyright")) {
390
- arr[idx] =
391
- `NSHumanReadableCopyright = "${app.NSHumanReadableCopyright}";`;
392
- }
393
- });
394
-
395
- infoPlistJson.LSApplicationCategoryType = app.LSApplicationCategoryType;
396
- infoPlistJson.CFBundleIdentifier = app.CFBundleIdentifier;
397
- infoPlistJson.CFBundleName = app.CFBundleName;
398
- infoPlistJson.CFBundleDisplayName = app.CFBundleDisplayName;
399
- infoPlistJson.CFBundleSpokenName = app.CFBundleSpokenName;
400
- infoPlistJson.CFBundleVersion = app.CFBundleVersion;
401
- infoPlistJson.CFBundleShortVersionString = app.CFBundleShortVersionString;
402
-
403
- Object.keys(infoPlistJson).forEach((option) => {
404
- if (infoPlistJson[option] === undefined) {
405
- delete infoPlistJson[option];
406
- }
407
- });
408
-
409
- await fs.promises.writeFile(infoPlistPath, plist.build(infoPlistJson));
410
- await fs.promises.writeFile(
411
- infoPlistStringsPath,
412
- infoPlistStringsDataArray.toString().replace(/,/g, "\n"),
413
- );
414
- } catch (error) {
415
- console.error(error);
416
- }
417
- };
418
-
419
345
  const buildNativeAddon = ({ cacheDir, version, platform, arch, outDir, nodeVersion }) => {
420
346
  let nodePath = path.resolve(cacheDir, `node-v${version}-${platform}-${arch}`);
421
347
  const cwd = path.resolve(
422
348
  outDir,
423
- platform !== "osx"
424
- ? "package.nw"
425
- : "nwjs.app/Contents/Resources/app.nw",
349
+ platform !== 'osx'
350
+ ? 'package.nw'
351
+ : 'nwjs.app/Contents/Resources/app.nw',
426
352
  );
427
353
 
428
354
  child_process.execSync(`node-gyp rebuild --target=${nodeVersion} --nodedir=${nodePath}`, { cwd });
@@ -432,18 +358,18 @@ const compress = async ({
432
358
  zip,
433
359
  outDir,
434
360
  }) => {
435
- if (zip === true || zip === "zip") {
361
+ if (zip === true || zip === 'zip') {
436
362
  const archive = archiver('zip');
437
363
  const writeStream = fs.createWriteStream(`${outDir}.zip`);
438
364
  archive.pipe(writeStream);
439
365
  archive.directory(outDir, false);
440
366
  archive.finalize();
441
- } else if (zip === "tar") {
367
+ } else if (zip === 'tar') {
442
368
  await tar.create({
443
369
  gzip: false,
444
370
  file: `${outDir}.tar`,
445
371
  }, [outDir]);
446
- } else if (zip === "tgz") {
372
+ } else if (zip === 'tgz') {
447
373
  await tar.create({
448
374
  gzip: true,
449
375
  file: `${outDir}.tgz`,