nw-builder 4.16.2 → 4.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +8 -10
- package/src/bld.js +1 -1
- package/src/cli.js +1 -1
- package/src/index.js +2 -2
- package/src/util.js +19 -13
- package/src/get/decompress.js +0 -94
- package/src/get/ffmpeg.js +0 -36
- package/src/get/index.js +0 -219
- package/src/get/node.js +0 -46
- package/src/get/nw.js +0 -56
- package/src/get/request.js +0 -36
- package/src/get/verify.js +0 -59
package/README.md
CHANGED
|
@@ -194,7 +194,7 @@ Options
|
|
|
194
194
|
| platform | `"linux" \| "osx" \| "win"` | | Host platform |
|
|
195
195
|
| arch | `"ia32" \| "x64" \| "arm64"` | | Host architecture |
|
|
196
196
|
| 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`) |
|
|
197
|
-
| manifestUrl | `"https://nwjs.io/versions.json" \| "https://raw.githubusercontent.com/nwutils/nw-builder/main/src/util/osx.arm.versions.json"` | `"https://nwjs.io/versions.json"` | Versions manifest |
|
|
197
|
+
| manifestUrl | `"https://nwjs.io/versions.json" \| "https://raw.githubusercontent.com/nwutils/nw-builder/main/src/util/osx.arm.versions.json"` | `"https://nwjs.io/versions.json"` | Versions manifest URI, gotten via https or local file |
|
|
198
198
|
| cacheDir | `string` | `"./cache"` | Directory to cache NW binaries |
|
|
199
199
|
| cache | `boolean` | `true`| If true the existing cache is used. Otherwise it removes and redownloads it. |
|
|
200
200
|
| ffmpeg | `boolean` | `false`| If true the chromium ffmpeg is replaced by community version with proprietary codecs. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nw-builder",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.1",
|
|
4
4
|
"description": "Build NW.js desktop applications for MacOS, Windows and Linux.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NW.js",
|
|
@@ -56,28 +56,26 @@
|
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@eslint/js": "^9.39.2",
|
|
59
|
-
"@vitest/coverage-v8": "^4.0.
|
|
59
|
+
"@vitest/coverage-v8": "^4.0.17",
|
|
60
60
|
"base-volta-off-of-nwjs": "^1.0.5",
|
|
61
61
|
"eslint": "^9.39.2",
|
|
62
|
-
"eslint-plugin-jsdoc": "^
|
|
63
|
-
"globals": "^
|
|
64
|
-
"nw": "^0.
|
|
62
|
+
"eslint-plugin-jsdoc": "^62.1.0",
|
|
63
|
+
"globals": "^17.0.0",
|
|
64
|
+
"nw": "^0.107.0",
|
|
65
65
|
"selenium-webdriver": "^4.39.0",
|
|
66
66
|
"vitest": "^4.0.14"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
+
"@nwutils/getter": "^0.2.0",
|
|
69
70
|
"archiver": "^7.0.1",
|
|
70
|
-
"axios": "^1.13.2",
|
|
71
71
|
"commander": "^14.0.2",
|
|
72
72
|
"glob": "^13.0.0",
|
|
73
73
|
"plist": "^3.1.0",
|
|
74
74
|
"resedit": "^3.0.1",
|
|
75
|
-
"
|
|
76
|
-
"tar": "^7.5.2",
|
|
77
|
-
"yauzl-promise": "^4.0.0"
|
|
75
|
+
"tar": "^7.5.2"
|
|
78
76
|
},
|
|
79
77
|
"volta": {
|
|
80
78
|
"node": "25.2.1",
|
|
81
|
-
"npm": "11.
|
|
79
|
+
"npm": "11.7.0"
|
|
82
80
|
}
|
|
83
81
|
}
|
package/src/bld.js
CHANGED
|
@@ -89,7 +89,7 @@ import setOsxConfig from './bld/osx.js';
|
|
|
89
89
|
* @property {"normal" | "sdk"} [flavor = "normal"] Build flavor
|
|
90
90
|
* @property {"linux" | "osx" | "win"} [platform] Target platform
|
|
91
91
|
* @property {"ia32" | "x64" | "arm64"} [arch] Target arch
|
|
92
|
-
* @property {string} [manifestUrl = "https://nwjs.io/versions.json"]
|
|
92
|
+
* @property {string} [manifestUrl = "https://nwjs.io/versions.json"] Versions manifest URI, https or file path
|
|
93
93
|
* @property {string} [srcDir = "./src"] Source directory
|
|
94
94
|
* @property {string} [cacheDir = "./cache"] Cache directory
|
|
95
95
|
* @property {string} [outDir = "./out"] Out directory
|
package/src/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ program
|
|
|
14
14
|
.option('--platform <string>', 'NW.js supported platform', util.PLATFORM_KV[process.platform])
|
|
15
15
|
.option('--arch <string>', 'NW.js supported architecture', util.ARCH_KV[process.arch])
|
|
16
16
|
.option('--downloadUrl <string>', 'NW.js download server', 'https://dl.nwjs.io')
|
|
17
|
-
.option('--manifestUrl <string>', 'NW.js
|
|
17
|
+
.option('--manifestUrl <string>', 'NW.js versions manifest URI', 'https://nwjs.io/versions.json')
|
|
18
18
|
.option('--cacheDir <string>', 'Cache NW.js binaries', './cache')
|
|
19
19
|
.option('--outDir <string>', 'NW.js build artifacts', './out')
|
|
20
20
|
.option('--app <object>', 'Platform specific app metadata. Refer to docs for more info', {})
|
package/src/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import fs from 'node:fs';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
|
|
6
6
|
import bld from './bld.js';
|
|
7
|
-
import get from '
|
|
7
|
+
import get from '@nwutils/getter';
|
|
8
8
|
import run from './run.js';
|
|
9
9
|
import util from './util.js';
|
|
10
10
|
|
|
@@ -16,7 +16,7 @@ import util from './util.js';
|
|
|
16
16
|
* @property {"linux" | "osx" | "win"} platform Host platform
|
|
17
17
|
* @property {"ia32" | "x64" | "arm64"} arch Host architecture
|
|
18
18
|
* @property {"https://dl.nwjs.io" | string} [downloadUrl="https://dl.nwjs.io"] Download server
|
|
19
|
-
* @property {"https://nwjs.io/versions.json" | string} [manifestUrl="https://nwjs.io/versions.json"]
|
|
19
|
+
* @property {"https://nwjs.io/versions.json" | string} [manifestUrl="https://nwjs.io/versions.json"] Versions manifest URI, https or file path
|
|
20
20
|
* @property {"./cache" | string} [cacheDir="./cache"] Directory to cache NW binaries
|
|
21
21
|
* @property {"./" | string} [srcDir="./"] File paths to application code
|
|
22
22
|
* @property {"./out" | string} [outDir="./out"] Directory to store build artifacts
|
package/src/util.js
CHANGED
|
@@ -3,17 +3,23 @@ import fs from 'node:fs';
|
|
|
3
3
|
import https from 'node:https';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import process from 'node:process';
|
|
6
|
+
import url from 'node:url';
|
|
6
7
|
|
|
7
8
|
import * as GlobModule from 'glob';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Get manifest (array of NW release metadata) from URL.
|
|
11
|
-
* @param {string} manifestUrl
|
|
12
|
-
* @returns {
|
|
12
|
+
* @param {string} manifestUrl Versions manifest URI, https or file path
|
|
13
|
+
* @returns {string} - Manifest object
|
|
13
14
|
*/
|
|
14
15
|
function getManifest(manifestUrl) {
|
|
15
16
|
let chunks = '';
|
|
16
17
|
|
|
18
|
+
if (manifestUrl.startsWith('file://')) {
|
|
19
|
+
const filePath = url.fileURLToPath(manifestUrl);
|
|
20
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
return new Promise((resolve) => {
|
|
18
24
|
const req = https.get(manifestUrl, (response) => {
|
|
19
25
|
response.on('data', (chunk) => {
|
|
@@ -42,8 +48,8 @@ function getManifest(manifestUrl) {
|
|
|
42
48
|
* @param {string} platform NW platform
|
|
43
49
|
* @param {string} arch NW architecture
|
|
44
50
|
* @param {string} cacheDir Directory to store NW binaries
|
|
45
|
-
* @param {string} manifestUrl
|
|
46
|
-
* @returns {object}
|
|
51
|
+
* @param {string} manifestUrl Versions manifest URI, https or file path
|
|
52
|
+
* @returns {Promise<object>} Version specific release info
|
|
47
53
|
*/
|
|
48
54
|
async function getReleaseInfo(
|
|
49
55
|
version,
|
|
@@ -343,8 +349,8 @@ export const validate = async (options, releaseInfo) => {
|
|
|
343
349
|
if (typeof options.downloadUrl === 'string' && !options.downloadUrl.startsWith('http') && !options.downloadUrl.startsWith('file')) {
|
|
344
350
|
throw new Error('Expected options.downloadUrl to be a string and starts with `http` or `file`.');
|
|
345
351
|
}
|
|
346
|
-
if (typeof options.manifestUrl === 'string' && !options.manifestUrl.startsWith('
|
|
347
|
-
throw new Error('Expected options.manifestUrl to be a string and starts with `
|
|
352
|
+
if (typeof options.manifestUrl === 'string' && !options.manifestUrl.startsWith('https') && !options.manifestUrl.startsWith('file')) {
|
|
353
|
+
throw new Error('Expected options.manifestUrl to be a string and starts with `https` or `file`.');
|
|
348
354
|
}
|
|
349
355
|
if (typeof options.cacheDir !== 'string') {
|
|
350
356
|
throw new Error('Expected options.cacheDir to be a string. Got ' + typeof options.cacheDir);
|
|
@@ -425,15 +431,15 @@ export const validate = async (options, releaseInfo) => {
|
|
|
425
431
|
}
|
|
426
432
|
|
|
427
433
|
if (typeof options.nativeAddon !== 'boolean') {
|
|
428
|
-
|
|
434
|
+
throw new Error('Expected options.nativeAddon to be a boolean. Got ' + typeof options.nativeAddon);
|
|
429
435
|
}
|
|
430
436
|
|
|
431
437
|
if (typeof options.zip !== 'boolean' &
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
438
|
+
options.zip !== 'zip' &&
|
|
439
|
+
options.zip !== 'tar' &&
|
|
440
|
+
options.zip !== 'tgz') {
|
|
441
|
+
throw new Error('Expected options.zip to be a boolean, `zip`, `tar` or `tgz`. Got ' + typeof options.zip);
|
|
442
|
+
}
|
|
437
443
|
|
|
438
444
|
if (options.platform === 'linux') {
|
|
439
445
|
if (options.app.name && typeof options.app.name !== 'string') {
|
|
@@ -664,4 +670,4 @@ function log(severity, logLevel, message) {
|
|
|
664
670
|
return stdout;
|
|
665
671
|
}
|
|
666
672
|
|
|
667
|
-
export default { fileExists, getReleaseInfo, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, globFiles, getNodeManifest, parse, validate, log };
|
|
673
|
+
export default { fileExists, getReleaseInfo, getManifest, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, globFiles, getNodeManifest, parse, validate, log };
|
package/src/get/decompress.js
DELETED
|
@@ -1,94 +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
|
-
/**
|
|
9
|
-
* Decompresses a file at `filePath` to `cacheDir` directory.
|
|
10
|
-
* @param {string} filePath - file path to compressed binary
|
|
11
|
-
* @param {string} cacheDir - directory to decompress into
|
|
12
|
-
*/
|
|
13
|
-
export default async function decompress(filePath, cacheDir) {
|
|
14
|
-
if (filePath.endsWith('.zip')) {
|
|
15
|
-
await unzip(filePath, cacheDir);
|
|
16
|
-
} else {
|
|
17
|
-
await tar.extract({
|
|
18
|
-
file: filePath,
|
|
19
|
-
C: cacheDir
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Get file mode from entry. Reference implementation is [here](https://github.com/fpsqdb/zip-lib/blob/ac447d269218d396e05cd7072d0e9cd82b5ec52c/src/unzip.ts#L380).
|
|
26
|
-
* @param {yauzl.Entry} entry - Yauzl entry
|
|
27
|
-
* @returns {number} - entry's file mode
|
|
28
|
-
*/
|
|
29
|
-
function modeFromEntry(entry) {
|
|
30
|
-
const attr = entry.externalFileAttributes >> 16 || 33188;
|
|
31
|
-
|
|
32
|
-
return [448 /* S_IRWXU */, 56 /* S_IRWXG */, 7 /* S_IRWXO */]
|
|
33
|
-
.map(mask => attr & mask)
|
|
34
|
-
.reduce((a, b) => a + b, attr & 61440 /* S_IFMT */);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Unzip `zippedFile` to `cacheDir`.
|
|
39
|
-
* @async
|
|
40
|
-
* @function
|
|
41
|
-
* @param {string} zippedFile - file path to .zip file
|
|
42
|
-
* @param {string} cacheDir - directory to unzip in
|
|
43
|
-
* @returns {Promise<void>}
|
|
44
|
-
*/
|
|
45
|
-
async function unzip(zippedFile, cacheDir) {
|
|
46
|
-
const zip = await yauzl.open(zippedFile);
|
|
47
|
-
let entry = await zip.readEntry();
|
|
48
|
-
const symlinks = []; // Array to hold symbolic link entries
|
|
49
|
-
|
|
50
|
-
while (entry !== null) {
|
|
51
|
-
let entryPathAbs = path.join(cacheDir, entry.filename);
|
|
52
|
-
// Check if entry is a symbolic link
|
|
53
|
-
const isSymlink = ((modeFromEntry(entry) & 0o170000) === 0o120000);
|
|
54
|
-
|
|
55
|
-
if (isSymlink) {
|
|
56
|
-
// Store symlink entries to process later
|
|
57
|
-
symlinks.push(entry);
|
|
58
|
-
} else {
|
|
59
|
-
// Handle regular files and directories
|
|
60
|
-
await fs.promises.mkdir(path.dirname(entryPathAbs), {recursive: true});
|
|
61
|
-
if (!entry.filename.endsWith('/')) { // Skip directories
|
|
62
|
-
const readStream = await entry.openReadStream();
|
|
63
|
-
const writeStream = fs.createWriteStream(entryPathAbs);
|
|
64
|
-
await stream.promises.pipeline(readStream, writeStream);
|
|
65
|
-
|
|
66
|
-
// Set file permissions after the file has been written
|
|
67
|
-
const mode = modeFromEntry(entry);
|
|
68
|
-
await fs.promises.chmod(entryPathAbs, mode);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Read next entry
|
|
73
|
-
entry = await zip.readEntry();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Process symbolic links after all other files have been extracted
|
|
77
|
-
for (const symlinkEntry of symlinks) {
|
|
78
|
-
let entryPathAbs = path.join(cacheDir, symlinkEntry.filename);
|
|
79
|
-
const readStream = await symlinkEntry.openReadStream();
|
|
80
|
-
const chunks = [];
|
|
81
|
-
readStream.on('data', (chunk) => chunks.push(chunk));
|
|
82
|
-
await new Promise(resolve => readStream.on('end', resolve));
|
|
83
|
-
const linkTarget = Buffer.concat(chunks).toString('utf8').trim();
|
|
84
|
-
|
|
85
|
-
// Check if the symlink or a file/directory already exists at the destination
|
|
86
|
-
if (fs.existsSync(entryPathAbs)) {
|
|
87
|
-
//skip
|
|
88
|
-
} else {
|
|
89
|
-
// Create symbolic link
|
|
90
|
-
await fs.promises.symlink(linkTarget, entryPathAbs);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
await zip.close();
|
|
94
|
-
}
|
package/src/get/ffmpeg.js
DELETED
|
@@ -1,36 +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
|
-
* @param {string} downloadUrl - Download server
|
|
8
|
-
* @param {string} version - Runtime version
|
|
9
|
-
* @param {string} platform - NW supported platform
|
|
10
|
-
* @param {string} arch - NW supported architecture
|
|
11
|
-
* @param {string} cacheDir - Directory to store FFmpeg binary
|
|
12
|
-
* @returns {Promise<string>} Path of compressed file which containscommunity FFmpeg binary.
|
|
13
|
-
*/
|
|
14
|
-
export default async function ffmpeg(downloadUrl, version, platform, arch, cacheDir) {
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* URL to download specific FFmpeg binary from.
|
|
18
|
-
* @type {string}
|
|
19
|
-
*/
|
|
20
|
-
const url = [
|
|
21
|
-
downloadUrl,
|
|
22
|
-
version,
|
|
23
|
-
`${version}-${platform}-${arch}.zip`,
|
|
24
|
-
].join('/');
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Absolute path of compressed file which contains FFmpeg binary.
|
|
28
|
-
*/
|
|
29
|
-
const ffmpegFileAbs = path.resolve(
|
|
30
|
-
cacheDir,
|
|
31
|
-
`ffmpeg-${version}-${platform}-${arch}.zip`,
|
|
32
|
-
);
|
|
33
|
-
await request(url, ffmpegFileAbs);
|
|
34
|
-
|
|
35
|
-
return ffmpegFileAbs;
|
|
36
|
-
}
|
package/src/get/index.js
DELETED
|
@@ -1,219 +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 {boolean} [nativeAddon = false] Download Node headers for native addons.
|
|
24
|
-
* @property {string} [logLevel = 'info'] User defined log level.
|
|
25
|
-
* @property {boolean} [shaSum = true] If true shasum is enabled, otherwise disabled.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get binaries.
|
|
30
|
-
* @async
|
|
31
|
-
* @function
|
|
32
|
-
* @param {GetOptions} options Get mode options
|
|
33
|
-
* @returns {Promise<void>}
|
|
34
|
-
*/
|
|
35
|
-
async function get(options) {
|
|
36
|
-
|
|
37
|
-
const uri = new url.URL(options.downloadUrl);
|
|
38
|
-
|
|
39
|
-
/* Download server is the cached directory. */
|
|
40
|
-
if (uri.protocol === 'file:') {
|
|
41
|
-
options.cacheDir = path.resolve(decodeURIComponent(options.downloadUrl.slice('file://'.length)));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* If `options.cacheDir` exists, then `true`. Otherwise, it is `false`.
|
|
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
|
-
* @type {string}
|
|
56
|
-
*/
|
|
57
|
-
let nwFilePath = path.resolve(
|
|
58
|
-
options.cacheDir,
|
|
59
|
-
`nwjs${options.flavor === 'sdk' ? '-sdk' : ''}-v${options.version}-${options.platform}-${options.arch}.${options.platform === 'linux' ? 'tar.gz' : 'zip'
|
|
60
|
-
}`,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* File path to directory which contain NW.js and related binaries.
|
|
65
|
-
* @type {string}
|
|
66
|
-
*/
|
|
67
|
-
let nwDirPath = path.resolve(
|
|
68
|
-
options.cacheDir,
|
|
69
|
-
`nwjs${options.flavor === 'sdk' ? '-sdk' : ''}-v${options.version}-${options.platform}-${options.arch}`,
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
// If `options.cache` is false, then remove the compressed binary.
|
|
73
|
-
if (options.cache === false) {
|
|
74
|
-
await fs.promises.rm(nwFilePath, {
|
|
75
|
-
recursive: true,
|
|
76
|
-
force: true,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// We remove the nwDir to prevent the edge case where you download with ffmpeg flag enabled
|
|
81
|
-
// but want a subsequent build with ffmpeg flag disabled. By removing the directory and
|
|
82
|
-
// decompressing it again, we prevent the community ffmpeg files from being left over.
|
|
83
|
-
// This is important since the community ffmpeg builds have specific licensing constraints.
|
|
84
|
-
await fs.promises.rm(nwDirPath, { recursive: true, force: true });
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* If the compressed binary exists, then `true`. Otherwise, it is `false`.
|
|
88
|
-
* @type {boolean}
|
|
89
|
-
*/
|
|
90
|
-
const nwFilePathExists = await util.fileExists(nwFilePath);
|
|
91
|
-
if (nwFilePathExists === false) {
|
|
92
|
-
nwFilePath = await nw(options.downloadUrl, options.version, options.flavor, options.platform, options.arch, options.cacheDir);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
await decompress(nwFilePath, options.cacheDir);
|
|
96
|
-
|
|
97
|
-
await verify(
|
|
98
|
-
`${options.downloadUrl}/v${options.version}/SHASUMS256.txt`,
|
|
99
|
-
`${options.cacheDir}/shasum/${options.version}.txt`,
|
|
100
|
-
options.cacheDir,
|
|
101
|
-
options.ffmpeg,
|
|
102
|
-
options.logLevel,
|
|
103
|
-
options.shaSum,
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
if (options.ffmpeg === true) {
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* File path to compressed binary which contains community FFmpeg binary.
|
|
110
|
-
* @type {string}
|
|
111
|
-
*/
|
|
112
|
-
let ffmpegFilePath = path.resolve(
|
|
113
|
-
options.cacheDir,
|
|
114
|
-
`ffmpeg-${options.version}-${options.platform}-${options.arch}.zip`,
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
// If `options.cache` is false, then remove the compressed binary.
|
|
118
|
-
if (options.cache === false) {
|
|
119
|
-
await fs.promises.rm(ffmpegFilePath, {
|
|
120
|
-
recursive: true,
|
|
121
|
-
force: true,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* If the compressed binary exists, then `true`. Otherwise, it is `false`.
|
|
127
|
-
* @type {boolean}
|
|
128
|
-
*/
|
|
129
|
-
const ffmpegFilePathExists = await util.fileExists(ffmpegFilePath);
|
|
130
|
-
if (ffmpegFilePathExists === false) {
|
|
131
|
-
// 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.
|
|
132
|
-
const downloadUrl =
|
|
133
|
-
'https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download';
|
|
134
|
-
ffmpegFilePath = await ffmpeg(downloadUrl, options.version, options.platform, options.arch, options.cacheDir);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
await decompress(ffmpegFilePath, options.cacheDir);
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Platform dependant file name of FFmpeg binary.
|
|
141
|
-
* @type {string}
|
|
142
|
-
*/
|
|
143
|
-
let ffmpegFileName = '';
|
|
144
|
-
|
|
145
|
-
if (options.platform === 'linux') {
|
|
146
|
-
ffmpegFileName = 'libffmpeg.so';
|
|
147
|
-
} else if (options.platform === 'win') {
|
|
148
|
-
ffmpegFileName = 'ffmpeg.dll';
|
|
149
|
-
} else if (options.platform === 'osx') {
|
|
150
|
-
ffmpegFileName = 'libffmpeg.dylib';
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* File path to platform specific FFmpeg file.
|
|
155
|
-
* @type {string}
|
|
156
|
-
*/
|
|
157
|
-
let ffmpegBinaryPath = path.resolve(options.cacheDir, ffmpegFileName);
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* File path of where FFmpeg will be copied to.
|
|
161
|
-
* @type {string}
|
|
162
|
-
*/
|
|
163
|
-
let ffmpegBinaryDest = '';
|
|
164
|
-
|
|
165
|
-
if (options.platform === 'linux') {
|
|
166
|
-
ffmpegBinaryDest = path.resolve(nwDirPath, 'lib', ffmpegFileName);
|
|
167
|
-
} else if (options.platform === 'win') {
|
|
168
|
-
ffmpegBinaryDest = path.resolve(nwDirPath, ffmpegFileName);
|
|
169
|
-
} else if (options.platform === 'osx') {
|
|
170
|
-
ffmpegBinaryDest = path.resolve(
|
|
171
|
-
nwDirPath,
|
|
172
|
-
'nwjs.app',
|
|
173
|
-
'Contents',
|
|
174
|
-
'Frameworks',
|
|
175
|
-
'nwjs Framework.framework',
|
|
176
|
-
'Versions',
|
|
177
|
-
'Current',
|
|
178
|
-
ffmpegFileName,
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
await fs.promises.copyFile(ffmpegBinaryPath, ffmpegBinaryDest);
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (options.nativeAddon === true) {
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* File path to NW'js Node headers tarball.
|
|
190
|
-
* @type {string}
|
|
191
|
-
*/
|
|
192
|
-
let nodeFilePath = path.resolve(
|
|
193
|
-
options.cacheDir,
|
|
194
|
-
`headers-v${options.version}.tar.gz`,
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
// If `options.cache` is false, then remove the compressed binary.
|
|
198
|
-
if (options.cache === false) {
|
|
199
|
-
await fs.promises.rm(nodeFilePath, {
|
|
200
|
-
recursive: true,
|
|
201
|
-
force: true,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* If the compressed binary exists, then `true`. Otherwise, it is `false`.
|
|
207
|
-
* @type {boolean}
|
|
208
|
-
*/
|
|
209
|
-
const nodeFilePathExists = await util.fileExists(nodeFilePath);
|
|
210
|
-
if (nodeFilePathExists === false) {
|
|
211
|
-
nodeFilePath = await node(options.downloadUrl, options.version, options.cacheDir);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
await decompress(nodeFilePath, options.cacheDir);
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export default get;
|
package/src/get/node.js
DELETED
|
@@ -1,46 +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
|
-
* @param {string} downloadUrl - Download server
|
|
8
|
-
* @param {string} version - Runtime version
|
|
9
|
-
* @param {string} cacheDir - Directory to store NW binaries
|
|
10
|
-
* @returns {Promise<string>} - path of compressed file which contains the Node headers.
|
|
11
|
-
*/
|
|
12
|
-
export default async function nw(downloadUrl, version, cacheDir) {
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Name of directory which contains Node headers.
|
|
16
|
-
* @type {string}
|
|
17
|
-
*/
|
|
18
|
-
const nodeDir = `node-v${version}`;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Name of compressed file which contains Node headers.
|
|
22
|
-
* @type {string}
|
|
23
|
-
*/
|
|
24
|
-
const nwFile = `${nodeDir}.tar.gz`;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* URL to download specific Node headers from.
|
|
28
|
-
* @type {string}
|
|
29
|
-
*/
|
|
30
|
-
const url = [
|
|
31
|
-
downloadUrl,
|
|
32
|
-
`v${version}`,
|
|
33
|
-
`nw-headers-v${version}.tar.gz`
|
|
34
|
-
].join('/');
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Absolute path of compressed file which contains Node headers.
|
|
38
|
-
*/
|
|
39
|
-
const nwFileAbs = path.resolve(
|
|
40
|
-
cacheDir,
|
|
41
|
-
nwFile
|
|
42
|
-
);
|
|
43
|
-
await request(url, nwFileAbs);
|
|
44
|
-
|
|
45
|
-
return nwFileAbs;
|
|
46
|
-
}
|
package/src/get/nw.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
|
|
3
|
-
import request from './request.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Download NW.js binary.
|
|
7
|
-
* @param {string} downloadUrl - Download server
|
|
8
|
-
* @param {string} version - Runtime version
|
|
9
|
-
* @param {string} flavor - Runtime build flavor
|
|
10
|
-
* @param {string} platform - NW supported platform
|
|
11
|
-
* @param {string} arch - NW supported architecture
|
|
12
|
-
* @param {string} cacheDir - Directory to store NW binaries
|
|
13
|
-
* @returns {Promise<string>} - path of compressed file which contains NW.js binaries.
|
|
14
|
-
*/
|
|
15
|
-
export default async function nw(downloadUrl, version, flavor, platform, arch, cacheDir) {
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Name of directory which contains NW.js binaries.
|
|
19
|
-
* @type {string}
|
|
20
|
-
*/
|
|
21
|
-
const nwDir = [
|
|
22
|
-
'nwjs',
|
|
23
|
-
flavor === 'sdk' ? '-sdk' : '',
|
|
24
|
-
`-v${version}-${platform}-${arch}`,
|
|
25
|
-
].join('');
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Name of compressed file which contains NW.js binaries.
|
|
29
|
-
* @type {string}
|
|
30
|
-
*/
|
|
31
|
-
const nwFile = [
|
|
32
|
-
nwDir,
|
|
33
|
-
platform === 'linux' ? 'tar.gz' : 'zip'
|
|
34
|
-
].join('.');
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* URL to download specific NW.js binary from.
|
|
38
|
-
* @type {string}
|
|
39
|
-
*/
|
|
40
|
-
const url = [
|
|
41
|
-
downloadUrl,
|
|
42
|
-
`v${version}`,
|
|
43
|
-
nwFile,
|
|
44
|
-
].join('/');
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Absolute path of compressed file which contains NW.js binaries.
|
|
48
|
-
*/
|
|
49
|
-
const nwFileAbs = path.resolve(
|
|
50
|
-
cacheDir,
|
|
51
|
-
nwFile
|
|
52
|
-
);
|
|
53
|
-
await request(url, nwFileAbs);
|
|
54
|
-
|
|
55
|
-
return nwFileAbs;
|
|
56
|
-
}
|
package/src/get/request.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import process from 'node:process';
|
|
3
|
-
import stream from 'node:stream';
|
|
4
|
-
|
|
5
|
-
import axios from 'axios';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Download from `url`.
|
|
9
|
-
* @async
|
|
10
|
-
* @function
|
|
11
|
-
* @param {string} url - Download server
|
|
12
|
-
* @param {string} filePath - file path of downloaded content
|
|
13
|
-
* @returns {Promise<void>}
|
|
14
|
-
*/
|
|
15
|
-
export default async function request(url, filePath) {
|
|
16
|
-
|
|
17
|
-
const writeStream = fs.createWriteStream(filePath);
|
|
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
|
-
|
|
28
|
-
const response = await axios({
|
|
29
|
-
method: 'get',
|
|
30
|
-
url: url,
|
|
31
|
-
responseType: 'stream'
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
await stream.promises.pipeline(response.data, writeStream);
|
|
35
|
-
|
|
36
|
-
}
|
package/src/get/verify.js
DELETED
|
@@ -1,59 +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
|
-
|
|
7
|
-
import util from '../util.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Verify the SHA256 checksum of downloaded artifacts.
|
|
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
|
-
* @param {boolean} ffmpeg - Toggle between community (true) and official (false) ffmpeg binary
|
|
15
|
-
* @param {string} logLevel - User defined log level.
|
|
16
|
-
* @param {boolean} shaSum - Throws error if true, otherwise logs a warning.
|
|
17
|
-
* @throws {Error}
|
|
18
|
-
* @returns {Promise<boolean>} - Returns true if the checksums match.
|
|
19
|
-
*/
|
|
20
|
-
export default async function verify(shaUrl, shaOut, cacheDir, ffmpeg, logLevel, shaSum) {
|
|
21
|
-
const shaOutExists = await util.fileExists(shaOut);
|
|
22
|
-
|
|
23
|
-
if (shaOutExists === false) {
|
|
24
|
-
/* Create directory if does not exist. */
|
|
25
|
-
await fs.promises.mkdir(path.dirname(shaOut), { recursive: true });
|
|
26
|
-
|
|
27
|
-
/* Download SHASUM text file. */
|
|
28
|
-
await request(shaUrl, shaOut);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/* Read SHASUM text file */
|
|
32
|
-
const shasum = await fs.promises.readFile(shaOut, { encoding: 'utf-8' });
|
|
33
|
-
const shasums = shasum.trim().split('\n');
|
|
34
|
-
for await (const line of shasums) {
|
|
35
|
-
const [storedSha, filePath] = line.split(/\s+/);
|
|
36
|
-
const relativeFilePath = path.resolve(cacheDir, filePath);
|
|
37
|
-
const relativefilePathExists = await util.fileExists(relativeFilePath);
|
|
38
|
-
if (relativefilePathExists) {
|
|
39
|
-
const fileBuffer = await fs.promises.readFile(relativeFilePath);
|
|
40
|
-
const hash = crypto.createHash('sha256');
|
|
41
|
-
hash.update(fileBuffer);
|
|
42
|
-
const generatedSha = hash.digest('hex');
|
|
43
|
-
if (!crypto.timingSafeEqual(Buffer.from(generatedSha, 'hex'), Buffer.from(storedSha, 'hex'))) {
|
|
44
|
-
if (filePath.includes('ffmpeg') && ffmpeg) {
|
|
45
|
-
console.warn(`The generated shasum for the community ffmpeg at ${filePath} is ${generatedSha}. The integrity of this file should be manually verified.`);
|
|
46
|
-
} else {
|
|
47
|
-
const message = `SHA256 checksums do not match. The file ${filePath} expected shasum is ${storedSha} but the actual shasum is ${generatedSha}.`;
|
|
48
|
-
if (shaSum) {
|
|
49
|
-
throw new Error(message);
|
|
50
|
-
} else {
|
|
51
|
-
util.log('warn', logLevel, message);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return true;
|
|
59
|
-
}
|