nw-builder 4.7.8 → 4.8.1
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/README.md +29 -15
- package/package.json +20 -19
- package/src/bld.js +71 -55
- package/src/index.d.ts +22 -20
- package/src/index.js +2 -3
- package/src/postinstall.js +5 -0
- package/src/util.js +3 -2
package/README.md
CHANGED
|
@@ -29,19 +29,22 @@ For version 3, please go to the [corresponding branch](https://github.com/nwutil
|
|
|
29
29
|
|
|
30
30
|
## Install
|
|
31
31
|
|
|
32
|
-
Every NW.js release includes a modified Node.js binary at a specific version. It is recommended to [install](https://nodejs.org/en/download/package-manager) exactly that version on the host system. Not doing so may download ABI incompatible Node modules. Consult the NW.js [versions manifest](https://nwjs.io/versions) for what Node.js version to install. It is recommended to use a Node version manager (such as [volta](https://volta.sh), n, nvm, or nvm-windows) to be able to easily install and switch between Node versions.
|
|
33
|
-
|
|
34
|
-
For example, NW.js v0.83.0 comes with Node.js v21.1.0.
|
|
35
|
-
|
|
36
32
|
```shell
|
|
37
|
-
|
|
38
|
-
v21.1.0
|
|
33
|
+
npm i -D nw nw-builder base-volta-off-of-nwjs
|
|
39
34
|
```
|
|
40
35
|
|
|
36
|
+
Every NW.js release includes a modified Node.js binary at a specific version. It is recommended to [install](https://nodejs.org/en/download/package-manager) exactly that version on the host system. Not doing so may download ABI incompatible Node modules. Consult the NW.js [versions manifest](https://nwjs.io/versions) for what Node.js version to install. It is recommended to use a Node version manager (such as [volta](https://volta.sh), n, nvm, or nvm-windows) to be able to easily install and switch between Node versions.
|
|
37
|
+
|
|
41
38
|
## Usage
|
|
42
39
|
|
|
43
40
|
This package can be used via a command line interface, be imported as a JavaScript module, or configured via the Node manifest as a JSON object.
|
|
44
41
|
|
|
42
|
+
CLI interface:
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
nwbuild --mode=build --glob=false --flavor=sdk --cacheDir=./node_modules/nw
|
|
46
|
+
```
|
|
47
|
+
|
|
45
48
|
ESM import:
|
|
46
49
|
|
|
47
50
|
```javascript
|
|
@@ -59,6 +62,13 @@ import("nwbuild")
|
|
|
59
62
|
.catch((error) => {
|
|
60
63
|
console.error(error);
|
|
61
64
|
});
|
|
65
|
+
|
|
66
|
+
nwbuild({
|
|
67
|
+
mode: "build",
|
|
68
|
+
glob: false,
|
|
69
|
+
flavor: "sdk",
|
|
70
|
+
cacheDir: "./node_modules/nw",
|
|
71
|
+
});
|
|
62
72
|
```
|
|
63
73
|
|
|
64
74
|
Node manifest usage:
|
|
@@ -66,12 +76,15 @@ Node manifest usage:
|
|
|
66
76
|
```json
|
|
67
77
|
{
|
|
68
78
|
"nwbuild": {
|
|
69
|
-
|
|
79
|
+
"mode": "build",
|
|
80
|
+
"glob": false,
|
|
81
|
+
"flavor": "sdk",
|
|
82
|
+
"cacheDir": "./node_modules/nw",
|
|
70
83
|
}
|
|
71
84
|
}
|
|
72
85
|
```
|
|
73
86
|
|
|
74
|
-
> From here on we will show `nw-builder` functionality by using the JavaScript module. Please note that the same
|
|
87
|
+
> From here on we will show `nw-builder` functionality by using the JavaScript module. Please note that the same functionality applies when using a command line or Node manifest.
|
|
75
88
|
|
|
76
89
|
## Concepts
|
|
77
90
|
|
|
@@ -79,7 +92,7 @@ Node manifest usage:
|
|
|
79
92
|
|
|
80
93
|
### Get Mode
|
|
81
94
|
|
|
82
|
-
> Deprecation warning: From v4.6.4 onward, run mode is deprecated. This logic
|
|
95
|
+
> Deprecation warning: From v4.6.4 onward, run mode is deprecated. This logic has been ported over to `nwjs/npm-installer` repo and will be removed in the next major release.
|
|
83
96
|
|
|
84
97
|
By default you get the normal build of the latest NW.js release for your specific platform and arch. For more information, please refer to the API reference.
|
|
85
98
|
|
|
@@ -109,7 +122,7 @@ nwbuild({
|
|
|
109
122
|
|
|
110
123
|
### Run Mode
|
|
111
124
|
|
|
112
|
-
> Deprecation warning: From v4.6.0 onward, run mode is deprecated. This logic
|
|
125
|
+
> Deprecation warning: From v4.6.0 onward, run mode is deprecated. This logic has been ported over to `nwjs/npm-installer` repo and will be removed in the next major release.
|
|
113
126
|
|
|
114
127
|
```javascript
|
|
115
128
|
nwbuild({
|
|
@@ -177,7 +190,7 @@ nwbuild({
|
|
|
177
190
|
We recommend rebuilding Node addons for NW.js via `node-gyp` if you are using NW.js v0.83.0 or above.
|
|
178
191
|
|
|
179
192
|
```shell
|
|
180
|
-
node-gyp rebuild --target=
|
|
193
|
+
node-gyp rebuild --target=22.2.0 --nodedir=/path/to/nw/node/headers
|
|
181
194
|
```
|
|
182
195
|
|
|
183
196
|
NW.js's Node version should match the Node version on the host machine due to [ABI differences in V8](https://github.com/nwjs/nw.js/issues/5025).
|
|
@@ -217,12 +230,12 @@ This object defines additional properties used for building for a specific platf
|
|
|
217
230
|
| ---- | ------- | --------- | ----------- |
|
|
218
231
|
| `icon` | `string` | `undefined` | The path to the icon file. It should be a .ico file. |
|
|
219
232
|
| `name` | `string` | Value of `name` in app's `package.json` | The name of the application |
|
|
220
|
-
| `version` | `string` | Value of `version` in app's `package.json` | The version of the application |
|
|
233
|
+
| `version` | `string` | Value of `version` in app's `package.json` | (deprecated, Use `fileVersion` instead) The version of the application |
|
|
221
234
|
| `comments` | `string` | `undefined` | Additional information that should be displayed for diagnostic purposes. |
|
|
222
|
-
| `company` | `string` | `
|
|
235
|
+
| `company` | `string` | Value of `author` in app's `package.json` | Company that produced the file—for example, Microsoft Corporation or Standard Microsystems Corporation, Inc. This string is required. |
|
|
223
236
|
| `fileDescription` | `string` | Value of `description` in app's `package.json` | File description to be presented to users. This string may be displayed in a list box when the user is choosing files to install. For example, Keyboard Driver for AT-Style Keyboards. This string is required. |
|
|
224
|
-
| `fileVersion` | `string` | Value of `version` in app's `package.json` | Version number of the file. For example, 3.10 or 5.00.RC2. This string is required. |
|
|
225
|
-
| `internalName` | `string` | `
|
|
237
|
+
| `fileVersion` | `string` | Value of `version` option or value of `version` in app's `package.json` | Version number of the file. For example, 3.10 or 5.00.RC2. This string is required. |
|
|
238
|
+
| `internalName` | `string` | Value of `name` in app's `package.json` |Internal name of the file, if one exists—for example, a module name if the file is a dynamic-link library. If the file has no internal name, this string should be the original filename, without extension. This string is required. |
|
|
226
239
|
| `legalCopyright` | `string` | NW.js' copyright info | Copyright notices that apply to the file. This should include the full text of all notices, legal symbols, copyright dates, and so on. This string is optional. |
|
|
227
240
|
| `legalTrademark` | `string` | `undefined` | Trademarks and registered trademarks that apply to the file. This should include the full text of all notices, legal symbols, trademark numbers, and so on. This string is optional. |
|
|
228
241
|
| `originalFilename` | `string` | Value of `name` option | Original name of the file, not including a path. This information enables an application to determine whether a file has been renamed by a user. The format of the name depends on the file system for which the file was created. This string is required. |
|
|
@@ -230,6 +243,7 @@ This object defines additional properties used for building for a specific platf
|
|
|
230
243
|
| `productName` | `string` | Matches the package name defined in app's `package.json` | Name of the product with which the file is distributed. This string is required. |
|
|
231
244
|
| `productVersion` | `string` | Value of `version` in app's `package.json` | Version of the product with which the file is distributed—for example, 3.10 or 5.00.RC2. |
|
|
232
245
|
| `specialBuild` | `string` | `undefined` | Text that specifies how this version of the file differs from the standard version—for example, Private build for TESTER1 solving mouse problems on M250 and M250E computers. |
|
|
246
|
+
| `languageCode` | `number` | `1033` | Language of the file, defined by Microsoft, see: https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a |
|
|
233
247
|
|
|
234
248
|
#### Linux-specific options (`LinuxRc`)
|
|
235
249
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nw-builder",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.1",
|
|
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
|
|
12
|
+
"name": "Steffen MÃÂüller",
|
|
13
13
|
"url": "https://www.mllrsohn.com/"
|
|
14
14
|
},
|
|
15
15
|
"maintainers": [
|
|
@@ -49,36 +49,37 @@
|
|
|
49
49
|
"test": "vitest run --coverage",
|
|
50
50
|
"test:cov": "vitest --coverage.enabled true",
|
|
51
51
|
"demo": "cd test/fixture && node demo.js",
|
|
52
|
-
"
|
|
52
|
+
"license-check": "jsgl --local ."
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@stylistic/eslint-plugin-js": "^2.
|
|
56
|
-
"@vitest/coverage-v8": "^
|
|
55
|
+
"@stylistic/eslint-plugin-js": "^2.6.1",
|
|
56
|
+
"@vitest/coverage-v8": "^2.0.5",
|
|
57
57
|
"base-volta-off-of-nwjs": "^1.0.5",
|
|
58
|
-
"eslint": "^9.
|
|
58
|
+
"eslint": "^9.8.0",
|
|
59
59
|
"eslint-config-tjw-jsdoc": "^1.0.5",
|
|
60
|
-
"eslint-plugin-jsdoc": "^48.
|
|
60
|
+
"eslint-plugin-jsdoc": "^48.11.0",
|
|
61
61
|
"eslint-plugin-markdown": "^5.0.0",
|
|
62
|
+
"js-green-licenses": "^4.0.0",
|
|
62
63
|
"jsdoc": "^4.0.3",
|
|
63
|
-
"nw": "^0.
|
|
64
|
-
"
|
|
65
|
-
"
|
|
64
|
+
"nw": "^0.90.0",
|
|
65
|
+
"patch-package": "^8.0.0",
|
|
66
|
+
"selenium-webdriver": "^4.23.0",
|
|
67
|
+
"vitest": "^2.0.4"
|
|
66
68
|
},
|
|
67
69
|
"dependencies": {
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"node-gyp": "^10.1.0",
|
|
70
|
+
"archiver": "^7.0.1",
|
|
71
|
+
"axios": "^1.7.3",
|
|
72
|
+
"glob": "^11.0.0",
|
|
73
|
+
"node-gyp": "^10.2.0",
|
|
73
74
|
"plist": "^3.1.0",
|
|
74
75
|
"resedit": "^2.0.2",
|
|
75
|
-
"semver": "^7.6.
|
|
76
|
-
"tar": "^7.4.
|
|
76
|
+
"semver": "^7.6.3",
|
|
77
|
+
"tar": "^7.4.3",
|
|
77
78
|
"yargs": "^17.7.2",
|
|
78
79
|
"yauzl-promise": "^4.0.0"
|
|
79
80
|
},
|
|
80
|
-
"packageManager": "npm@10.8.1",
|
|
81
81
|
"volta": {
|
|
82
|
-
"node": "22.2.0"
|
|
82
|
+
"node": "22.2.0",
|
|
83
|
+
"npm": "10.8.2"
|
|
83
84
|
}
|
|
84
85
|
}
|
package/src/bld.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import child_process from "node:child_process";
|
|
2
2
|
import console from "node:console";
|
|
3
|
+
import fs from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
|
-
import fsm from "node:fs/promises";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import archiver from "archiver";
|
|
8
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
11
|
import plist from "plist";
|
|
12
|
+
import * as tar from 'tar';
|
|
12
13
|
|
|
13
|
-
import util from "./util.js"
|
|
14
|
+
import util from "./util.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* References:
|
|
@@ -67,7 +68,7 @@ import util from "./util.js"
|
|
|
67
68
|
*
|
|
68
69
|
* @typedef {object} WinRc Windows configuration options. More info
|
|
69
70
|
* @property {string} name The name of the application
|
|
70
|
-
* @property {string} version The version of the application
|
|
71
|
+
* @property {string} version @deprecated Use {@link fileVersion} instead. The version of the application
|
|
71
72
|
* @property {string} comments Additional information that should be displayed for diagnostic purposes.
|
|
72
73
|
* @property {string} company Company that produced the file—for example, Microsoft Corporation or Standard Microsystems Corporation, Inc. This string is required.
|
|
73
74
|
* @property {string} fileDescription File description to be presented to users. This string may be displayed in a list box when the user is choosing files to install. For example, Keyboard Driver for AT-Style Keyboards. This string is required.
|
|
@@ -81,6 +82,7 @@ import util from "./util.js"
|
|
|
81
82
|
* @property {string} productName Name of the product with which the file is distributed. This string is required.
|
|
82
83
|
* @property {string} productVersion Version of the product with which the file is distributed—for example, 3.10 or 5.00.RC2. This string is required.
|
|
83
84
|
* @property {string} specialBuild Text that specifies how this version of the file differs from the standard version—for example, Private build for TESTER1 solving mouse problems on M250 and M250E computers. This string should be present only if VS_FF_SPECIALBUILD is specified in the fileflags parameter of the root block.
|
|
85
|
+
* @property {string} languageCode Language of the file, defined by Microsoft, see: https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a
|
|
84
86
|
*/
|
|
85
87
|
|
|
86
88
|
/**
|
|
@@ -129,15 +131,15 @@ async function bld({
|
|
|
129
131
|
}-${arch}`,
|
|
130
132
|
);
|
|
131
133
|
|
|
132
|
-
await
|
|
133
|
-
await
|
|
134
|
+
await fs.promises.rm(outDir, { force: true, recursive: true });
|
|
135
|
+
await fs.promises.cp(nwDir, outDir, { recursive: true, verbatimSymlinks: true });
|
|
134
136
|
|
|
135
137
|
const files = await util.globFiles({ srcDir, glob });
|
|
136
138
|
const manifest = await util.getNodeManifest({ srcDir, glob });
|
|
137
139
|
|
|
138
140
|
if (glob) {
|
|
139
141
|
for (let file of files) {
|
|
140
|
-
await
|
|
142
|
+
await fs.promises.cp(
|
|
141
143
|
file,
|
|
142
144
|
path.resolve(
|
|
143
145
|
outDir,
|
|
@@ -150,7 +152,7 @@ async function bld({
|
|
|
150
152
|
);
|
|
151
153
|
}
|
|
152
154
|
} else {
|
|
153
|
-
await
|
|
155
|
+
await fs.promises.cp(
|
|
154
156
|
files,
|
|
155
157
|
path.resolve(
|
|
156
158
|
outDir,
|
|
@@ -176,7 +178,7 @@ async function bld({
|
|
|
176
178
|
typeof managedManifest === "object" ||
|
|
177
179
|
typeof managedManifest === "string"
|
|
178
180
|
) {
|
|
179
|
-
await manageManifest({ manifest, managedManifest, outDir, platform });
|
|
181
|
+
await manageManifest({ nwPkg: manifest, managedManifest, outDir, platform });
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
if (platform === "linux") {
|
|
@@ -208,7 +210,7 @@ const manageManifest = async ({ nwPkg, managedManifest, outDir, platform }) => {
|
|
|
208
210
|
}
|
|
209
211
|
|
|
210
212
|
if (typeof managedManifest === "string") {
|
|
211
|
-
manifest = JSON.parse(await
|
|
213
|
+
manifest = JSON.parse(await fs.promises.readFile(managedManifest));
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
if (manifest.devDependencies) {
|
|
@@ -216,7 +218,7 @@ const manageManifest = async ({ nwPkg, managedManifest, outDir, platform }) => {
|
|
|
216
218
|
}
|
|
217
219
|
manifest.packageManager = manifest.packageManager ?? "npm@*";
|
|
218
220
|
|
|
219
|
-
await
|
|
221
|
+
await fs.promises.writeFile(
|
|
220
222
|
path.resolve(
|
|
221
223
|
outDir,
|
|
222
224
|
platform !== "osx"
|
|
@@ -228,21 +230,19 @@ const manageManifest = async ({ nwPkg, managedManifest, outDir, platform }) => {
|
|
|
228
230
|
"utf8",
|
|
229
231
|
);
|
|
230
232
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
: "nwjs.app/Contents/Resources/app.nw",
|
|
237
|
-
),
|
|
233
|
+
const cwd = path.resolve(
|
|
234
|
+
outDir,
|
|
235
|
+
platform !== "osx"
|
|
236
|
+
? "package.nw"
|
|
237
|
+
: "nwjs.app/Contents/Resources/app.nw",
|
|
238
238
|
);
|
|
239
239
|
|
|
240
240
|
if (manifest.packageManager.startsWith("npm")) {
|
|
241
|
-
child_process.execSync(`npm install
|
|
241
|
+
child_process.execSync(`npm install`, { cwd });
|
|
242
242
|
} else if (manifest.packageManager.startsWith("yarn")) {
|
|
243
|
-
child_process.execSync(`yarn install
|
|
243
|
+
child_process.execSync(`yarn install`, { cwd });
|
|
244
244
|
} else if (manifest.packageManager.startsWith("pnpm")) {
|
|
245
|
-
child_process.execSync(`pnpm install
|
|
245
|
+
child_process.execSync(`pnpm install`, { cwd });
|
|
246
246
|
}
|
|
247
247
|
};
|
|
248
248
|
|
|
@@ -279,7 +279,7 @@ const setLinuxConfig = async ({ app, outDir }) => {
|
|
|
279
279
|
SingleMainWindow: app.singleMainWindow,
|
|
280
280
|
};
|
|
281
281
|
|
|
282
|
-
await
|
|
282
|
+
await fs.promises.rename(`${outDir}/nw`, `${outDir}/${app.name}`);
|
|
283
283
|
|
|
284
284
|
let fileContent = `[Desktop Entry]\n`;
|
|
285
285
|
Object.keys(desktopEntryFile).forEach((key) => {
|
|
@@ -288,23 +288,23 @@ const setLinuxConfig = async ({ app, outDir }) => {
|
|
|
288
288
|
}
|
|
289
289
|
});
|
|
290
290
|
let filePath = `${outDir}/${app.name}.desktop`;
|
|
291
|
-
await
|
|
291
|
+
await fs.promises.writeFile(filePath, fileContent);
|
|
292
292
|
};
|
|
293
293
|
|
|
294
294
|
const setWinConfig = async ({ app, outDir }) => {
|
|
295
295
|
let versionString = {
|
|
296
296
|
Comments: app.comments,
|
|
297
|
-
CompanyName: app.
|
|
297
|
+
CompanyName: app.company,
|
|
298
298
|
FileDescription: app.fileDescription,
|
|
299
299
|
FileVersion: app.fileVersion,
|
|
300
|
-
InternalName: app.
|
|
300
|
+
InternalName: app.internalName,
|
|
301
301
|
LegalCopyright: app.legalCopyright,
|
|
302
302
|
LegalTrademarks: app.legalTrademark,
|
|
303
|
-
OriginalFilename: app.
|
|
304
|
-
PrivateBuild: app.
|
|
305
|
-
ProductName: app.
|
|
306
|
-
ProductVersion: app.
|
|
307
|
-
SpecialBuild: app.
|
|
303
|
+
OriginalFilename: app.originalFilename,
|
|
304
|
+
PrivateBuild: app.privateBuild,
|
|
305
|
+
ProductName: app.productName,
|
|
306
|
+
ProductVersion: app.productVersion,
|
|
307
|
+
SpecialBuild: app.specialBuild,
|
|
308
308
|
};
|
|
309
309
|
|
|
310
310
|
Object.keys(versionString).forEach((option) => {
|
|
@@ -314,13 +314,13 @@ const setWinConfig = async ({ app, outDir }) => {
|
|
|
314
314
|
});
|
|
315
315
|
|
|
316
316
|
const outDirAppExe = path.resolve(outDir, `${app.name}.exe`);
|
|
317
|
-
await
|
|
318
|
-
const exe = peLibrary.NtExecutable.from(await
|
|
317
|
+
await fs.promises.rename(path.resolve(outDir, "nw.exe"), outDirAppExe);
|
|
318
|
+
const exe = peLibrary.NtExecutable.from(await fs.promises.readFile(outDirAppExe));
|
|
319
319
|
const res = peLibrary.NtExecutableResource.from(exe);
|
|
320
320
|
// English (United States)
|
|
321
321
|
const EN_US = 1033;
|
|
322
322
|
if (app.icon) {
|
|
323
|
-
const iconBuffer = await
|
|
323
|
+
const iconBuffer = await fs.promises.readFile(path.resolve(app.icon));
|
|
324
324
|
const iconFile = resedit.Data.IconFile.from(iconBuffer);
|
|
325
325
|
resedit.Resource.IconGroupEntry.replaceIconsForResource(
|
|
326
326
|
res.entries,
|
|
@@ -331,16 +331,24 @@ const setWinConfig = async ({ app, outDir }) => {
|
|
|
331
331
|
);
|
|
332
332
|
}
|
|
333
333
|
const [vi] = resedit.Resource.VersionInfo.fromEntries(res.entries);
|
|
334
|
-
|
|
335
|
-
|
|
334
|
+
if (app.languageCode !== EN_US) {
|
|
335
|
+
res.removeResourceEntry(16, 1, EN_US);
|
|
336
|
+
vi.removeAllStringValues({
|
|
337
|
+
lang: EN_US,
|
|
338
|
+
codepage: 1200,
|
|
339
|
+
});
|
|
340
|
+
vi.lang=app.languageCode;
|
|
341
|
+
}
|
|
342
|
+
vi.setFileVersion(app.fileVersion, app.languageCode);
|
|
343
|
+
vi.setProductVersion(app.productVersion, app.languageCode);
|
|
336
344
|
vi.setStringValues({
|
|
337
|
-
lang:
|
|
345
|
+
lang: app.languageCode,
|
|
338
346
|
codepage: 1200
|
|
339
347
|
}, versionString);
|
|
340
348
|
vi.outputToResourceEntries(res.entries);
|
|
341
349
|
res.outputResource(exe);
|
|
342
350
|
const outBuffer = Buffer.from(exe.generate());
|
|
343
|
-
await
|
|
351
|
+
await fs.promises.writeFile(outDirAppExe, outBuffer);
|
|
344
352
|
};
|
|
345
353
|
|
|
346
354
|
const setOsxConfig = async ({ outDir, app }) => {
|
|
@@ -352,16 +360,16 @@ const setOsxConfig = async ({ outDir, app }) => {
|
|
|
352
360
|
|
|
353
361
|
try {
|
|
354
362
|
const outApp = path.resolve(outDir, `${app.name}.app`);
|
|
355
|
-
await
|
|
363
|
+
await fs.promises.rename(path.resolve(outDir, "nwjs.app"), outApp);
|
|
356
364
|
if (app.icon !== undefined) {
|
|
357
|
-
await
|
|
365
|
+
await fs.promises.copyFile(
|
|
358
366
|
path.resolve(app.icon),
|
|
359
367
|
path.resolve(outApp, "Contents", "Resources", "app.icns"),
|
|
360
368
|
);
|
|
361
369
|
}
|
|
362
370
|
|
|
363
371
|
const infoPlistPath = path.resolve(outApp, "Contents", "Info.plist");
|
|
364
|
-
const infoPlistJson = plist.parse(await
|
|
372
|
+
const infoPlistJson = plist.parse(await fs.promises.readFile(infoPlistPath, "utf-8"));
|
|
365
373
|
|
|
366
374
|
const infoPlistStringsPath = path.resolve(
|
|
367
375
|
outApp,
|
|
@@ -370,7 +378,7 @@ const setOsxConfig = async ({ outDir, app }) => {
|
|
|
370
378
|
"en.lproj",
|
|
371
379
|
"InfoPlist.strings",
|
|
372
380
|
);
|
|
373
|
-
const infoPlistStringsData = await
|
|
381
|
+
const infoPlistStringsData = await fs.promises.readFile(
|
|
374
382
|
infoPlistStringsPath,
|
|
375
383
|
"utf-8",
|
|
376
384
|
);
|
|
@@ -398,8 +406,8 @@ const setOsxConfig = async ({ outDir, app }) => {
|
|
|
398
406
|
}
|
|
399
407
|
});
|
|
400
408
|
|
|
401
|
-
await
|
|
402
|
-
await
|
|
409
|
+
await fs.promises.writeFile(infoPlistPath, plist.build(infoPlistJson));
|
|
410
|
+
await fs.promises.writeFile(
|
|
403
411
|
infoPlistStringsPath,
|
|
404
412
|
infoPlistStringsDataArray.toString().replace(/,/g, "\n"),
|
|
405
413
|
);
|
|
@@ -410,16 +418,14 @@ const setOsxConfig = async ({ outDir, app }) => {
|
|
|
410
418
|
|
|
411
419
|
const buildNativeAddon = ({ cacheDir, version, platform, arch, outDir, nodeVersion }) => {
|
|
412
420
|
let nodePath = path.resolve(cacheDir, `node-v${version}-${platform}-${arch}`);
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
: "nwjs.app/Contents/Resources/app.nw",
|
|
419
|
-
),
|
|
421
|
+
const cwd = path.resolve(
|
|
422
|
+
outDir,
|
|
423
|
+
platform !== "osx"
|
|
424
|
+
? "package.nw"
|
|
425
|
+
: "nwjs.app/Contents/Resources/app.nw",
|
|
420
426
|
);
|
|
421
427
|
|
|
422
|
-
child_process.execSync(`node-gyp rebuild --target=${nodeVersion} --nodedir=${nodePath}
|
|
428
|
+
child_process.execSync(`node-gyp rebuild --target=${nodeVersion} --nodedir=${nodePath}`, { cwd });
|
|
423
429
|
};
|
|
424
430
|
|
|
425
431
|
const compress = async ({
|
|
@@ -427,14 +433,24 @@ const compress = async ({
|
|
|
427
433
|
outDir,
|
|
428
434
|
}) => {
|
|
429
435
|
if (zip === true || zip === "zip") {
|
|
430
|
-
|
|
436
|
+
const archive = archiver('zip');
|
|
437
|
+
const writeStream = fs.createWriteStream(`${outDir}.zip`);
|
|
438
|
+
archive.pipe(writeStream);
|
|
439
|
+
archive.directory(outDir, false);
|
|
440
|
+
archive.finalize();
|
|
431
441
|
} else if (zip === "tar") {
|
|
432
|
-
await
|
|
442
|
+
await tar.create({
|
|
443
|
+
gzip: false,
|
|
444
|
+
file: `${outDir}.tar`,
|
|
445
|
+
}, [outDir]);
|
|
433
446
|
} else if (zip === "tgz") {
|
|
434
|
-
await
|
|
447
|
+
await tar.create({
|
|
448
|
+
gzip: true,
|
|
449
|
+
file: `${outDir}.tgz`,
|
|
450
|
+
}, [outDir]);
|
|
435
451
|
}
|
|
436
452
|
|
|
437
|
-
await
|
|
453
|
+
await fs.promises.rm(outDir, { recursive: true, force: true });
|
|
438
454
|
};
|
|
439
455
|
|
|
440
456
|
export default bld;
|
package/src/index.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export type AppOptions<P extends SupportedPlatform> =
|
|
|
49
49
|
: (WindowsAppOptions | OsxAppOptions | LinuxAppOptions);
|
|
50
50
|
|
|
51
51
|
/** Windows configuration options
|
|
52
|
-
*
|
|
52
|
+
*
|
|
53
53
|
* References:
|
|
54
54
|
* - https://learn.microsoft.com/en-us/windows/win32/msi/version
|
|
55
55
|
* - https://learn.microsoft.com/en-gb/windows/win32/sbscs/application-manifests
|
|
@@ -59,7 +59,7 @@ export type AppOptions<P extends SupportedPlatform> =
|
|
|
59
59
|
export interface WindowsAppOptions {
|
|
60
60
|
/** The name of the application */
|
|
61
61
|
name?: string,
|
|
62
|
-
/** The version of the application */
|
|
62
|
+
/** @deprecated Use {@link fileVersion} instead. The version of the application */
|
|
63
63
|
version?: string,
|
|
64
64
|
/** Additional information that should be displayed for diagnostic purposes. */
|
|
65
65
|
comments?: string,
|
|
@@ -87,28 +87,30 @@ export interface WindowsAppOptions {
|
|
|
87
87
|
productVersion: string,
|
|
88
88
|
/** Text that specifies how this version of the file differs from the standard version—for example, Private build for TESTER1 solving mouse problems on M250 and M250E computers. This string should be present only if VS_FF_SPECIALBUILD is specified in the fileflags parameter of the root block. */
|
|
89
89
|
specialBuild?: string,
|
|
90
|
+
/** Language of the file, defined by Microsoft, see: https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oe376/6c085406-a698-4e12-9d4d-c3b0ee3dbc4a */
|
|
91
|
+
languageCode?: number,
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
/** Linux configuration options
|
|
93
|
-
*
|
|
95
|
+
*
|
|
94
96
|
* References:
|
|
95
97
|
* https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
|
|
96
98
|
*/
|
|
97
99
|
export interface LinuxAppOptions {
|
|
98
100
|
/** Name of the application */
|
|
99
|
-
name?: string,
|
|
101
|
+
name?: string,
|
|
100
102
|
/** Generic name of the application */
|
|
101
|
-
genericName?: string,
|
|
103
|
+
genericName?: string,
|
|
102
104
|
/** If true the application is not displayed */
|
|
103
|
-
noDisplay?: boolean,
|
|
105
|
+
noDisplay?: boolean,
|
|
104
106
|
/** Tooltip for the entry, for example "View sites on the Internet". */
|
|
105
|
-
comment?: string,
|
|
107
|
+
comment?: string,
|
|
106
108
|
/** Icon to display in file manager, menus, etc. */
|
|
107
|
-
icon?: string,
|
|
109
|
+
icon?: string,
|
|
108
110
|
/** A list of strings identifying the desktop environments that should (/not) display a given desktop entry */
|
|
109
|
-
onlyShowIn?: string[],
|
|
111
|
+
onlyShowIn?: string[],
|
|
110
112
|
/** A list of strings identifying the desktop environments that should (/not) display a given desktop entry */
|
|
111
|
-
notShowIn?: string[],
|
|
113
|
+
notShowIn?: string[],
|
|
112
114
|
/** A boolean value specifying if D-Bus activation is supported for this application */
|
|
113
115
|
dBusActivatable?: boolean,
|
|
114
116
|
/** Path to an executable file on disk used to determine if the program is actually installed */
|
|
@@ -140,7 +142,7 @@ export interface LinuxAppOptions {
|
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
/** OSX resource configuration options
|
|
143
|
-
*
|
|
145
|
+
*
|
|
144
146
|
* References:
|
|
145
147
|
* https://developer.apple.com/documentation/bundleresources/information_property_list
|
|
146
148
|
*/
|
|
@@ -148,23 +150,23 @@ export interface OsxAppOptions {
|
|
|
148
150
|
/** The name of the application */
|
|
149
151
|
name?: string,
|
|
150
152
|
/** The path to the icon file. It should be a .icns file. */
|
|
151
|
-
icon?: string,
|
|
153
|
+
icon?: string,
|
|
152
154
|
/** The category that best describes your app for the App Store. */
|
|
153
|
-
LSApplicationCategoryType?: string,
|
|
155
|
+
LSApplicationCategoryType?: string,
|
|
154
156
|
/** A unique identifier for a bundle usually in reverse DNS format. */
|
|
155
|
-
CFBundleIdentifier?: string,
|
|
157
|
+
CFBundleIdentifier?: string,
|
|
156
158
|
/** A user-visible short name for the bundle. */
|
|
157
|
-
CFBundleName?: string,
|
|
159
|
+
CFBundleName?: string,
|
|
158
160
|
/** The user-visible name for the bundle. */
|
|
159
|
-
CFBundleDisplayName?: string,
|
|
161
|
+
CFBundleDisplayName?: string,
|
|
160
162
|
/** A replacement for the app name in text-to-speech operations. */
|
|
161
|
-
CFBundleSpokenName?: string,
|
|
163
|
+
CFBundleSpokenName?: string,
|
|
162
164
|
/** The version of the build that identifies an iteration of the bundle. */
|
|
163
|
-
CFBundleVersion?: string,
|
|
165
|
+
CFBundleVersion?: string,
|
|
164
166
|
/** The release or version number of the bundle. */
|
|
165
|
-
CFBundleShortVersionString?: string,
|
|
167
|
+
CFBundleShortVersionString?: string,
|
|
166
168
|
/** A human-readable copyright notice for the bundle. */
|
|
167
|
-
NSHumanReadableCopyright?: string,
|
|
169
|
+
NSHumanReadableCopyright?: string,
|
|
168
170
|
}
|
|
169
171
|
|
|
170
172
|
/**
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import console from "node:console";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import fsm from "node:fs/promises";
|
|
4
3
|
|
|
5
4
|
import bld from "./bld.js";
|
|
6
5
|
import get from "./get/index.js";
|
|
@@ -59,13 +58,13 @@ async function nwbuild(options) {
|
|
|
59
58
|
|
|
60
59
|
built = fs.existsSync(options.cacheDir);
|
|
61
60
|
if (built === false) {
|
|
62
|
-
await
|
|
61
|
+
await fs.promises.mkdir(options.cacheDir, { recursive: true });
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
if (options.mode === "build") {
|
|
66
65
|
built = fs.existsSync(options.outDir);
|
|
67
66
|
if (built === false) {
|
|
68
|
-
await
|
|
67
|
+
await fs.promises.mkdir(options.outDir, { recursive: true });
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
|
package/src/postinstall.js
CHANGED
|
@@ -6,8 +6,13 @@ import url from 'node:url';
|
|
|
6
6
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
7
7
|
|
|
8
8
|
const baseVoltaPath = path.resolve(path.join(__dirname, '..', 'node_modules', 'base-volta-off-of-nwjs', 'index.js'));
|
|
9
|
+
const patchPackagePath = path.resolve(path.join(__dirname, '..', 'node_modules', 'patch-package'));
|
|
9
10
|
|
|
10
11
|
/* Execute the script in development mode only since it is used during testing */
|
|
11
12
|
if (fs.existsSync(baseVoltaPath)) {
|
|
12
13
|
child_process.execSync('node ' + baseVoltaPath);
|
|
13
14
|
}
|
|
15
|
+
|
|
16
|
+
if (fs.existsSync(patchPackagePath)) {
|
|
17
|
+
child_process.execSync('node ' + patchPackagePath);
|
|
18
|
+
}
|
package/src/util.js
CHANGED
|
@@ -242,15 +242,16 @@ export const parse = async (options, pkg) => {
|
|
|
242
242
|
options.app.company = options.app.company ?? pkg.author;
|
|
243
243
|
options.app.fileDescription =
|
|
244
244
|
options.app.fileDescription ?? pkg.description;
|
|
245
|
-
options.app.fileVersion = options.app.fileVersion ?? pkg.version;
|
|
245
|
+
options.app.fileVersion = options.app.fileVersion ?? options.app.version ?? pkg.version;
|
|
246
246
|
options.app.internalName = options.app.internalName ?? pkg.name;
|
|
247
247
|
options.app.legalCopyright = options.app.legalCopyright ?? undefined;
|
|
248
248
|
options.app.legalTrademark = options.app.legalTrademark ?? undefined;
|
|
249
|
-
options.app.originalFilename = options.app.originalFilename ??
|
|
249
|
+
options.app.originalFilename = options.app.originalFilename ?? options.app.name;
|
|
250
250
|
options.app.privateBuild = options.app.privateBuild ?? undefined;
|
|
251
251
|
options.app.productName = options.app.productName ?? pkg.name;
|
|
252
252
|
options.app.productVersion = options.app.productVersion ?? pkg.version;
|
|
253
253
|
options.app.specialBuild = options.app.specialBuild ?? undefined;
|
|
254
|
+
options.app.languageCode = options.app.languageCode ?? 1033;
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
if (options.platform === "osx") {
|