nw 0.85.0 → 0.86.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 CHANGED
@@ -1,173 +1,123 @@
1
1
  # nw
2
2
 
3
- An installer for [NW.js](https://nwjs.io).
3
+ An npm installer for [NW.js](https://nwjs.io).
4
4
 
5
- > NW.js is a runtime-environment based on Chromium and Node.js. It is used to build desktop applications that run on Windows, OSX, and Linux.
5
+ [![npm](https://img.shields.io/npm/v/nw)](https://www.npmjs.com/package/nw)
6
6
 
7
- [![npm](https://img.shields.io/npm/v/nw.svg?style=flat)](https://www.npmjs.com/package/nw)
7
+ ## Install
8
8
 
9
- ## usage
10
- Install locally to your project with: `npm install nw` and then in your `package.json` add a script:
9
+ ### Latest version globally
11
10
 
12
- ```json
13
- {
14
- "scripts": {
15
- "start": "nw"
16
- }
17
- }
11
+ ```shell
12
+ npm install -g nw
18
13
  ```
19
14
 
20
- Now it will run your local project when you type `npm start`.
15
+ You might run into issues installing globally. [Learn how to fix this](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally)
21
16
 
22
- If your project is in another folder, add the path to the project `"start": "nw path/to/app"`.
17
+ ### Latest version of normal build flavor:
23
18
 
24
- You could also call `nw` directly from `node_modules/.bin/nw` instead of adding to your `package.json`.
19
+ ```shell
20
+ npm install --save-dev nw
21
+ ```
25
22
 
26
- ### global
27
- You can also install globally with `npm install nw -g` and then in any project type `nw` to run the project. Installing locally is recommended though as each project can have its own dependent version of nw.js.
23
+ ### Specific version with changes to installer:
28
24
 
29
- ## example
30
- If you want a really quick example try this:
25
+ ```shell
26
+ npm install --save-dev nw@0.85.0-1
27
+ ```
31
28
 
32
- 1. `git clone https://github.com/zcbenz/nw-sample-apps && cd nw-sample-apps`
33
- 2. `npm init`
34
- 3. `npm install nw`
35
- 4. `"node_modules/.bin/nw" file-explorer`
29
+ > You may use `npm view nw versions` to view the list of available versions.
36
30
 
37
- and now you should see a file explorer demo app.
31
+ ### Specify build flavor:
38
32
 
39
- ## command line options
40
- There are a few (platform-specific) arguments you can pass to the `nw` executable to
41
- customize your nw.js application:
33
+ ```shell
34
+ npm install --save-dev nw@sdk
35
+ ```
42
36
 
43
- * `--mac_plist <path-to-plist-file>`: (OS X only) Copies the given file to Info.plist in the app
44
- bundle. This lets you do things like change your app's name and point to a different icon.
37
+ > Optionally set `nwjs_build_type=sdk` in `.npmrc` or `NWJS_BUILD_TYPE=sdk` environment variable.
45
38
 
46
- * `--mac_icon <path-to-icns-file>`: (OS X only) Copies the given .icns file to the Resources/ dir
47
- in the app bundle. You will need to point to the file with a custom plist file as well (see
48
- `--mac_list`)
39
+ ### Specify platform:
49
40
 
50
- **NOTE**: These options will keep the copied files in the app bundle for as long as the bundle is
51
- on the filesystem (they're not deleted between app invocations). As a result, they're not
52
- recommended if you installed nw globally using `-g`. Also note that
53
- [OS X caches these files](http://proteo.me.uk/2011/08/mac-application-bundle-caching/),
54
- so you may need to manually clear these cached files during development.
41
+ Set `nwjs_platform` in `.npmrc` or `NWJS_PLATFORM` environment variable. Defaults to `process.platform`.
55
42
 
56
- ## install a specific version of nw.js
43
+ ### Specify architecture:
57
44
 
58
- To install a specific version of nw.js use npm with the specific version: `npm install nw@0.12.0`
45
+ Set `nwjs_arch` in `.npmrc` or `NWJS_ARCH` environment variable. Defaults to `process.arch`.
59
46
 
60
- > *Please note:* This npm package version tracks the version of nw.js that will be installed, with an additional build number that is used for revisions to the installer. As such `0.12.0-1` and `0.12.0-2` will both install `nw.js@0.12.0` but the latter has newer changes to the installer.
47
+ ### Specify cache directory:
61
48
 
62
- You may use `npm view nw versions` to view the list of available versions.
49
+ Set `nwjs_cache_dir` in `.npmrc` or `NWJS_ARCH` environment variable. Defaults to `./node_modules/nw`.
63
50
 
64
- ## install a specific build type of nw.js
51
+ ### Specify cache flag:
65
52
 
66
- nw.js has three build types: `normal`, `sdk` and `nacl`. To install a specific build type you may set npm config property `nwjs_build_type`, environment variable `NWJS_BUILD_TYPE` or pass command line option `--nwjs_build_type`:
53
+ Set `nwjs_cache` in `.npmrc` or `NWJS_ARCH` environment variable to keep or delete cached binaries. Defaults to `true`.
67
54
 
68
- ``` shell
69
- npm install nw --nwjs_build_type=sdk
70
- ```
55
+ ### Specify ffmpeg flag:
71
56
 
72
- Setting option in `.npmrc` file (https://www.npmjs.org/doc/files/npmrc.html):
57
+ Set `nwjs_ffmpeg` in `.npmrc` or `NWJS_ARCH` environment variable to toggle downloading [community FFmpeg binaries](https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt). Defaults to `false`.
73
58
 
74
- ```
75
- nwjs_build_type=sdk
76
- ```
59
+ ### Specify Native Addon flag:
77
60
 
78
- Setting environment variable `NWJS_BUILD_TYPE`:
61
+ Set `nwjs_native_addon` in `.npmrc` or `NWJS_NATIVE_ADDON` environment variable to toggle downloading NW.js Node headers. Defaults to `false`.
79
62
 
80
- ``` shell
81
- export NWJS_BUILD_TYPE=sdk
82
- ```
63
+ ### Specify download URL:
83
64
 
84
- You can alternatively install `sdk` build by specifying `-sdk` suffix in version:
65
+ Set `nwjs_urlbase` in `.npmrc`or `NWJS_URLBASE` environment variable. Defaults to `https://dl.nwjs.io`. The file system (`file://`) is also supported (for example, `file:///home/localghost/local_mirror`).
85
66
 
86
- ``` shell
87
- npm install nw@0.13.3-sdk
88
- ```
67
+ ## Usage
89
68
 
90
- You can also run `npm install nw@sdk` to get the latest of published SDK versions. (Note: that may be a beta version.)
69
+ Add a script in your `package.json`:
91
70
 
92
- ## install a specific architecture
71
+ ```json
72
+ {
73
+ "scripts": {
74
+ "start": "nw /path/to/app"
75
+ }
76
+ }
77
+ ```
93
78
 
94
- You may use the environment variable `npm_config_nwjs_process_arch` to override the default architecture (`process.arch`) and to download NW.js built for some other architecture.
79
+ Executing `npm start` runs the NW.js app. Omitting the file path makes NW.js check for valid project in current working directory. You can also call `nw` directly from `node_modules/.bin/nw`.
95
80
 
96
- ## finding the path to the nw.js binary
81
+ ## APIs
97
82
 
98
- If you would like to programmatically retrieve the path to the nw.js binary use:
83
+ ### Find path to the NW.js binary:
99
84
 
100
85
  ``` js
101
- var findpath = require('nw').findpath;
102
- var nwpath = findpath();
103
- // nwpath will equal the path to the binary depending on your environment
86
+ import { findpath } from 'nw';
87
+ var path = findpath();
104
88
  ```
105
89
 
106
- ## finding the path to the chromedriver binary
107
-
108
- If you would like to programmatically retrieve the path to the chromedriver use:
90
+ ## Find the path to the chromedriver binary
109
91
 
110
92
  ``` js
111
- var findpath = require('nw').findpath;
112
- var chromedriver_path = findpath('chromedriver');
113
- // chromedriver_path will equal the path to the binary depending on your environment
93
+ import { findpath } from 'nw';
94
+ var path = findpath('chromedriver');
114
95
  ```
115
96
 
116
- Then you can use that path to run NW.js programmatically. For example, to run in the current script's directory:
97
+ ## Download specific versions independant of installer version
117
98
 
118
99
  ```js
119
- require('child_process').spawn(
120
- require('nw').findpath(),
121
- ['.'].concat( process.argv.slice(2) ),
122
- {
123
- cwd: __dirname,
124
- detached: true,
125
- stdio: 'ignore'
126
- }
127
- ).unref();
128
- ```
129
-
130
- ## retrieve binaries from custom download location or file path
131
-
132
- The installer attempts to download binaries from the default location of `https://dl.nwjs.io/v`. You can override this by setting the npm config property `nwjs_urlbase` on the command line by passing the `--nwjs_urlbase` option:
133
-
134
- ``` shell
135
- npm install nw --nwjs_urlbase=http://my.own.location/somewhere
136
- ```
137
-
138
- or adding it to your `.npmrc` file (https://www.npmjs.org/doc/files/npmrc.html):
139
-
140
- ```
141
- nwjs_urlbase=http://my.own.location/somewhere
142
- ```
143
-
144
- You can alternatively set an environment variable `NWJS_URLBASE`:
100
+ import { get } from 'nw';
145
101
 
146
- ``` shell
147
- export NWJS_URLBASE=http://my.own.location/somewhere
102
+ await get({
103
+ // options
104
+ });
148
105
  ```
149
106
 
150
- The installer supports `file://` URLs to retrieve files from the local filesystem:
107
+ Options:
151
108
 
152
- ``` shell
153
- export NWJS_URLBASE=file:///home/bilbo/my/own/mirror
154
- ```
155
-
156
- ## using a proxy with or without authentication
157
-
158
- If you are behind a proxy server you have to set an environment variable `http_proxy` with proxy servers url:
159
-
160
- ```
161
- export http_proxy="http://username:password@myproxy.com:8080"
162
- ```
163
-
164
- or
165
-
166
- ```
167
- export http_proxy="http://myproxy.com:8080"
168
- ```
109
+ | Name | Type | Default | Description |
110
+ | ---- | ------- | --------- | ----------- |
111
+ | version | `string \| "latest" \| "stable"` | `"latest"` | Runtime version |
112
+ | flavor | `"normal" \| "sdk"` | `"normal"` | Runtime flavor |
113
+ | platform | `"linux" \| "osx" \| "win"` | | Host platform |
114
+ | arch | `"ia32" \| "x64" \| "arm64"` | | Host architecture |
115
+ | 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 |
116
+ | cacheDir | `string` | `"./cache"` | Directory to cache NW binaries |
117
+ | cache | `boolean` | `true`| If true the existing cache is used. Otherwise it removes and redownloads it. |
118
+ | ffmpeg | `boolean` | `false`| If true the chromium ffmpeg is replaced by community version with proprietary codecs. |
119
+ | nodeAddon | `false \| "gyp"` | `false` | Download Node headers |
169
120
 
170
- (However, if the environment variable `https_proxy` is set, then it will be preferred, as [programmed](https://github.com/kevva/get-proxy/blob/master/index.js) in the `get-proxy` package.)
121
+ ## License
171
122
 
172
- ## license
173
- [nw.js](https://github.com/nwjs/nw.js)'s code and this installer use the MIT license.
123
+ [NW.js](https://github.com/nwjs/nw.js)'s code and this installer use the MIT license.
package/package.json CHANGED
@@ -1,23 +1,25 @@
1
1
  {
2
2
  "name": "nw",
3
- "version": "0.85.0",
4
- "description": "A installer for nw.js",
3
+ "version": "0.86.0",
4
+ "description": "An installer for nw.js",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git://github.com/nwjs/npm-installer.git"
8
8
  },
9
- "main": "lib/findpath.js",
9
+ "type": "module",
10
+ "main": "src/index.js",
10
11
  "bin": {
11
- "nw": "bin/nw.js"
12
+ "nw": "src/cli.js"
12
13
  },
13
14
  "scripts": {
14
- "postinstall": "node lib/install.js",
15
- "test": "node --test-reporter=spec --test test/index.js",
16
- "dry-run": "nw ./test/app"
15
+ "postinstall": "node src/postinstall.js",
16
+ "test": "vitest run",
17
+ "demo": "nw ./test/app"
17
18
  },
18
19
  "files": [
20
+ "bin",
19
21
  "lib",
20
- "bin"
22
+ "src"
21
23
  ],
22
24
  "author": {
23
25
  "name": "Kyle Robinson Young",
@@ -31,10 +33,12 @@
31
33
  ],
32
34
  "license": "MIT",
33
35
  "dependencies": {
34
- "cli-progress": "^3.12.0",
35
- "compressing": "^1.10.0",
36
+ "axios": "^1.6.8",
37
+ "commander": "^12.0.0",
36
38
  "semver": "^7.5.4",
37
- "yargs": "^17.7.2"
39
+ "tar": "^6.2.1",
40
+ "yargs": "^17.7.2",
41
+ "yauzl-promise": "^4.0.0"
38
42
  },
39
43
  "keywords": [
40
44
  "nw",
@@ -47,5 +51,9 @@
47
51
  "installer",
48
52
  "desktop",
49
53
  "application"
50
- ]
54
+ ],
55
+ "devDependencies": {
56
+ "selenium-webdriver": "^4.18.1",
57
+ "vitest": "^1.4.0"
58
+ }
51
59
  }
package/src/cli.js ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+
3
+ import process from 'node:process';
4
+
5
+ import { program } from 'commander';
6
+
7
+ import parse from '../src/parse.js';
8
+ import run from '../src/run.js';
9
+
10
+ await cli();
11
+
12
+ async function cli() {
13
+
14
+ program
15
+ .option('--version <string>')
16
+ .option('--flavor <flavor>')
17
+ .option('--platform <platform>')
18
+ .option('--arch <arch>')
19
+ .option('--cacheDir <cacheDir>')
20
+ .argument('<app>')
21
+ .parse(process.argv);
22
+
23
+ let options = program.opts();
24
+ options = await parse(options);
25
+
26
+ await run({
27
+ version: options.version,
28
+ flavor: options.flavor,
29
+ platform: options.platform,
30
+ arch: options.arch,
31
+ cacheDir: options.cacheDir,
32
+ srcDir: program.args[0],
33
+ });
34
+
35
+ }
@@ -0,0 +1,95 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import stream from "node:stream";
4
+
5
+ import tar from "tar";
6
+ import yauzl from "yauzl-promise";
7
+
8
+ import util from "./util.js";
9
+
10
+ /**
11
+ * Decompresses a file at `filePath` to `cacheDir` directory.
12
+ *
13
+ * @param {string} filePath - file path to compressed binary
14
+ * @param {string} cacheDir - directory to decompress into
15
+ */
16
+ export default async function decompress(filePath, cacheDir) {
17
+ if (filePath.endsWith(".zip")) {
18
+ await unzip(filePath, cacheDir);
19
+ } else {
20
+ await tar.extract({
21
+ file: filePath,
22
+ C: cacheDir
23
+ });
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Get file mode from entry. Reference implementation is [here](https://github.com/fpsqdb/zip-lib/blob/ac447d269218d396e05cd7072d0e9cd82b5ec52c/src/unzip.ts#L380).
29
+ *
30
+ * @param {yauzl.Entry} entry - Yauzl entry
31
+ * @return {number} - entry's file mode
32
+ */
33
+ function modeFromEntry(entry) {
34
+ const attr = entry.externalFileAttributes >> 16 || 33188;
35
+
36
+ return [448 /* S_IRWXU */, 56 /* S_IRWXG */, 7 /* S_IRWXO */]
37
+ .map(mask => attr & mask)
38
+ .reduce((a, b) => a + b, attr & 61440 /* S_IFMT */);
39
+ }
40
+
41
+ /**
42
+ * Unzip `zippedFile` to `cacheDir`.
43
+ *
44
+ * @async
45
+ * @function
46
+ * @param {string} zippedFile - file path to .zip file
47
+ * @param {string} cacheDir - directory to unzip in
48
+ * @return {Promise<void>}
49
+ */
50
+ async function unzip(zippedFile, cacheDir) {
51
+ const zip = await yauzl.open(zippedFile);
52
+ let entry = await zip.readEntry();
53
+ const symlinks = []; // Array to hold symbolic link entries
54
+
55
+ while (entry !== null) {
56
+ let entryPathAbs = path.join(cacheDir, entry.filename);
57
+ /* Check if entry is a symbolic link */
58
+ const isSymlink = ((modeFromEntry(entry) & 0o170000) === 0o120000);
59
+
60
+ if (isSymlink) {
61
+ /* Store symlink entries to process later */
62
+ symlinks.push(entry);
63
+ } else {
64
+ /* Handle regular files and directories */
65
+ await fs.promises.mkdir(path.dirname(entryPathAbs), {recursive: true});
66
+ if (!entry.filename.endsWith('/')) { // Skip directories
67
+ const readStream = await entry.openReadStream();
68
+ const writeStream = fs.createWriteStream(entryPathAbs);
69
+ await stream.promises.pipeline(readStream, writeStream);
70
+
71
+ /* Set file permissions after the file has been written */
72
+ const mode = modeFromEntry(entry);
73
+ await fs.promises.chmod(entryPathAbs, mode);
74
+ }
75
+ }
76
+
77
+ /* Read next entry */
78
+ entry = await zip.readEntry();
79
+ }
80
+
81
+ /* Process symbolic links after all other files have been extracted */
82
+ for (const symlinkEntry of symlinks) {
83
+ let entryPathAbs = path.join(cacheDir, symlinkEntry.filename);
84
+ const readStream = await symlinkEntry.openReadStream();
85
+ const chunks = [];
86
+ readStream.on("data", (chunk) => chunks.push(chunk));
87
+ await new Promise(resolve => readStream.on("end", resolve));
88
+ const linkTarget = Buffer.concat(chunks).toString('utf8').trim();
89
+
90
+ const fileExists = await util.fileExists(entryPathAbs);
91
+ if (!fileExists) {
92
+ await fs.promises.symlink(linkTarget, entryPathAbs);
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,27 @@
1
+ import fs from "node:fs";
2
+
3
+ import { beforeAll, describe, it } from "vitest";
4
+
5
+ import decompress from "./decompress.js";
6
+ import request from "./request.js";
7
+
8
+ describe("get/decompress", function () {
9
+
10
+ let tarUrl = "https://dl.nwjs.io/v0.83.0/nwjs-sdk-v0.83.0-linux-x64.tar.gz";
11
+ let zipUrl = "https://dl.nwjs.io/v0.83.0/nwjs-sdk-v0.83.0-osx-x64.zip";
12
+
13
+ beforeAll(async function () {
14
+ await fs.promises.mkdir("./test/fixture/cache", {recursive: true});
15
+
16
+ await request(tarUrl, "./test/fixture/cache/nw.tar.gz");
17
+ await request(zipUrl, "./test/fixture/cache/nw.zip");
18
+ }, Infinity);
19
+
20
+ it("decompresses a Linux tarball", async function () {
21
+ await decompress("./test/fixture/cache/nw.tar.gz", "./test/fixture/cache");
22
+ }, Infinity);
23
+
24
+ it("decompresses a MacOS zip", async function () {
25
+ await decompress("./test/fixture/cache/nw.zip", "./test/fixture/cache");
26
+ }, Infinity);
27
+ });
package/src/ffmpeg.js ADDED
@@ -0,0 +1,38 @@
1
+ import path from "node:path";
2
+
3
+ import request from "./request.js";
4
+
5
+ /**
6
+ * Download community FFmpeg binary from `https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt`.
7
+ *
8
+ * @param {string} downloadUrl - Download server
9
+ * @param {string} version - Runtime version
10
+ * @param {string} platform - NW supported platform
11
+ * @param {string} arch - NW supported architecture
12
+ * @param {string} cacheDir - Directory to store FFmpeg binary
13
+ * @return {Promise<string>} Path of compressed file which containscommunity FFmpeg binary.
14
+ */
15
+ export default async function ffmpeg(downloadUrl, version, platform, arch, cacheDir) {
16
+
17
+ /**
18
+ * URL to download specific FFmpeg binary from.
19
+ *
20
+ * @type {string}
21
+ */
22
+ const url = [
23
+ downloadUrl,
24
+ version,
25
+ `${version}-${platform}-${arch}.zip`,
26
+ ].join('/');
27
+
28
+ /**
29
+ * Absolute path of compressed file which contains FFmpeg binary.
30
+ */
31
+ const ffmpegFileAbs = path.resolve(
32
+ cacheDir,
33
+ `ffmpeg-${version}-${platform}-${arch}.zip`,
34
+ );
35
+ await request(url, ffmpegFileAbs);
36
+
37
+ return ffmpegFileAbs;
38
+ }
@@ -0,0 +1,31 @@
1
+ import fs from "node:fs";
2
+ import process from "node:process";
3
+
4
+ import { afterEach, beforeAll, describe, expect, it } from "vitest";
5
+
6
+ import ffmpeg from "./ffmpeg.js";
7
+ import util from "./util.js";
8
+
9
+ describe("get/ffmpeg", function () {
10
+
11
+ let ffmpegFile = '';
12
+
13
+ afterEach(function () {
14
+ fs.promises.rm(ffmpegFile, { recursive: true, force: true });
15
+ });
16
+
17
+ beforeAll(async function () {
18
+ await fs.promises.mkdir("./test/fixture", { recursive: true });
19
+ });
20
+
21
+ it("downloades community prebuild FFmpeg for specifc platform", async function () {
22
+ ffmpegFile = await ffmpeg(
23
+ "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download",
24
+ "0.83.0",
25
+ util.PLATFORM_KV[process.platform],
26
+ util.ARCH_KV[process.arch],
27
+ "./test/fixture"
28
+ );
29
+ expect(util.fileExists(ffmpegFile)).resolves.toBe(true);
30
+ }, Infinity);
31
+ });