nw-builder 4.11.6 → 4.12.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/README.md +32 -23
- package/package.json +12 -8
- package/src/bld.js +7 -6
- package/src/get/request.js +11 -0
- package/src/index.d.ts +1 -1
- package/src/index.js +16 -6
- package/src/run.js +9 -3
- package/src/util.js +232 -26
package/README.md
CHANGED
|
@@ -84,7 +84,14 @@ Node manifest usage:
|
|
|
84
84
|
}
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
See `nw-builder` in action by building the demo application.
|
|
88
|
+
|
|
89
|
+
1. `git clone https://github.com/nwutils/nw-builder`
|
|
90
|
+
1. Run `npm run demo:bld:linux && npm run demo:exe:linux` to build and execute a Linux application.
|
|
91
|
+
1. Run `npm run demo:bld:osx && npm run demo:exe:osx` to build and execute a MacOS application.
|
|
92
|
+
1. Run `npm run demo:bld:win && npm run demo:exe:win` to build and execute a Windows application.
|
|
93
|
+
|
|
94
|
+
> 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 manifest file.
|
|
88
95
|
|
|
89
96
|
## Concepts
|
|
90
97
|
|
|
@@ -92,7 +99,7 @@ Node manifest usage:
|
|
|
92
99
|
|
|
93
100
|
### Get Mode
|
|
94
101
|
|
|
95
|
-
> Deprecation warning: From v4.6.4 onward,
|
|
102
|
+
> Deprecation warning: From v4.6.4 onward, get mode is deprecated. This logic has been ported over to `nwjs/npm-installer` repo and will be removed in the next major release.
|
|
96
103
|
|
|
97
104
|
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.
|
|
98
105
|
|
|
@@ -125,13 +132,15 @@ nwbuild({
|
|
|
125
132
|
> 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.
|
|
126
133
|
|
|
127
134
|
```javascript
|
|
128
|
-
nwbuild({
|
|
135
|
+
const nwProcess = await nwbuild({
|
|
129
136
|
mode: "run",
|
|
130
137
|
srcDir: "./app",
|
|
131
138
|
glob: false,
|
|
132
139
|
});
|
|
133
140
|
```
|
|
134
141
|
|
|
142
|
+
Note: The `nwProcess` is a [Node.js process](https://nodejs.org/api/process.html#process)
|
|
143
|
+
|
|
135
144
|
### Build Mode
|
|
136
145
|
|
|
137
146
|
Build with defaults:
|
|
@@ -142,7 +151,7 @@ nwbuild({
|
|
|
142
151
|
});
|
|
143
152
|
```
|
|
144
153
|
|
|
145
|
-
Managed Manifest
|
|
154
|
+
#### Managed Manifest
|
|
146
155
|
|
|
147
156
|
You can let `nw-builder` manage your node modules. The `managedManifest` options accepts a `boolean`, `string` or `object` type. It will then remove `devDependencies`, autodetect and download `dependencies` via the relevant `packageManager`. If none is specified, it uses `npm` as default.
|
|
148
157
|
|
|
@@ -176,7 +185,7 @@ nwbuild({
|
|
|
176
185
|
});
|
|
177
186
|
```
|
|
178
187
|
|
|
179
|
-
Rebuild Node addons
|
|
188
|
+
#### Rebuild Node addons
|
|
180
189
|
|
|
181
190
|
Currently this feature is quite limited. It only builds node addons which have a `binding.gyp` file in the `srcDir`. There are plans to support nan, cmake, ffi and gn and auto rebuild native addons which are installed as node modules.
|
|
182
191
|
|
|
@@ -201,7 +210,6 @@ Options
|
|
|
201
210
|
|
|
202
211
|
| Name | Type | Default | Description |
|
|
203
212
|
| ---- | ------- | --------- | ----------- |
|
|
204
|
-
| app | `LinuxRc \| WinRc \| OsxRc` | Additional options for each platform. (See below.)
|
|
205
213
|
| mode | `"get" \| "run" \| "build"` | `"build"` | Choose between get, run or build mode |
|
|
206
214
|
| version | `string \| "latest" \| "stable"` | `"latest"` | Runtime version |
|
|
207
215
|
| flavor | `"normal" \| "sdk"` | `"normal"` | Runtime flavor |
|
|
@@ -210,15 +218,17 @@ Options
|
|
|
210
218
|
| downloadUrl | `"https://dl.nwjs.io" \| "https://npm.taobao.org/mirrors/nwjs" \| https://npmmirror.com/mirrors/nwjs \| "https://github.com/corwin-of-amber/nw.js/releases/"` | `"https://dl.nwjs.io"` | Download server. Supports file systems too (for example `file:///home/localghost/nwjs_mirror`) |
|
|
211
219
|
| manifestUrl | `"https://nwjs.io/versions" \| "https://raw.githubusercontent.com/nwutils/nw-builder/main/src/util/osx.arm.versions.json"` | `"https://nwjs.io/versions"` | Versions manifest |
|
|
212
220
|
| cacheDir | `string` | `"./cache"` | Directory to cache NW binaries |
|
|
221
|
+
| cache | `boolean` | `true`| If true the existing cache is used. Otherwise it removes and redownloads it. |
|
|
222
|
+
| ffmpeg | `boolean` | `false`| If true the chromium ffmpeg is replaced by community version with proprietary codecs. |
|
|
223
|
+
| logLevel | `"error" \| "warn" \| "info" \| "debug"` | `"info"`| Specify level of logging. |
|
|
213
224
|
| srcDir | `string` | `"./"` | File paths to application code |
|
|
225
|
+
| argv | `string[]` | `[]` | Command line arguments to pass to NW executable in run mode. You can also define these in `chromium-args` in NW.js manifest. |
|
|
226
|
+
| glob | `boolean` | `true`| If true file globbing is enabled when parsing `srcDir`. |
|
|
214
227
|
| outDir | `string` | `"./out"` | Directory to store build artifacts |
|
|
215
228
|
| managedManifest | `boolean \| string \| object` | `false` | Managed manifest |
|
|
216
229
|
| nodeAddon | `false \| "gyp"` | `false` | Rebuild Node native addons |
|
|
217
|
-
| cache | `boolean` | `true`| If true the existing cache is used. Otherwise it removes and redownloads it. |
|
|
218
|
-
| ffmpeg | `boolean` | `false`| If true the chromium ffmpeg is replaced by community version with proprietary codecs. |
|
|
219
|
-
| glob | `boolean` | `true`| If true file globbing is enabled when parsing `srcDir`. |
|
|
220
|
-
| logLevel | `"error" \| "warn" \| "info" \| "debug"` | `"info"`| Specify level of logging. |
|
|
221
230
|
| zip | `boolean \| "zip" \| "tar" \| "tgz"` | `false`| If true, "zip", "tar" or "tgz" the `outDir` directory is compressed. |
|
|
231
|
+
| app | `LinuxRc \| WinRc \| OsxRc` | Additional options for each platform. (See below.)
|
|
222
232
|
|
|
223
233
|
### `app` configuration object
|
|
224
234
|
|
|
@@ -228,20 +238,20 @@ This object defines additional properties used for building for a specific platf
|
|
|
228
238
|
|
|
229
239
|
| Name | Type | Default | Description |
|
|
230
240
|
| ---- | ------- | --------- | ----------- |
|
|
231
|
-
| `icon` | `string` | `undefined` | The path to the icon file. It should be a .ico file. |
|
|
232
|
-
| `name` | `string` | Value of `name` in
|
|
233
|
-
| `version` | `string` | Value of `version` in
|
|
241
|
+
| `icon` | `string` | `undefined` | The path to the icon file. It should be a .ico file. (**WARNING**: Please define the icon in the NW.js manifest instead) |
|
|
242
|
+
| `name` | `string` | Value of `name` in NW.js manifest | The name of the application |
|
|
243
|
+
| `version` | `string` | Value of `version` in NW.js manifest | The version of the application |
|
|
234
244
|
| `comments` | `string` | `undefined` | Additional information that should be displayed for diagnostic purposes. |
|
|
235
|
-
| `company` | `string` | Value of `author` in
|
|
236
|
-
| `fileDescription` | `string` | Value of `description` in
|
|
237
|
-
| `fileVersion` | `string` | Value of `version`
|
|
238
|
-
| `internalName` | `string` | Value of `name` in
|
|
239
|
-
| `legalCopyright` | `string` |
|
|
245
|
+
| `company` | `string` | Value of `author` in NW.js manifest | Company that produced the file—for example, Microsoft Corporation or Standard Microsystems Corporation, Inc. This string is required. |
|
|
246
|
+
| `fileDescription` | `string` | Value of `description` in NW.js manifest | 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. |
|
|
247
|
+
| `fileVersion` | `string` | Value of `version` or value of `version` in NW.js manifest | Version number of the file. For example, 3.10 or 5.00.RC2. This string is required. |
|
|
248
|
+
| `internalName` | `string` | Value of `name` in NW.js manifest |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. |
|
|
249
|
+
| `legalCopyright` | `string` | `undefined` | 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. |
|
|
240
250
|
| `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. |
|
|
241
251
|
| `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. |
|
|
242
252
|
| `privateBuild` | `string` | `undefined` | Information about a private version of the file—for example, Built by TESTER1 on \\TESTBED. |
|
|
243
|
-
| `productName` | `string` |
|
|
244
|
-
| `productVersion` | `string` | Value of `version` in
|
|
253
|
+
| `productName` | `string` | `name` in NW.js manifest | Name of the product with which the file is distributed. This string is required. |
|
|
254
|
+
| `productVersion` | `string` | Value of `version` in NW.js manifest | Version of the product with which the file is distributed—for example, 3.10 or 5.00.RC2. |
|
|
245
255
|
| `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
256
|
| `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 |
|
|
247
257
|
|
|
@@ -253,7 +263,7 @@ This object defines additional properties used for building for a specific platf
|
|
|
253
263
|
| genericName | `string` | Generic name of the application |
|
|
254
264
|
| noDisplay | `boolean` | If true the application is not displayed |
|
|
255
265
|
| comment | `string` | Tooltip for the entry, for example "View sites on the Internet". |
|
|
256
|
-
| icon | `string` | Icon to display in file manager, menus, etc. |
|
|
266
|
+
| icon | `string` | Icon to display in file manager, menus, etc. (**WARNING**: Please define the icon in the NW.js manifest instead) |
|
|
257
267
|
| hidden | `boolean` | TBD |
|
|
258
268
|
| onlyShowIn | `string[]` | A list of strings identifying the desktop environments that should display a given desktop entry |
|
|
259
269
|
| notShowIn | `string[]` | A list of strings identifying the desktop environments that should not display a given desktop entry |
|
|
@@ -277,7 +287,7 @@ This object defines additional properties used for building for a specific platf
|
|
|
277
287
|
| Name | Type | Description |
|
|
278
288
|
| ---- | ------- | ----------- |
|
|
279
289
|
| name | `string` | The name of the application |
|
|
280
|
-
| icon | `string` | The path to the icon file. It should be a .icns file. |
|
|
290
|
+
| icon | `string` | The path to the icon file. It should be a .icns file. (**WARNING**: Please define the icon in the NW.js manifest instead) |
|
|
281
291
|
| LSApplicationCategoryType | `string` | The category that best describes your app for the App Store. |
|
|
282
292
|
| CFBundleIdentifier | `string` | A unique identifier for a bundle usually in reverse DNS format. |
|
|
283
293
|
| CFBundleName | `string` | A user-visible short name for the bundle. |
|
|
@@ -385,7 +395,6 @@ nwbuild({
|
|
|
385
395
|
|
|
386
396
|
### Chores
|
|
387
397
|
|
|
388
|
-
- chore: add Linux, MacOS and Windows fixtures
|
|
389
398
|
- chore(docs): don't store JSDoc definitions in `typedef`s - get's hard to understand during development.
|
|
390
399
|
- chore: annotate file paths as `fs.PathLike` instead of `string`.
|
|
391
400
|
- chore(bld): factor out core build step
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nw-builder",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "Build NW.js desktop applications for MacOS, Windows and Linux.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NW.js",
|
|
@@ -46,17 +46,21 @@
|
|
|
46
46
|
"lint:fix": "eslint --fix ./src ./tests",
|
|
47
47
|
"test": "vitest run --coverage",
|
|
48
48
|
"test:cov": "vitest --coverage.enabled true",
|
|
49
|
-
"demo:bld": "node ./tests/fixtures/demo.js",
|
|
50
|
-
"demo:
|
|
49
|
+
"demo:bld:linux": "node ./tests/fixtures/demo.linux.js",
|
|
50
|
+
"demo:bld:osx": "node ./tests/fixtures/demo.osx.js",
|
|
51
|
+
"demo:bld:win": "node ./tests/fixtures/demo.win.js",
|
|
52
|
+
"demo:exe:linux": "./tests/fixtures/out/linux/Demo",
|
|
53
|
+
"demo:exe:osx": "./tests/fixtures/out/osx/Demo.app/Contents/MacOS/Demo",
|
|
54
|
+
"demo:exe:win": "./tests/fixtures/out/win/Demo.exe",
|
|
51
55
|
"demo:cli": "nwbuild --mode=run --flavor=sdk --glob=false --cacheDir=./node_modules/nw ./tests/fixtures/app"
|
|
52
56
|
},
|
|
53
57
|
"devDependencies": {
|
|
54
|
-
"@eslint/js": "^9.
|
|
55
|
-
"@vitest/coverage-v8": "^2.1.
|
|
58
|
+
"@eslint/js": "^9.15.0",
|
|
59
|
+
"@vitest/coverage-v8": "^2.1.5",
|
|
56
60
|
"base-volta-off-of-nwjs": "^1.0.5",
|
|
57
|
-
"eslint": "^9.
|
|
58
|
-
"eslint-plugin-jsdoc": "^50.
|
|
59
|
-
"globals": "^15.
|
|
61
|
+
"eslint": "^9.15.0",
|
|
62
|
+
"eslint-plugin-jsdoc": "^50.5.0",
|
|
63
|
+
"globals": "^15.12.0",
|
|
60
64
|
"nw": "^0.93.0",
|
|
61
65
|
"selenium-webdriver": "^4.25.0",
|
|
62
66
|
"vitest": "^2.0.4"
|
package/src/bld.js
CHANGED
|
@@ -62,11 +62,11 @@ import setOsxConfig from './bld/osx.js';
|
|
|
62
62
|
* References:
|
|
63
63
|
* https://learn.microsoft.com/en-us/windows/win32/msi/version
|
|
64
64
|
* https://learn.microsoft.com/en-gb/windows/win32/sbscs/application-manifests
|
|
65
|
-
* https://learn.microsoft.com/en-us/
|
|
65
|
+
* https://learn.microsoft.com/en-us/visualstudio/deployment/trustinfo-element-clickonce-application?view=vs-2022#requestedexecutionlevel
|
|
66
66
|
* https://learn.microsoft.com/en-gb/windows/win32/menurc/versioninfo-resource
|
|
67
67
|
* @typedef {object} WinRc Windows configuration options. More info
|
|
68
68
|
* @property {string} name The name of the application
|
|
69
|
-
* @property {string} version
|
|
69
|
+
* @property {string} version The version of the application
|
|
70
70
|
* @property {string} comments Additional information that should be displayed for diagnostic purposes.
|
|
71
71
|
* @property {string} company Company that produced the file—for example, Microsoft Corporation or Standard Microsystems Corporation, Inc. This string is required.
|
|
72
72
|
* @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.
|
|
@@ -256,13 +256,13 @@ const setLinuxConfig = async ({ app, outDir }) => {
|
|
|
256
256
|
GenericName: app.genericName,
|
|
257
257
|
NoDisplay: app.noDisplay,
|
|
258
258
|
Comment: app.comment,
|
|
259
|
-
Icon: app.icon,
|
|
259
|
+
Icon: path.resolve(outDir, 'package.nw', path.basename(app.icon)),
|
|
260
260
|
Hidden: app.hidden,
|
|
261
261
|
OnlyShowIn: app.onlyShowIn,
|
|
262
262
|
NotShowIn: app.notShowIn,
|
|
263
263
|
DBusActivatable: app.dBusActivatable,
|
|
264
264
|
TryExec: app.tryExec,
|
|
265
|
-
Exec: app.
|
|
265
|
+
Exec: app.exec,
|
|
266
266
|
Path: app.path,
|
|
267
267
|
Terminal: app.terminal,
|
|
268
268
|
Actions: app.actions,
|
|
@@ -319,10 +319,11 @@ const setWinConfig = async ({ app, outDir }) => {
|
|
|
319
319
|
if (app.icon) {
|
|
320
320
|
const iconBuffer = await fs.promises.readFile(path.resolve(app.icon));
|
|
321
321
|
const iconFile = resedit.Data.IconFile.from(iconBuffer);
|
|
322
|
+
const iconGroupIDs = resedit.Resource.IconGroupEntry.fromEntries(res.entries).map((entry) => entry.id);
|
|
322
323
|
resedit.Resource.IconGroupEntry.replaceIconsForResource(
|
|
323
324
|
res.entries,
|
|
324
|
-
|
|
325
|
-
|
|
325
|
+
/* Should be `IDR_MAINFRAME` */
|
|
326
|
+
iconGroupIDs[0],
|
|
326
327
|
EN_US,
|
|
327
328
|
iconFile.icons.map(i => i.data)
|
|
328
329
|
);
|
package/src/get/request.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
+
import process from 'node:process';
|
|
2
3
|
import stream from 'node:stream';
|
|
3
4
|
|
|
4
5
|
import axios from 'axios';
|
|
@@ -15,6 +16,15 @@ export default async function request(url, filePath) {
|
|
|
15
16
|
|
|
16
17
|
const writeStream = fs.createWriteStream(filePath);
|
|
17
18
|
|
|
19
|
+
/* Listen for SIGINT (Ctrl+C) */
|
|
20
|
+
process.on('SIGINT', function () {
|
|
21
|
+
/* Delete file if it exists. This prevents unnecessary `Central Directory not found` errors. */
|
|
22
|
+
if (fs.existsSync(filePath)) {
|
|
23
|
+
fs.unlinkSync(filePath);
|
|
24
|
+
}
|
|
25
|
+
process.exit();
|
|
26
|
+
});
|
|
27
|
+
|
|
18
28
|
const response = await axios({
|
|
19
29
|
method: 'get',
|
|
20
30
|
url: url,
|
|
@@ -22,4 +32,5 @@ export default async function request(url, filePath) {
|
|
|
22
32
|
});
|
|
23
33
|
|
|
24
34
|
await stream.promises.pipeline(response.data, writeStream);
|
|
35
|
+
|
|
25
36
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -61,7 +61,7 @@ export type AppOptions<P extends SupportedPlatform> =
|
|
|
61
61
|
export interface WindowsAppOptions {
|
|
62
62
|
/** The name of the application */
|
|
63
63
|
name?: string,
|
|
64
|
-
/**
|
|
64
|
+
/** The version of the application */
|
|
65
65
|
version?: string,
|
|
66
66
|
/** Additional information that should be displayed for diagnostic purposes. */
|
|
67
67
|
comments?: string,
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import console from 'node:console';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
3
4
|
|
|
4
5
|
import bld from './bld.js';
|
|
5
6
|
import get from './get/index.js';
|
|
@@ -45,17 +46,19 @@ async function nwbuild(options) {
|
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
try {
|
|
48
|
-
|
|
49
|
+
/* Parse options */
|
|
49
50
|
options = await util.parse(options, manifest);
|
|
51
|
+
util.log('debug', 'info', 'Parse initial options');
|
|
50
52
|
|
|
53
|
+
util.log('debug', 'info', 'Get node manifest...');
|
|
51
54
|
manifest = await util.getNodeManifest({ srcDir: options.srcDir, glob: options.glob });
|
|
52
55
|
if (typeof manifest.json?.nwbuild === 'object') {
|
|
53
56
|
options = manifest.json.nwbuild;
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
util.log('info', options.logLevel, 'Parse final options using node manifest');
|
|
56
60
|
options = await util.parse(options, manifest.json);
|
|
57
|
-
|
|
58
|
-
//TODO: impl logging
|
|
61
|
+
util.log('debug', options.logLevel, 'Manifest: ', `${manifest.path}\n${manifest.json}\n`);
|
|
59
62
|
|
|
60
63
|
built = fs.existsSync(options.cacheDir);
|
|
61
64
|
if (built === false) {
|
|
@@ -69,7 +72,8 @@ async function nwbuild(options) {
|
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
/* Validate options.version to get the version specific release info */
|
|
76
|
+
util.log('info', options.logLevel, 'Get version specific release info...');
|
|
73
77
|
releaseInfo = await util.getReleaseInfo(
|
|
74
78
|
options.version,
|
|
75
79
|
options.platform,
|
|
@@ -77,13 +81,16 @@ async function nwbuild(options) {
|
|
|
77
81
|
options.cacheDir,
|
|
78
82
|
options.manifestUrl,
|
|
79
83
|
);
|
|
84
|
+
util.log('debug', options.logLevel, `Release info:\n${JSON.stringify(releaseInfo, null, 2)}\n`);
|
|
80
85
|
|
|
86
|
+
util.log('info', options.logLevel, 'Validate options.* ...');
|
|
81
87
|
await util.validate(options, releaseInfo);
|
|
88
|
+
util.log('debug', options.logLevel, `Options:\n${JSON.stringify(options, null, 2)}`);
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
/* Remove leading "v" from version string */
|
|
84
91
|
options.version = releaseInfo.version.slice(1);
|
|
85
92
|
|
|
86
|
-
|
|
93
|
+
util.log('info', options.logLevel, 'Getting NW.js and related binaries...');
|
|
87
94
|
await get({
|
|
88
95
|
version: options.version,
|
|
89
96
|
flavor: options.flavor,
|
|
@@ -102,6 +109,7 @@ async function nwbuild(options) {
|
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
if (options.mode === 'run') {
|
|
112
|
+
util.log('info', options.logLevel, 'Running NW.js in run mode...');
|
|
105
113
|
await run({
|
|
106
114
|
version: options.version,
|
|
107
115
|
flavor: options.flavor,
|
|
@@ -113,6 +121,7 @@ async function nwbuild(options) {
|
|
|
113
121
|
argv: options.argv,
|
|
114
122
|
});
|
|
115
123
|
} else if (options.mode === 'build') {
|
|
124
|
+
util.log('info', options.logLevel, `Build a NW.js application for ${options.platform} ${options.arch}...`);
|
|
116
125
|
await bld({
|
|
117
126
|
version: options.version,
|
|
118
127
|
flavor: options.flavor,
|
|
@@ -129,6 +138,7 @@ async function nwbuild(options) {
|
|
|
129
138
|
zip: options.zip,
|
|
130
139
|
releaseInfo: releaseInfo,
|
|
131
140
|
});
|
|
141
|
+
util.log('info', options.logLevel, `Appliction is available at ${path.resolve(options.outDir)}`);
|
|
132
142
|
}
|
|
133
143
|
} catch (error) {
|
|
134
144
|
console.error(error);
|
package/src/run.js
CHANGED
|
@@ -23,7 +23,7 @@ import util from './util.js';
|
|
|
23
23
|
* @async
|
|
24
24
|
* @function
|
|
25
25
|
* @param {RunOptions} options Run mode options
|
|
26
|
-
* @returns {Promise<
|
|
26
|
+
* @returns {Promise<child_process.ChildProcess | null>} - A Node.js process object
|
|
27
27
|
*/
|
|
28
28
|
async function run({
|
|
29
29
|
version = 'latest',
|
|
@@ -35,6 +35,11 @@ async function run({
|
|
|
35
35
|
glob = false,
|
|
36
36
|
argv = [],
|
|
37
37
|
}) {
|
|
38
|
+
/**
|
|
39
|
+
* @type {child_process.ChildProcess | null}
|
|
40
|
+
*/
|
|
41
|
+
let nwProcess = null;
|
|
42
|
+
|
|
38
43
|
try {
|
|
39
44
|
if (util.EXE_NAME[platform] === undefined) {
|
|
40
45
|
throw new Error('Unsupported platform.');
|
|
@@ -49,8 +54,8 @@ async function run({
|
|
|
49
54
|
);
|
|
50
55
|
|
|
51
56
|
return new Promise((res, rej) => {
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
/* It is assumed that the package.json is located at `${options.srcDir}/package.json` */
|
|
58
|
+
nwProcess = child_process.spawn(
|
|
54
59
|
path.resolve(nwDir, util.EXE_NAME[platform]),
|
|
55
60
|
[...[srcDir], ...argv],
|
|
56
61
|
{ stdio: 'inherit' },
|
|
@@ -68,6 +73,7 @@ async function run({
|
|
|
68
73
|
} catch (error) {
|
|
69
74
|
console.error(error);
|
|
70
75
|
}
|
|
76
|
+
return nwProcess;
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
export default run;
|
package/src/util.js
CHANGED
|
@@ -172,16 +172,16 @@ async function getNodeManifest({
|
|
|
172
172
|
* @param {any} option - a boolean type option
|
|
173
173
|
* @returns {any} Usually `undefined`, `true` or `false`. if not then it is validated later on.
|
|
174
174
|
*/
|
|
175
|
-
function str2Bool
|
|
175
|
+
function str2Bool(option) {
|
|
176
176
|
if (typeof option === 'string') {
|
|
177
177
|
if (option === 'true') {
|
|
178
178
|
return true;
|
|
179
179
|
} else if (option === 'false') {
|
|
180
180
|
return false;
|
|
181
|
-
}
|
|
181
|
+
}
|
|
182
182
|
} else {
|
|
183
183
|
return option;
|
|
184
|
-
}
|
|
184
|
+
}
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
/**
|
|
@@ -230,7 +230,8 @@ export const parse = async (options, pkg) => {
|
|
|
230
230
|
/* Remove special and control characters from app.name to mitigate potential path traversal. */
|
|
231
231
|
options.app.name = options.app.name.replace(/[<>:"/\\|?*\u0000-\u001F]/g, '');
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
/* Path to where the icon currently is in the filesystem */
|
|
234
|
+
options.app.icon = path.resolve(options.app.icon) ?? undefined;
|
|
234
235
|
|
|
235
236
|
// TODO(#737): move this out
|
|
236
237
|
if (options.platform === 'linux') {
|
|
@@ -243,7 +244,7 @@ export const parse = async (options, pkg) => {
|
|
|
243
244
|
options.app.notShowIn = options.app.notShowIn ?? undefined;
|
|
244
245
|
options.app.dBusActivatable = options.app.dBusActivatable ?? undefined;
|
|
245
246
|
options.app.tryExec = options.app.tryExec ?? undefined;
|
|
246
|
-
options.app.exec = options.app.
|
|
247
|
+
options.app.exec = path.resolve(options.app.exec) ?? undefined;
|
|
247
248
|
options.app.path = options.app.path ?? undefined;
|
|
248
249
|
options.app.terminal = options.app.terminal ?? undefined;
|
|
249
250
|
options.app.actions = options.app.actions ?? undefined;
|
|
@@ -306,7 +307,11 @@ export const parse = async (options, pkg) => {
|
|
|
306
307
|
* @throws {Error} Throw error if options are invalid
|
|
307
308
|
*/
|
|
308
309
|
export const validate = async (options, releaseInfo) => {
|
|
309
|
-
if (
|
|
310
|
+
if (
|
|
311
|
+
options.mode !== 'get' &&
|
|
312
|
+
options.mode !== 'run' &&
|
|
313
|
+
options.mode !== 'build'
|
|
314
|
+
) {
|
|
310
315
|
throw new Error(
|
|
311
316
|
`Unknown mode ${options.mode}. Expected "get", "run" or "build".`,
|
|
312
317
|
);
|
|
@@ -330,16 +335,23 @@ export const validate = async (options, releaseInfo) => {
|
|
|
330
335
|
`Platform ${options.platform} and architecture ${options.arch} is not supported by this download server.`,
|
|
331
336
|
);
|
|
332
337
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
338
|
+
if (typeof options.downloadUrl === 'string' && !options.downloadUrl.startsWith('http') && !options.downloadUrl.startsWith('file')) {
|
|
339
|
+
throw new Error('Expected options.downloadUrl to be a string and starts with `http` or `file`.');
|
|
340
|
+
}
|
|
341
|
+
if (typeof options.manifestUrl === 'string' && !options.manifestUrl.startsWith('http') && !options.manifestUrl.startsWith('file')) {
|
|
342
|
+
throw new Error('Expected options.manifestUrl to be a string and starts with `http` or `file`.');
|
|
343
|
+
}
|
|
344
|
+
if (typeof options.cacheDir !== 'string') {
|
|
345
|
+
throw new Error('Expected options.cacheDir to be a string. Got ' + typeof options.cacheDir);
|
|
346
|
+
}
|
|
347
|
+
|
|
336
348
|
if (typeof options.cache !== 'boolean') {
|
|
337
|
-
|
|
349
|
+
throw new Error(
|
|
338
350
|
'Expected options.cache to be a boolean. Got ' + typeof options.cache,
|
|
339
351
|
);
|
|
340
352
|
}
|
|
341
353
|
if (typeof options.ffmpeg !== 'boolean') {
|
|
342
|
-
|
|
354
|
+
throw new Error(
|
|
343
355
|
'Expected options.ffmpeg to be a boolean. Got ' + typeof options.ffmpeg,
|
|
344
356
|
);
|
|
345
357
|
}
|
|
@@ -359,27 +371,26 @@ export const validate = async (options, releaseInfo) => {
|
|
|
359
371
|
if (options.mode === 'get') {
|
|
360
372
|
return undefined;
|
|
361
373
|
}
|
|
374
|
+
if (typeof options.srcDir !== 'string') {
|
|
375
|
+
throw new Error('Expected options.srcDir to be a string. Got ' + typeof options.srcDir);
|
|
376
|
+
}
|
|
362
377
|
if (Array.isArray(options.argv)) {
|
|
363
|
-
|
|
378
|
+
throw new Error(
|
|
364
379
|
'Expected options.argv to be an array. Got ' + typeof options.argv,
|
|
365
380
|
);
|
|
366
381
|
}
|
|
367
382
|
if (typeof options.glob !== 'boolean') {
|
|
368
|
-
|
|
383
|
+
throw new Error(
|
|
369
384
|
'Expected options.glob to be a boolean. Got ' + typeof options.glob,
|
|
370
385
|
);
|
|
371
386
|
}
|
|
372
387
|
|
|
373
|
-
if (options.srcDir) {
|
|
374
|
-
await fs.promises.readdir(options.srcDir);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
388
|
if (options.mode === 'run') {
|
|
378
389
|
return undefined;
|
|
379
390
|
}
|
|
380
391
|
|
|
381
|
-
if (options.outDir) {
|
|
382
|
-
|
|
392
|
+
if (typeof options.outDir !== 'string') {
|
|
393
|
+
throw new Error('Expected options.outDir to be a string. Got ' + typeof options.outDir);
|
|
383
394
|
}
|
|
384
395
|
|
|
385
396
|
if (
|
|
@@ -387,7 +398,7 @@ export const validate = async (options, releaseInfo) => {
|
|
|
387
398
|
typeof options.managedManifest !== 'object' &&
|
|
388
399
|
typeof options.managedManifest !== 'string'
|
|
389
400
|
) {
|
|
390
|
-
|
|
401
|
+
throw new Error(
|
|
391
402
|
'Expected options.managedManifest to be a boolean, object or string. Got ' +
|
|
392
403
|
typeof options.managedManifest,
|
|
393
404
|
);
|
|
@@ -395,24 +406,184 @@ export const validate = async (options, releaseInfo) => {
|
|
|
395
406
|
|
|
396
407
|
if (typeof options.managedManifest === 'object') {
|
|
397
408
|
if (options.managedManifest.name === undefined) {
|
|
398
|
-
|
|
409
|
+
throw new Error('Expected NW.js Manifest to have a `name` property.');
|
|
399
410
|
}
|
|
400
411
|
if (options.managedManifest.main === undefined) {
|
|
401
|
-
|
|
412
|
+
throw new Error('Expected NW.js Manifest to have a `main` property.');
|
|
402
413
|
}
|
|
403
414
|
}
|
|
404
415
|
|
|
405
416
|
if (typeof options.nativeAddon !== 'boolean') {
|
|
406
417
|
if (typeof options.nativeAddon !== 'boolean' && typeof options.nativeAddon !== 'string') {
|
|
407
|
-
|
|
418
|
+
throw new Error('Expected options.nativeAddon to be a boolean or string type. Got ' + typeof options.nativeAddon);
|
|
408
419
|
}
|
|
409
420
|
|
|
410
421
|
if (semver.parse(options.version).minor >= '83' && options.nativeAddon !== false) {
|
|
411
|
-
|
|
422
|
+
throw new Error('Native addons are not supported for NW.js v0.82.0 and below');
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (typeof options.zip !== 'boolean' &
|
|
426
|
+
options.zip !== 'zip' &&
|
|
427
|
+
options.zip !== 'tar' &&
|
|
428
|
+
options.zip !== 'tgz') {
|
|
429
|
+
throw new Error('Expected options.zip to be a boolean, `zip`, `tar` or `tgz`. Got ' + typeof options.zip);
|
|
412
430
|
}
|
|
413
431
|
}
|
|
414
432
|
|
|
415
|
-
|
|
433
|
+
if (options.platform === 'linux') {
|
|
434
|
+
if (options.app.name && typeof options.app.name !== 'string') {
|
|
435
|
+
throw new Error('Expected options.app.name to be a string. Got ' + options.app.name);
|
|
436
|
+
}
|
|
437
|
+
if (options.app.genericName && typeof options.app.genericName !== 'string') {
|
|
438
|
+
throw new Error('Expected options.app.genericName to be a string. Got ' + options.app.genericName);
|
|
439
|
+
}
|
|
440
|
+
if (options.app.noDisplay && typeof options.app.noDisplay !== 'boolean') {
|
|
441
|
+
throw new Error('Expected options.app.noDisplay to be a boolean. Got ' + options.app.noDisplay);
|
|
442
|
+
}
|
|
443
|
+
if (options.app.comment && typeof options.app.comment !== 'string') {
|
|
444
|
+
throw new Error('Expected options.app.comment to be a string. Got ' + options.app.comment);
|
|
445
|
+
}
|
|
446
|
+
if (options.app.icon && typeof options.app.icon !== 'string') {
|
|
447
|
+
throw new Error('Expected options.app.icon to be a string. Got ' + options.app.icon);
|
|
448
|
+
}
|
|
449
|
+
if (options.app.hidden && typeof options.app.hidden !== 'string') {
|
|
450
|
+
throw new Error('Expected options.app.hidden to be a string. Got ' + options.app.hidden);
|
|
451
|
+
}
|
|
452
|
+
if (options.app.onlyShowIn && Array.isArray(options.app.onlyShowIn)) {
|
|
453
|
+
throw new Error('Expected options.app.onlyShowIn to be an Array<string>. Got ' + options.app.onlyShowIn);
|
|
454
|
+
}
|
|
455
|
+
if (options.app.notShowIn && Array.isArray(options.app.notShowIn)) {
|
|
456
|
+
throw new Error('Expected options.app.notShowIn to be an Array<string>. Got ' + options.app.notShowIn);
|
|
457
|
+
}
|
|
458
|
+
if (options.app.dBusActivatable && typeof options.app.dBusActivatable !== 'boolean') {
|
|
459
|
+
throw new Error('Expected options.app.dBusActivatable to be a boolean. Got ' + options.app.dBusActivatable);
|
|
460
|
+
}
|
|
461
|
+
if (options.app.tryExec && typeof options.app.tryExec !== 'string') {
|
|
462
|
+
throw new Error('Expected options.app.tryExec to be a string. Got ' + options.app.tryExec);
|
|
463
|
+
}
|
|
464
|
+
if (options.app.exec && typeof options.app.exec !== 'string') {
|
|
465
|
+
throw new Error('Expected options.app.exec to be a string. Got ' + options.app.exec);
|
|
466
|
+
}
|
|
467
|
+
if (options.app.path && typeof options.app.path !== 'string') {
|
|
468
|
+
throw new Error('Expected options.app.path to be a string. Got ' + options.app.path);
|
|
469
|
+
}
|
|
470
|
+
if (options.app.terminal && typeof options.app.terminal !== 'boolean') {
|
|
471
|
+
throw new Error('Expected options.app.terminal to be a boolean. Got ' + options.app.terminal);
|
|
472
|
+
}
|
|
473
|
+
if (options.app.actions && Array.isArray(options.app.actions)) {
|
|
474
|
+
throw new Error('Expected options.app.actions to be a Array<string>. Got ' + options.app.actions);
|
|
475
|
+
}
|
|
476
|
+
if (options.app.mimeType && Array.isArray(options.app.mimeType)) {
|
|
477
|
+
throw new Error('Expected options.app.mimeType to be a Array<string>. Got ' + options.app.mimeType);
|
|
478
|
+
}
|
|
479
|
+
if (options.app.categories && Array.isArray(options.app.categories)) {
|
|
480
|
+
throw new Error('Expected options.app.categories to be a Array<string>. Got ' + options.app.categories);
|
|
481
|
+
}
|
|
482
|
+
if (options.app.implements && Array.isArray(options.app.implements)) {
|
|
483
|
+
throw new Error('Expected options.app.implements to be a Array<string>. Got ' + options.app.implements);
|
|
484
|
+
}
|
|
485
|
+
if (options.app.keywords && Array.isArray(options.app.keywords)) {
|
|
486
|
+
throw new Error('Expected options.app.keywords to be a Array<string>. Got ' + options.app.keywords);
|
|
487
|
+
}
|
|
488
|
+
if (options.app.startupNotify && typeof options.app.startupNotify !== 'boolean') {
|
|
489
|
+
throw new Error('Expected options.app.startupNotify to be a boolean. Got ' + options.app.startupNotify);
|
|
490
|
+
}
|
|
491
|
+
if (options.app.startupWMClass && typeof options.app.startupWMClass !== 'string') {
|
|
492
|
+
throw new Error('Expected options.app.startupWMClass to be a string. Got ' + options.app.startupWMClass);
|
|
493
|
+
}
|
|
494
|
+
if (options.app.prefersNonDefaultGPU && typeof options.app.prefersNonDefaultGPU !== 'boolean') {
|
|
495
|
+
throw new Error('Expected options.app.prefersNonDefaultGPU to be a boolean. Got ' + options.app.prefersNonDefaultGPU);
|
|
496
|
+
}
|
|
497
|
+
if (options.app.singleMainWindow && typeof options.app.singleMainWindow !== 'string') {
|
|
498
|
+
throw new Error('Expected options.app.singleMainWindow to be a string. Got ' + options.app.singleMainWindow);
|
|
499
|
+
}
|
|
500
|
+
} else if (options.platform === 'osx') {
|
|
501
|
+
if (typeof options.app.name !== 'string') {
|
|
502
|
+
throw new Error('Expected options.app.name to be a string. Got ' + options.app.name);
|
|
503
|
+
}
|
|
504
|
+
if (typeof options.app.icon !== 'string') {
|
|
505
|
+
throw new Error('Expected options.app.icon to be a string. Got ' + options.app.icon);
|
|
506
|
+
}
|
|
507
|
+
if (typeof options.app.LSApplicationCategoryType !== 'string') {
|
|
508
|
+
throw new Error('Expected options.app.LSApplicationCategoryType to be a string. Got ' + options.app.LSApplicationCategoryType);
|
|
509
|
+
}
|
|
510
|
+
if (typeof options.app.CFBundleIdentifier !== 'string') {
|
|
511
|
+
throw new Error('Expected options.app.CFBundleIdentifier to be a string. Got ' + options.app.CFBundleIdentifier);
|
|
512
|
+
}
|
|
513
|
+
if (typeof options.app.CFBundleName !== 'string') {
|
|
514
|
+
throw new Error('Expected options.app.CFBundleName to be a string. Got ' + options.app.CFBundleName);
|
|
515
|
+
}
|
|
516
|
+
if (typeof options.app.CFBundleDisplayName !== 'string') {
|
|
517
|
+
throw new Error('Expected options.app.CFBundleDisplayName to be a string. Got ' + options.app.CFBundleDisplayName);
|
|
518
|
+
}
|
|
519
|
+
if (typeof options.app.CFBundleSpokenName !== 'string') {
|
|
520
|
+
throw new Error('Expected options.app.CFBundleSpokenName to be a string. Got ' + options.app.CFBundleSpokenName);
|
|
521
|
+
}
|
|
522
|
+
if (typeof options.app.CFBundleVersion !== 'string') {
|
|
523
|
+
throw new Error('Expected options.app.CFBundleVersion to be a string. Got ' + options.app.CFBundleVersion);
|
|
524
|
+
}
|
|
525
|
+
if (typeof options.app.CFBundleShortVersionString !== 'string') {
|
|
526
|
+
throw new Error('Expected options.app.CFBundleShortVersionString to be a string. Got ' + options.app.CFBundleShortVersionString);
|
|
527
|
+
}
|
|
528
|
+
if (typeof options.app.NSHumanReadableCopyright !== 'string') {
|
|
529
|
+
throw new Error('Expected options.app.NSHumanReadableCopyright to be a string. Got ' + options.app.NSHumanReadableCopyright);
|
|
530
|
+
}
|
|
531
|
+
if (typeof options.app.NSLocalNetworkUsageDescription !== 'string') {
|
|
532
|
+
throw new Error('Expected options.app.NSLocalNetworkUsageDescription to be a string. Got ' + options.app.NSLocalNetworkUsageDescription);
|
|
533
|
+
}
|
|
534
|
+
} else {
|
|
535
|
+
if (typeof options.app.name !== 'string') {
|
|
536
|
+
throw new Error('Expected options.app.name to be a string. Got ' + options.app.name);
|
|
537
|
+
}
|
|
538
|
+
if (typeof options.app.icon !== 'string') {
|
|
539
|
+
throw new Error('Expected options.app.icon to be a string. Got ' + options.app.icon);
|
|
540
|
+
}
|
|
541
|
+
if (typeof options.app.version !== 'string') {
|
|
542
|
+
throw new Error('Expected options.app.version to be a string. Got ' + options.app.version);
|
|
543
|
+
}
|
|
544
|
+
if (options.app.comments && typeof options.app.comments !== 'string') {
|
|
545
|
+
throw new Error('Expected options.app.comments to be a string. Got ' + options.app.comments);
|
|
546
|
+
}
|
|
547
|
+
if (typeof options.app.company !== 'string') {
|
|
548
|
+
throw new Error('Expected options.app.company to be a string. Got ' + options.app.company);
|
|
549
|
+
}
|
|
550
|
+
if (typeof options.app.fileDescription !== 'string') {
|
|
551
|
+
throw new Error('Expected options.app.fileDescription to be a string. Got ' + options.app.fileDescription);
|
|
552
|
+
}
|
|
553
|
+
if (typeof options.app.fileVersion !== 'string') {
|
|
554
|
+
throw new Error('Expected options.app.fileVersion to be a string. Got ' + options.app.fileVersion);
|
|
555
|
+
}
|
|
556
|
+
if (typeof options.app.internalName !== 'string') {
|
|
557
|
+
throw new Error('Expected options.app.internalName to be a string. Got ' + options.app.internalName);
|
|
558
|
+
}
|
|
559
|
+
if (options.app.legalCopyright && typeof options.app.legalCopyright !== 'string') {
|
|
560
|
+
throw new Error('Expected options.app.legalCopyright to be a string. Got ' + options.app.legalCopyright);
|
|
561
|
+
}
|
|
562
|
+
if (options.app.legalTrademark && typeof options.app.legalTrademark !== 'string') {
|
|
563
|
+
throw new Error('Expected options.app.legalTrademark to be a string. Got ' + options.app.legalTrademark);
|
|
564
|
+
}
|
|
565
|
+
if (typeof options.app.originalFilename !== 'string') {
|
|
566
|
+
throw new Error('Expected options.app.originalFilename to be a string. Got ' + options.app.originalFilename);
|
|
567
|
+
}
|
|
568
|
+
if (typeof options.app.privateBuild !== 'string') {
|
|
569
|
+
throw new Error('Expected options.app.privateBuild to be a string. Got ' + options.app.privateBuild);
|
|
570
|
+
}
|
|
571
|
+
if (typeof options.app.productName !== 'string') {
|
|
572
|
+
throw new Error('Expected options.app.productName to be a string. Got ' + options.app.productName);
|
|
573
|
+
}
|
|
574
|
+
if (typeof options.app.productVersion !== 'string') {
|
|
575
|
+
throw new Error('Expected options.app.productVersion to be a string. Got ' + options.app.productVersion);
|
|
576
|
+
}
|
|
577
|
+
if (options.app.specialBuild && typeof options.app.specialBuild !== 'string') {
|
|
578
|
+
throw new Error('Expected options.app.specialBuild to be a string. Got ' + options.app.specialBuild);
|
|
579
|
+
}
|
|
580
|
+
if (typeof options.app.legalCopyright !== 'string') {
|
|
581
|
+
throw new Error('Expected options.app.legalCopyright to be a string. Got ' + options.app.legalCopyright);
|
|
582
|
+
}
|
|
583
|
+
if (typeof options.app.languageCode !== 'number') {
|
|
584
|
+
throw new Error('Expected options.app.languageCode to be a number. Got ' + options.app.languageCode);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
416
587
|
return undefined;
|
|
417
588
|
};
|
|
418
589
|
|
|
@@ -453,4 +624,39 @@ async function fileExists(filePath) {
|
|
|
453
624
|
return exists;
|
|
454
625
|
}
|
|
455
626
|
|
|
456
|
-
|
|
627
|
+
/**
|
|
628
|
+
* Custom logging function
|
|
629
|
+
* @param {'debug' | 'info' | 'warn' | 'error'} severity - severity of message
|
|
630
|
+
* @param {'debug' | 'info' | 'warn' | 'error'} logLevel - log level requested by user
|
|
631
|
+
* @param {string} message - contents of message
|
|
632
|
+
* @throws {Error} - throw error on invalid input
|
|
633
|
+
* @returns {string} - stdout
|
|
634
|
+
*/
|
|
635
|
+
function log(severity, logLevel, message) {
|
|
636
|
+
if (!['debug', 'info', 'warn', 'error'].includes(severity)) {
|
|
637
|
+
throw new Error(`Expected debug, info, warn or error message severity. Got ${severity}`);
|
|
638
|
+
}
|
|
639
|
+
if (!['debug', 'info', 'warn', 'error'].includes(logLevel)) {
|
|
640
|
+
throw new Error(`Expected debug, info, warn or error user defined log level. Got ${logLevel}`);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
const sev = {
|
|
644
|
+
'debug': 4,
|
|
645
|
+
'info': 3,
|
|
646
|
+
'warn': 2,
|
|
647
|
+
'error': 1,
|
|
648
|
+
};
|
|
649
|
+
let stdout = '';
|
|
650
|
+
const messageSeverity = sev[severity];
|
|
651
|
+
const userDefSeverity = sev[logLevel];
|
|
652
|
+
|
|
653
|
+
if (messageSeverity <= userDefSeverity) {
|
|
654
|
+
stdout = `[ ${severity.toUpperCase()} ] ${message}`;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
console.log(stdout);
|
|
658
|
+
|
|
659
|
+
return stdout;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
export default { fileExists, getReleaseInfo, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, globFiles, getNodeManifest, parse, validate, log };
|