nw 0.111.0-sdk → 0.111.1-sdk
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/package.json +3 -1
- package/src/cli.js +11 -11
- package/src/index.js +4 -3
- package/src/parse.js +19 -18
- package/src/postinstall.js +25 -21
- package/src/util.js +12 -12
- package/src/decompress.js +0 -96
- package/src/ffmpeg.js +0 -38
- package/src/get.js +0 -228
- package/src/node.js +0 -50
- package/src/nw.js +0 -60
- package/src/request.js +0 -27
- package/src/run.js +0 -79
- package/src/verify.js +0 -47
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nw",
|
|
3
|
-
"version": "0.111.
|
|
3
|
+
"version": "0.111.1-sdk",
|
|
4
4
|
"description": "An installer for NW.js",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
],
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@nwutils/getter": "^0.2.4",
|
|
35
|
+
"@nwutils/runner": "^0.2.3",
|
|
34
36
|
"axios": "^1.15.2",
|
|
35
37
|
"commander": "^14.0.3",
|
|
36
38
|
"semver": "^7.7.4",
|
package/src/cli.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import process from
|
|
3
|
+
import process from "node:process";
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import run from "@nwutils/runner";
|
|
6
|
+
import { program } from "commander";
|
|
6
7
|
|
|
7
|
-
import parse from
|
|
8
|
-
import run from '../src/run.js';
|
|
8
|
+
import parse from "../src/parse.js";
|
|
9
9
|
|
|
10
10
|
await cli();
|
|
11
11
|
|
|
12
12
|
async function cli() {
|
|
13
13
|
|
|
14
14
|
program
|
|
15
|
-
.argument(
|
|
16
|
-
.option(
|
|
17
|
-
.option(
|
|
18
|
-
.option(
|
|
19
|
-
.option(
|
|
20
|
-
.option(
|
|
15
|
+
.argument("[app]", "File path to project", ".")
|
|
16
|
+
.option("--version <string>", "NW.js version")
|
|
17
|
+
.option("--flavor <flavor>", "NW.js flavor")
|
|
18
|
+
.option("--platform <platform>", "Host platform")
|
|
19
|
+
.option("--arch <arch>", "Host architecture")
|
|
20
|
+
.option("--cacheDir <cacheDir>", "File path to cache directory")
|
|
21
21
|
.allowExcessArguments(true)
|
|
22
22
|
.allowUnknownOption() // this allows chromium and node options to be passed through to the nwjs binary
|
|
23
23
|
.parse(process.argv);
|
|
@@ -32,7 +32,7 @@ async function cli() {
|
|
|
32
32
|
arch: options.arch,
|
|
33
33
|
cacheDir: options.cacheDir,
|
|
34
34
|
srcDir: program.args[0],
|
|
35
|
-
|
|
35
|
+
argv: program.args.slice(1),
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
}
|
package/src/index.js
CHANGED
package/src/parse.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import path from
|
|
3
|
-
import process from
|
|
4
|
-
import url from
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import url from "node:url";
|
|
5
5
|
|
|
6
|
-
import semver from
|
|
6
|
+
import semver from "semver";
|
|
7
7
|
|
|
8
|
-
import util from
|
|
8
|
+
import util from "../src/util.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @typedef {object} ParseOptions
|
|
@@ -33,31 +33,32 @@ export default async function parse(options) {
|
|
|
33
33
|
/**
|
|
34
34
|
* @type {fs.PathLike}
|
|
35
35
|
*/
|
|
36
|
-
const nodeManifestPath = path.resolve(__dirname,
|
|
36
|
+
const nodeManifestPath = path.resolve(__dirname, "..", "package.json");
|
|
37
37
|
/**
|
|
38
38
|
* @type {object}
|
|
39
39
|
*/
|
|
40
|
-
const nodeManifest = JSON.parse(await fs.promises.readFile(nodeManifestPath, { encoding:
|
|
40
|
+
const nodeManifest = JSON.parse(await fs.promises.readFile(nodeManifestPath, { encoding: "utf-8" }));
|
|
41
41
|
options.version = options.version ?? nodeManifest.version;
|
|
42
42
|
const parsedVersion = semver.parse(options.version);
|
|
43
43
|
options.version = [
|
|
44
44
|
parsedVersion.major,
|
|
45
45
|
parsedVersion.minor,
|
|
46
46
|
parsedVersion.patch
|
|
47
|
-
].join(
|
|
48
|
-
options.flavor = options.flavor || process.env.npm_config_nwjs_build_type || process.env.NWJS_BUILD_TYPE ||
|
|
49
|
-
if (String(parsedVersion?.prerelease[0]).endsWith(
|
|
50
|
-
options.flavor =
|
|
47
|
+
].join(".");
|
|
48
|
+
options.flavor = options.flavor || process.env.npm_config_nwjs_build_type || process.env.NWJS_BUILD_TYPE || "normal";
|
|
49
|
+
if (String(parsedVersion?.prerelease[0]).endsWith("sdk")) {
|
|
50
|
+
options.flavor = "sdk";
|
|
51
51
|
}
|
|
52
52
|
options.platform = options.platform || util.PLATFORM_KV[process.env.npm_config_nwjs_platform || process.env.NWJS_PLATFORM || process.platform];
|
|
53
53
|
options.arch = options.arch || util.ARCH_KV[process.env.npm_config_nwjs_process_arch || process.env.NWJS_ARCH || process.arch];
|
|
54
|
-
options.downloadUrl = options.downloadUrl || process.env.npm_config_nwjs_urlbase || process.env.NWJS_URLBASE ||
|
|
55
|
-
options.
|
|
54
|
+
options.downloadUrl = options.downloadUrl || process.env.npm_config_nwjs_urlbase || process.env.NWJS_URLBASE || "https://dl.nwjs.io";
|
|
55
|
+
options.manifestUrl = options.manifestUrl || process.env.npm_config_nwjs_manifest_urlbase || process.env.NWJS_MANIFEST_URLBASE || "https://nwjs.io/versions.json";
|
|
56
|
+
options.cacheDir = options.npm_config_nwjs_urlbase || process.env.npm_config_nwjs_cache_dir || process.env.NWJS_CACHE_DIR || path.resolve(__dirname, "..");
|
|
56
57
|
options.srcDir = options.srcDir || process.cwd();
|
|
57
|
-
options.cache ??= process.env.npm_config_nwjs_cache !==
|
|
58
|
-
options.ffmpeg ??= process.env.npm_config_nwjs_ffmpeg ===
|
|
59
|
-
options.nativeAddon ??= (process.env.npm_config_nwjs_native_addon ===
|
|
60
|
-
options.unref ??= process.env.npm_config_nwjs_unref ===
|
|
58
|
+
options.cache ??= process.env.npm_config_nwjs_cache !== "false" && process.env.NWJS_CACHE !== "false";
|
|
59
|
+
options.ffmpeg ??= process.env.npm_config_nwjs_ffmpeg === "true" || process.env.NWJS_FFMPEG === "true";
|
|
60
|
+
options.nativeAddon ??= (process.env.npm_config_nwjs_native_addon === "gyp" || process.env.NWJS_NATIVE_ADDON === "gyp") ? "gyp" : false;
|
|
61
|
+
options.unref ??= process.env.npm_config_nwjs_unref === "true" || process.env.NWJS_UNREF === "true";
|
|
61
62
|
|
|
62
63
|
return { ...options };
|
|
63
64
|
}
|
package/src/postinstall.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import process from
|
|
3
|
-
import path from
|
|
4
|
-
import url from
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import url from "node:url";
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import get from "@nwutils/getter";
|
|
7
|
+
import semver from "semver";
|
|
7
8
|
|
|
8
|
-
import
|
|
9
|
-
import util from './util.js';
|
|
9
|
+
import util from "./util.js";
|
|
10
10
|
|
|
11
11
|
await postinstall()
|
|
12
12
|
.catch((error) => {
|
|
13
|
-
if (error.code ===
|
|
14
|
-
console.error(
|
|
13
|
+
if (error.code === "EPERM") {
|
|
14
|
+
console.error("Unable to create symlink since user did not run as Administrator.");
|
|
15
15
|
} else {
|
|
16
16
|
console.error(error)
|
|
17
17
|
}
|
|
@@ -22,7 +22,7 @@ async function postinstall() {
|
|
|
22
22
|
/**
|
|
23
23
|
* @type {fs.PathLike}
|
|
24
24
|
*/
|
|
25
|
-
const nodeManifestPath = path.resolve(__dirname,
|
|
25
|
+
const nodeManifestPath = path.resolve(__dirname, "..", "package.json");
|
|
26
26
|
/**
|
|
27
27
|
* @type {object}
|
|
28
28
|
*/
|
|
@@ -32,9 +32,9 @@ async function postinstall() {
|
|
|
32
32
|
parsedVersion.major,
|
|
33
33
|
parsedVersion.minor,
|
|
34
34
|
parsedVersion.patch
|
|
35
|
-
].join(
|
|
35
|
+
].join(".");
|
|
36
36
|
|
|
37
|
-
let flavor = process.env.npm_config_nwjs_build_type || process.env.NWJS_BUILD_TYPE ||
|
|
37
|
+
let flavor = process.env.npm_config_nwjs_build_type || process.env.NWJS_BUILD_TYPE || "normal";
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* If `parsedVersion` is `null`, then prerelease is `"null"`.
|
|
@@ -45,17 +45,19 @@ async function postinstall() {
|
|
|
45
45
|
*/
|
|
46
46
|
const prerelease = String(parsedVersion?.prerelease[0]);
|
|
47
47
|
/* Check build flavor and slice that off the `version`. */
|
|
48
|
-
if (prerelease.endsWith(
|
|
49
|
-
flavor =
|
|
48
|
+
if (prerelease.endsWith("sdk")) {
|
|
49
|
+
flavor = "sdk";
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const platform = util.PLATFORM_KV[process.env.npm_config_nwjs_platform || process.env.NWJS_PLATFORM || process.platform];
|
|
53
53
|
const arch = util.ARCH_KV[process.env.npm_config_nwjs_process_arch || process.env.NWJS_ARCH || process.arch];
|
|
54
|
-
const downloadUrl = process.env.npm_config_nwjs_urlbase || process.env.NWJS_URLBASE ||
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
54
|
+
const downloadUrl = process.env.npm_config_nwjs_urlbase || process.env.NWJS_URLBASE || "https://dl.nwjs.io";
|
|
55
|
+
const manifestUrl = process.env.npm_config_nwjs_manifest_url || process.env.NWJS_MANIFEST_URL || "https://nwjs.io/versions.json";
|
|
56
|
+
const cacheDir = process.env.npm_config_nwjs_cache_dir || process.env.NWJS_CACHE_DIR || ".";
|
|
57
|
+
const cache = process.env.npm_config_nwjs_cache !== "false" && process.env.NWJS_CACHE !== "false";
|
|
58
|
+
const ffmpeg = process.env.npm_config_nwjs_ffmpeg === "true" || process.env.NWJS_FFMPEG === "true";
|
|
59
|
+
const nativeAddon = (process.env.npm_config_nwjs_native_addon === "gyp" || process.env.NWJS_NATIVE_ADDON === "gyp") ? "gyp" : false;
|
|
60
|
+
const shaSum = process.env.npm_config_nwjs_shasum !== "false" && process.env.NWJS_SHASUM !== "false";
|
|
59
61
|
|
|
60
62
|
await get({
|
|
61
63
|
version,
|
|
@@ -63,9 +65,11 @@ async function postinstall() {
|
|
|
63
65
|
platform,
|
|
64
66
|
arch,
|
|
65
67
|
downloadUrl,
|
|
68
|
+
manifestUrl,
|
|
66
69
|
cacheDir,
|
|
67
70
|
cache,
|
|
68
|
-
ffmpeg
|
|
69
|
-
nativeAddon
|
|
71
|
+
ffmpeg,
|
|
72
|
+
nativeAddon,
|
|
73
|
+
shaSum,
|
|
70
74
|
});
|
|
71
75
|
}
|
package/src/util.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import path from
|
|
3
|
-
import process from
|
|
4
|
-
import url from
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import url from "node:url";
|
|
5
5
|
|
|
6
|
-
import parse from
|
|
6
|
+
import parse from "./parse.js";
|
|
7
7
|
|
|
8
8
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
9
9
|
|
|
@@ -44,18 +44,18 @@ const EXE_NAME = {
|
|
|
44
44
|
/**
|
|
45
45
|
* Get the platform dependant path of the NW.js or ChromeDriver binary.
|
|
46
46
|
*
|
|
47
|
-
* @param {
|
|
47
|
+
* @param {"nwjs" | "chromedriver" | "all"} Path to NW.js or Chromedriver executable.
|
|
48
48
|
* @return {Promise<string>}
|
|
49
49
|
*/
|
|
50
|
-
async function findpath(executable =
|
|
50
|
+
async function findpath(executable = "nwjs", options = {}) {
|
|
51
51
|
options = await parse(options);
|
|
52
|
-
const nwDir = path.resolve(__dirname,
|
|
52
|
+
const nwDir = path.resolve(__dirname, "..", `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`);
|
|
53
53
|
/**
|
|
54
54
|
* File path to executable.
|
|
55
55
|
*
|
|
56
56
|
* @type {string}
|
|
57
57
|
*/
|
|
58
|
-
let binPath =
|
|
58
|
+
let binPath = "";
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* Get the platform dependant path of the NW.js directory containing everything.
|
|
@@ -78,11 +78,11 @@ async function findpath(executable = 'nwjs', options = {}) {
|
|
|
78
78
|
binPath = path.resolve(nwDir, `chromedriver${process.platform === "win32" ? ".exe" : ""}`);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
if (executable ===
|
|
81
|
+
if (executable === "nwjs") {
|
|
82
82
|
findNwjs();
|
|
83
|
-
} else if (executable ===
|
|
83
|
+
} else if (executable === "chromedriver") {
|
|
84
84
|
findChromeDriver();
|
|
85
|
-
} else if (executable ===
|
|
85
|
+
} else if (executable === "all") {
|
|
86
86
|
findDir();
|
|
87
87
|
} else {
|
|
88
88
|
console.error(`[ ERROR ] Expected nwjs or chromedriver, got ${executable}.`);
|
package/src/decompress.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import stream from "node:stream";
|
|
4
|
-
|
|
5
|
-
import * as 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
|
-
await zip.close();
|
|
96
|
-
}
|
package/src/ffmpeg.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
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
|
-
}
|
package/src/get.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import url from 'node:url';
|
|
4
|
-
|
|
5
|
-
import decompress from "./decompress.js";
|
|
6
|
-
import ffmpeg from "./ffmpeg.js";
|
|
7
|
-
import node from "./node.js";
|
|
8
|
-
import nw from "./nw.js";
|
|
9
|
-
import verify from "./verify.js";
|
|
10
|
-
|
|
11
|
-
import util from "./util.js";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {object} GetOptions
|
|
15
|
-
* @property {string | "latest" | "stable" | "lts"} [version = "latest"] Runtime version
|
|
16
|
-
* @property {"normal" | "sdk"} [flavor = "normal"] Build flavor
|
|
17
|
-
* @property {"linux" | "osx" | "win"} [platform] Target platform
|
|
18
|
-
* @property {"ia32" | "x64" | "arm64"} [arch] Target arch
|
|
19
|
-
* @property {string} [downloadUrl = "https://dl.nwjs.io"] Download server.
|
|
20
|
-
* @property {string} [cacheDir = "./cache"] Cache directory
|
|
21
|
-
* @property {boolean} [cache = true] If false, remove cache and redownload.
|
|
22
|
-
* @property {boolean} [ffmpeg = false] If true, ffmpeg is not downloaded.
|
|
23
|
-
* @property {false | "gyp"} [nativeAddon = false] Rebuild native modules
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Get binaries.
|
|
28
|
-
*
|
|
29
|
-
* @async
|
|
30
|
-
* @function
|
|
31
|
-
* @param {GetOptions} options Get mode options
|
|
32
|
-
* @return {Promise<void>}
|
|
33
|
-
*/
|
|
34
|
-
async function get(options) {
|
|
35
|
-
|
|
36
|
-
const uri = new url.URL(options.downloadUrl);
|
|
37
|
-
|
|
38
|
-
/* Download server is the cached directory. */
|
|
39
|
-
if (uri.protocol === 'file:') {
|
|
40
|
-
options.cacheDir = path.resolve(decodeURIComponent(options.downloadUrl.slice('file://'.length)));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* If `options.cacheDir` exists, then `true`. Otherwise, it is `false`.
|
|
45
|
-
*
|
|
46
|
-
* @type {boolean}
|
|
47
|
-
*/
|
|
48
|
-
const cacheDirExists = await util.fileExists(options.cacheDir);
|
|
49
|
-
if (cacheDirExists === false) {
|
|
50
|
-
await fs.promises.mkdir(options.cacheDir, { recursive: true });
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* File path to compressed binary.
|
|
55
|
-
*
|
|
56
|
-
* @type {string}
|
|
57
|
-
*/
|
|
58
|
-
let nwFilePath = path.resolve(
|
|
59
|
-
options.cacheDir,
|
|
60
|
-
`nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}.${options.platform === "linux" ? "tar.gz" : "zip"
|
|
61
|
-
}`,
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* File path to directory which contain NW.js and related binaries.
|
|
66
|
-
*
|
|
67
|
-
* @type {string}
|
|
68
|
-
*/
|
|
69
|
-
let nwDirPath = path.resolve(
|
|
70
|
-
options.cacheDir,
|
|
71
|
-
`nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform}-${options.arch}`,
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
// If `options.cache` is false, then remove the compressed binary.
|
|
75
|
-
if (options.cache === false) {
|
|
76
|
-
await fs.promises.rm(nwFilePath, {
|
|
77
|
-
recursive: true,
|
|
78
|
-
force: true,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// We remove the nwDir to prevent the edge case where you download with ffmpeg flag enabled
|
|
83
|
-
// but want a subsequent build with ffmpeg flag disabled. By removing the directory and
|
|
84
|
-
// decompressing it again, we prevent the community ffmpeg files from being left over.
|
|
85
|
-
// This is important since the community ffmpeg builds have specific licensing constraints.
|
|
86
|
-
await fs.promises.rm(nwDirPath, { recursive: true, force: true });
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* If the compressed binary exists, then `true`. Otherwise, it is `false`.
|
|
90
|
-
*
|
|
91
|
-
* @type {boolean}
|
|
92
|
-
*/
|
|
93
|
-
const nwFilePathExists = await util.fileExists(nwFilePath);
|
|
94
|
-
if (nwFilePathExists === false) {
|
|
95
|
-
nwFilePath = await nw(options.downloadUrl, options.version, options.flavor, options.platform, options.arch, options.cacheDir);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
await decompress(nwFilePath, options.cacheDir);
|
|
99
|
-
|
|
100
|
-
await verify(
|
|
101
|
-
`${options.downloadUrl}/v${options.version}/SHASUMS256.txt`,
|
|
102
|
-
`${options.cacheDir}/shasum/${options.version}.txt`,
|
|
103
|
-
options.cacheDir,
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
await fs.promises.symlink(nwDirPath, './nwjs', );
|
|
107
|
-
|
|
108
|
-
if (options.ffmpeg === true) {
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* File path to compressed binary which contains community FFmpeg binary.
|
|
112
|
-
*
|
|
113
|
-
* @type {string}
|
|
114
|
-
*/
|
|
115
|
-
let ffmpegFilePath = path.resolve(
|
|
116
|
-
options.cacheDir,
|
|
117
|
-
`ffmpeg-${options.version}-${options.platform}-${options.arch}.zip`,
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
// If `options.cache` is false, then remove the compressed binary.
|
|
121
|
-
if (options.cache === false) {
|
|
122
|
-
await fs.promises.rm(ffmpegFilePath, {
|
|
123
|
-
recursive: true,
|
|
124
|
-
force: true,
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* If the compressed binary exists, then `true`. Otherwise, it is `false`.
|
|
130
|
-
*
|
|
131
|
-
* @type {boolean}
|
|
132
|
-
*/
|
|
133
|
-
const ffmpegFilePathExists = await util.fileExists(ffmpegFilePath);
|
|
134
|
-
if (ffmpegFilePathExists === false) {
|
|
135
|
-
// Do not update the options.downloadUrl with the ffmpeg URL here. Doing so would lead to error when options.ffmpeg and options.nativeAddon are both enabled.
|
|
136
|
-
const downloadUrl =
|
|
137
|
-
"https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download";
|
|
138
|
-
ffmpegFilePath = await ffmpeg(downloadUrl, options.version, options.platform, options.arch, options.cacheDir);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
await decompress(ffmpegFilePath, options.cacheDir);
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Platform dependant file name of FFmpeg binary.
|
|
145
|
-
*
|
|
146
|
-
* @type {string}
|
|
147
|
-
*/
|
|
148
|
-
let ffmpegFileName = "";
|
|
149
|
-
|
|
150
|
-
if (options.platform === "linux") {
|
|
151
|
-
ffmpegFileName = "libffmpeg.so";
|
|
152
|
-
} else if (options.platform === "win") {
|
|
153
|
-
ffmpegFileName = "ffmpeg.dll";
|
|
154
|
-
} else if (options.platform === "osx") {
|
|
155
|
-
ffmpegFileName = "libffmpeg.dylib";
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* File path to platform specific FFmpeg file.
|
|
160
|
-
*
|
|
161
|
-
* @type {string}
|
|
162
|
-
*/
|
|
163
|
-
let ffmpegBinaryPath = path.resolve(options.cacheDir, ffmpegFileName);
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* File path of where FFmpeg will be copied to.
|
|
167
|
-
*
|
|
168
|
-
* @type {string}
|
|
169
|
-
*/
|
|
170
|
-
let ffmpegBinaryDest = "";
|
|
171
|
-
|
|
172
|
-
if (options.platform === "linux") {
|
|
173
|
-
ffmpegBinaryDest = path.resolve(nwDirPath, "lib", ffmpegFileName);
|
|
174
|
-
} else if (options.platform === "win") {
|
|
175
|
-
ffmpegBinaryDest = path.resolve(nwDirPath, ffmpegFileName);
|
|
176
|
-
} else if (options.platform === "osx") {
|
|
177
|
-
ffmpegBinaryDest = path.resolve(
|
|
178
|
-
nwDirPath,
|
|
179
|
-
"nwjs.app",
|
|
180
|
-
"Contents",
|
|
181
|
-
"Frameworks",
|
|
182
|
-
"nwjs Framework.framework",
|
|
183
|
-
"Versions",
|
|
184
|
-
"Current",
|
|
185
|
-
ffmpegFileName,
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
await fs.promises.copyFile(ffmpegBinaryPath, ffmpegBinaryDest);
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (options.nativeAddon === "gyp") {
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* File path to NW'js Node headers tarball.
|
|
197
|
-
*
|
|
198
|
-
* @type {string}
|
|
199
|
-
*/
|
|
200
|
-
let nodeFilePath = path.resolve(
|
|
201
|
-
options.cacheDir,
|
|
202
|
-
`headers-v${options.version}.tar.gz`,
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
// If `options.cache` is false, then remove the compressed binary.
|
|
206
|
-
if (options.cache === false) {
|
|
207
|
-
await fs.promises.rm(nodeFilePath, {
|
|
208
|
-
recursive: true,
|
|
209
|
-
force: true,
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* If the compressed binary exists, then `true`. Otherwise, it is `false`.
|
|
215
|
-
*
|
|
216
|
-
* @type {boolean}
|
|
217
|
-
*/
|
|
218
|
-
const nodeFilePathExists = await util.fileExists(nodeFilePath);
|
|
219
|
-
if (nodeFilePathExists === false) {
|
|
220
|
-
nodeFilePath = await node(options.downloadUrl, options.version, options.cacheDir);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
await decompress(nodeFilePath, options.cacheDir);
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export default get;
|
package/src/node.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
|
-
import request from "./request.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Download NW.js's Node.js headers.
|
|
7
|
-
*
|
|
8
|
-
* @param {string} downloadUrl - Download server
|
|
9
|
-
* @param {string} version - Runtime version
|
|
10
|
-
* @param {string} cacheDir - Directory to store NW binaries
|
|
11
|
-
* @return {Promise<string>} - path of compressed file which contains the Node headers.
|
|
12
|
-
*/
|
|
13
|
-
export default async function nw(downloadUrl, version, cacheDir) {
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Name of directory which contains Node headers.
|
|
17
|
-
*
|
|
18
|
-
* @type {string}
|
|
19
|
-
*/
|
|
20
|
-
const nodeDir = `node-v${version}`;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Name of compressed file which contains Node headers.
|
|
24
|
-
*
|
|
25
|
-
* @type {string}
|
|
26
|
-
*/
|
|
27
|
-
const nwFile = `${nodeDir}.tar.gz`
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* URL to download specific Node headers from.
|
|
31
|
-
*
|
|
32
|
-
* @type {string}
|
|
33
|
-
*/
|
|
34
|
-
const url = [
|
|
35
|
-
downloadUrl,
|
|
36
|
-
`v${version}`,
|
|
37
|
-
`nw-headers-v${version}.tar.gz`
|
|
38
|
-
].join('/');
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Absolute path of compressed file which contains Node headers.
|
|
42
|
-
*/
|
|
43
|
-
const nwFileAbs = path.resolve(
|
|
44
|
-
cacheDir,
|
|
45
|
-
nwFile
|
|
46
|
-
);
|
|
47
|
-
await request(url, nwFileAbs);
|
|
48
|
-
|
|
49
|
-
return nwFileAbs;
|
|
50
|
-
}
|
package/src/nw.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
|
|
3
|
-
import request from "./request.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Download NW.js binary.
|
|
7
|
-
*
|
|
8
|
-
* @param {string} downloadUrl - Download server
|
|
9
|
-
* @param {string} version - Runtime version
|
|
10
|
-
* @param {string} flavor - Runtime build flavor
|
|
11
|
-
* @param {string} platform - NW supported platform
|
|
12
|
-
* @param {string} arch - NW supported architecture
|
|
13
|
-
* @param {string} cacheDir - Directory to store NW binaries
|
|
14
|
-
* @return {Promise<string>} - path of compressed file which contains NW.js binaries.
|
|
15
|
-
*/
|
|
16
|
-
export default async function nw(downloadUrl, version, flavor, platform, arch, cacheDir) {
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Name of directory which contains NW.js binaries.
|
|
20
|
-
*
|
|
21
|
-
* @type {string}
|
|
22
|
-
*/
|
|
23
|
-
const nwDir = [
|
|
24
|
-
`nwjs`,
|
|
25
|
-
flavor === 'sdk' ? '-sdk' : '',
|
|
26
|
-
`-v${version}-${platform}-${arch}`,
|
|
27
|
-
].join('');
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Name of compressed file which contains NW.js binaries.
|
|
31
|
-
*
|
|
32
|
-
* @type {string}
|
|
33
|
-
*/
|
|
34
|
-
const nwFile = [
|
|
35
|
-
nwDir,
|
|
36
|
-
platform === 'linux' ? "tar.gz" : "zip"
|
|
37
|
-
].join('.');
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* URL to download specific NW.js binary from.
|
|
41
|
-
*
|
|
42
|
-
* @type {string}
|
|
43
|
-
*/
|
|
44
|
-
const url = [
|
|
45
|
-
downloadUrl,
|
|
46
|
-
`v${version}`,
|
|
47
|
-
nwFile,
|
|
48
|
-
].join('/');
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Absolute path of compressed file which contains NW.js binaries.
|
|
52
|
-
*/
|
|
53
|
-
const nwFileAbs = path.resolve(
|
|
54
|
-
cacheDir,
|
|
55
|
-
nwFile
|
|
56
|
-
);
|
|
57
|
-
await request(url, nwFileAbs);
|
|
58
|
-
|
|
59
|
-
return nwFileAbs;
|
|
60
|
-
}
|
package/src/request.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import stream from "node:stream";
|
|
3
|
-
|
|
4
|
-
import axios from "axios";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Download from `url`.
|
|
8
|
-
*
|
|
9
|
-
* @async
|
|
10
|
-
* @function
|
|
11
|
-
*
|
|
12
|
-
* @param {string} url - Download server
|
|
13
|
-
* @param {string} filePath - file path of downloaded content
|
|
14
|
-
* @return {Promise<void>}
|
|
15
|
-
*/
|
|
16
|
-
export default async function request(url, filePath) {
|
|
17
|
-
|
|
18
|
-
const writeStream = fs.createWriteStream(filePath);
|
|
19
|
-
|
|
20
|
-
const response = await axios({
|
|
21
|
-
method: "get",
|
|
22
|
-
url: url,
|
|
23
|
-
responseType: "stream"
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
await stream.promises.pipeline(response.data, writeStream);
|
|
27
|
-
}
|
package/src/run.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import child_process from "node:child_process";
|
|
2
|
-
import console from "node:console";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import process from "node:process";
|
|
5
|
-
|
|
6
|
-
import util from "./util.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @typedef {object} RunOptions
|
|
10
|
-
* @property {string | "latest" | "stable" | "lts"} [version = "latest"] Runtime version
|
|
11
|
-
* @property {"normal" | "sdk"} [flavor = "normal"] Build flavor
|
|
12
|
-
* @property {"linux" | "osx" | "win"} [platform] Target platform
|
|
13
|
-
* @property {"ia32" | "x64" | "arm64"} [arch] Target arch
|
|
14
|
-
* @property {string} [srcDir = "./src"] Source directory
|
|
15
|
-
* @property {string} [cacheDir = "./cache"] Cache directory
|
|
16
|
-
* @property {boolean} [unref = false] Unref the child process and unblock the caller
|
|
17
|
-
* @property {string[]} [args = []] Command line arguments
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Run NW.js application.
|
|
22
|
-
*
|
|
23
|
-
* @async
|
|
24
|
-
* @function
|
|
25
|
-
*
|
|
26
|
-
* @param {RunOptions} options Run mode options
|
|
27
|
-
* @return {Promise<void>}
|
|
28
|
-
*/
|
|
29
|
-
async function run({
|
|
30
|
-
version = "latest",
|
|
31
|
-
flavor = "normal",
|
|
32
|
-
platform = util.PLATFORM_KV[process.platform],
|
|
33
|
-
arch = util.ARCH_KV[process.arch],
|
|
34
|
-
srcDir = ".",
|
|
35
|
-
cacheDir = "./cache",
|
|
36
|
-
unref = false,
|
|
37
|
-
args = [],
|
|
38
|
-
}) {
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
if (util.EXE_NAME[platform] === undefined) {
|
|
42
|
-
throw new Error("Unsupported platform.");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const nwDir = path.resolve(
|
|
46
|
-
cacheDir,
|
|
47
|
-
`nwjs${flavor === "sdk" ? "-sdk" : ""}-v${version}-${platform}-${arch}`,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
return new Promise((res, rej) => {
|
|
51
|
-
const nwProcess = child_process.spawn(
|
|
52
|
-
path.resolve(nwDir, util.EXE_NAME[platform]),
|
|
53
|
-
[srcDir, ...args],
|
|
54
|
-
{ stdio: "inherit" },
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
nwProcess.on("close", () => {
|
|
58
|
-
res();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
nwProcess.on("message", (message) => {
|
|
62
|
-
console.log(message);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
nwProcess.on("error", (error) => {
|
|
66
|
-
console.error(error);
|
|
67
|
-
rej(error);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
if (unref) {
|
|
71
|
-
nwProcess.unref();
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error(error);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default run;
|
package/src/verify.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
|
|
5
|
-
import request from './request.js';
|
|
6
|
-
import util from './util.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Verify the SHA256 checksum of downloaded artifacts.
|
|
10
|
-
*
|
|
11
|
-
* @param {string} shaUrl - URL to get the shasum text file from.
|
|
12
|
-
* @param {string} shaOut - File path to shasum text file.
|
|
13
|
-
* @param {string} cacheDir - File path to cache directory.
|
|
14
|
-
* @throws {Error}
|
|
15
|
-
* @returns {Promise<boolean>}
|
|
16
|
-
*/
|
|
17
|
-
export default async function verify(shaUrl, shaOut, cacheDir) {
|
|
18
|
-
const shaOutExists = await util.fileExists(shaOut);
|
|
19
|
-
|
|
20
|
-
if (shaOutExists === false) {
|
|
21
|
-
/* Create directory if does not exist. */
|
|
22
|
-
await fs.promises.mkdir(path.dirname(shaOut), { recursive: true });
|
|
23
|
-
|
|
24
|
-
/* Download SHASUM text file. */
|
|
25
|
-
await request(shaUrl, shaOut);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/* Read SHASUM text file */
|
|
29
|
-
const shasum = await fs.promises.readFile(shaOut, { encoding: 'utf-8' });
|
|
30
|
-
const shasums = shasum.trim().split('\n');
|
|
31
|
-
for await (const line of shasums) {
|
|
32
|
-
const [storedSha, filePath] = line.split(' ');
|
|
33
|
-
const relativeFilePath = path.resolve(cacheDir, filePath);
|
|
34
|
-
const relativefilePathExists = await util.fileExists(relativeFilePath);
|
|
35
|
-
if (relativefilePathExists) {
|
|
36
|
-
const fileBuffer = await fs.promises.readFile(relativeFilePath);
|
|
37
|
-
const hash = crypto.createHash('sha256');
|
|
38
|
-
hash.update(fileBuffer);
|
|
39
|
-
const generatedSha = hash.digest('hex');
|
|
40
|
-
if (storedSha !== generatedSha) {
|
|
41
|
-
throw new Error('SHA256 checksums do not match.');
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return true;
|
|
47
|
-
}
|