nw-builder 4.3.2 → 4.3.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nw-builder",
3
- "version": "4.3.2",
3
+ "version": "4.3.4",
4
4
  "description": "Build NW.js desktop applications for MacOS, Windows and Linux.",
5
5
  "keywords": [
6
6
  "NW.js",
@@ -25,10 +25,11 @@
25
25
  }
26
26
  ],
27
27
  "license": "MIT",
28
- "exports": {
29
- "default": "./src/index.js",
30
- "types": "./src/index.d.ts"
28
+ "main": "./src/index.js",
29
+ "bin": {
30
+ "nwbuild": "./src/cli.js"
31
31
  },
32
+ "types": "./src/index.d.ts",
32
33
  "type": "module",
33
34
  "files": [
34
35
  "./src"
@@ -40,9 +41,8 @@
40
41
  },
41
42
  "scripts": {
42
43
  "fmt": "prettier --write \"./**/*.{css,html,js,json,md,yml}\"",
43
- "lnt": "eslint --config=cfg/eslint.config.cjs --fix src",
44
- "doc:api": "jsdoc2md ./src/index.js > ./doc/api.md && jsdoc2md ./src/bld/linuxCfg.js > ./doc/api-nux.md && jsdoc2md ./src/bld/winCfg.js > ./doc/api-win.md && jsdoc2md ./src/bld/osxCfg.js > ./doc/api-osx.md",
45
- "doc:dev": "vitepress dev doc",
44
+ "lnt": "eslint --config=cfg/eslint.config.cjs --fix src test",
45
+ "doc:dev": "concurrently --kill-others \"node cfg/fswatch.config.js\" \"vitepress dev doc\"",
46
46
  "doc:bld": "vitepress build doc",
47
47
  "test:unit": "node --test-reporter=spec --test test/unit/index.js",
48
48
  "test:e2e": "node --test-reporter=spec --test test/e2e/index.js",
@@ -50,25 +50,24 @@
50
50
  "test:cli": "cd test/fixture && nwbuild --platform win --arch x64 --outDir out --no-glob app"
51
51
  },
52
52
  "devDependencies": {
53
- "eslint": "^8.44.0",
53
+ "concurrently": "^8.2.0",
54
+ "eslint": "^8.45.0",
54
55
  "eslint-config-tjw-jsdoc": "^1.0.3",
55
56
  "gh-pages": "^5.0.0",
56
57
  "jsdoc": "^4.0.2",
57
58
  "jsdoc-to-markdown": "^8.0.0",
58
- "prettier": "^2.8.8",
59
+ "prettier": "^3.0.0",
59
60
  "selenium-webdriver": "^4.10.0",
60
- "vitepress": "^1.0.0-beta.4"
61
+ "vitepress": "^1.0.0-beta.5"
61
62
  },
62
63
  "dependencies": {
63
64
  "cli-progress": "^3.12.0",
64
65
  "compressing": "^1.9.0",
65
- "glob": "^10.3.1",
66
- "plist": "^3.0.6",
66
+ "glob": "^10.3.3",
67
+ "plist": "^3.1.0",
67
68
  "rcedit": "^3.0.1",
68
69
  "winston": "^3.9.0",
69
70
  "yargs": "^17.7.2"
70
71
  },
71
- "bin": {
72
- "nwbuild": "./src/cli.js"
73
- }
72
+ "packageManager": "npm@9.8.1"
74
73
  }
package/src/bld/build.js CHANGED
@@ -28,7 +28,7 @@ export const build = async (
28
28
  platform,
29
29
  zip,
30
30
  app,
31
- nwPkg
31
+ nwPkg,
32
32
  ) => {
33
33
  log.debug(`Remove any files at ${outDir} directory`);
34
34
  await rm(outDir, { force: true, recursive: true });
@@ -42,9 +42,11 @@ export const build = async (
42
42
  files,
43
43
  resolve(
44
44
  outDir,
45
- platform !== "osx" ? "package.nw" : "nwjs.app/Contents/Resources/app.nw"
45
+ platform !== "osx"
46
+ ? "package.nw"
47
+ : "nwjs.app/Contents/Resources/app.nw",
46
48
  ),
47
- { recursive: true, verbatimSymlinks: true }
49
+ { recursive: true, verbatimSymlinks: true },
48
50
  );
49
51
  } else {
50
52
  for (let file of files) {
@@ -56,9 +58,9 @@ export const build = async (
56
58
  platform !== "osx"
57
59
  ? "package.nw"
58
60
  : "nwjs.app/Contents/Resources/app.nw",
59
- file
61
+ file,
60
62
  ),
61
- { recursive: true, verbatimSymlinks: true }
63
+ { recursive: true, verbatimSymlinks: true },
62
64
  );
63
65
  }
64
66
 
@@ -71,10 +73,10 @@ export const build = async (
71
73
  platform !== "osx"
72
74
  ? "package.nw"
73
75
  : "nwjs.app/Contents/Resources/app.nw",
74
- "package.json"
76
+ "package.json",
75
77
  ),
76
78
  JSON.stringify(nwPkg, null, 2),
77
- "utf8"
79
+ "utf8",
78
80
  );
79
81
  }
80
82
 
@@ -40,7 +40,7 @@ import { log } from "../log.js";
40
40
  export const setLinuxConfig = async (app, outDir) => {
41
41
  if (platform === "win32") {
42
42
  log.warn(
43
- "Linux apps built on Windows platform do not preserve all file permissions. See #716"
43
+ "Linux apps built on Windows platform do not preserve all file permissions. See #716",
44
44
  );
45
45
  }
46
46
  let desktopEntryFile = {
package/src/bld/osxCfg.js CHANGED
@@ -31,7 +31,7 @@ import { log } from "../log.js";
31
31
  const setOsxConfig = async (app, outDir) => {
32
32
  if (platform === "win32") {
33
33
  log.warn(
34
- "MacOS apps built on Windows platform do not preserve all file permissions. See #716"
34
+ "MacOS apps built on Windows platform do not preserve all file permissions. See #716",
35
35
  );
36
36
  }
37
37
 
@@ -41,13 +41,32 @@ const setOsxConfig = async (app, outDir) => {
41
41
  if (app.icon !== undefined) {
42
42
  await copyFile(
43
43
  resolve(app.icon),
44
- resolve(outApp, "Contents", "Resources", "app.icns")
44
+ resolve(outApp, "Contents", "Resources", "app.icns"),
45
45
  );
46
46
  }
47
47
 
48
48
  const infoPlistPath = resolve(outApp, "Contents", "Info.plist");
49
49
  const infoPlistJson = plist.parse(await readFile(infoPlistPath, "utf-8"));
50
50
 
51
+ const infoPlistStringsPath = resolve(
52
+ outApp,
53
+ "Contents",
54
+ "Resources",
55
+ "en.lproj",
56
+ "InfoPlist.strings",
57
+ );
58
+ const infoPlistStringsData = await readFile(infoPlistStringsPath, "utf-8");
59
+
60
+ let infoPlistStringsDataArray = infoPlistStringsData.split("\n");
61
+
62
+ infoPlistStringsDataArray.forEach((line, idx, arr) => {
63
+ if (line.includes("NSHumanReadableCopyright")) {
64
+ arr[
65
+ idx
66
+ ] = `NSHumanReadableCopyright = "${app.NSHumanReadableCopyright}";`;
67
+ }
68
+ });
69
+
51
70
  infoPlistJson.LSApplicationCategoryType = app.LSApplicationCategoryType;
52
71
  infoPlistJson.CFBundleIdentifier = app.CFBundleIdentifier;
53
72
  infoPlistJson.CFBundleName = app.CFBundleName;
@@ -55,7 +74,6 @@ const setOsxConfig = async (app, outDir) => {
55
74
  infoPlistJson.CFBundleSpokenName = app.CFBundleSpokenName;
56
75
  infoPlistJson.CFBundleVersion = app.CFBundleVersion;
57
76
  infoPlistJson.CFBundleShortVersionString = app.CFBundleShortVersionString;
58
- infoPlistJson.NSHumanReadableCopyright = app.NSHumanReadableCopyright;
59
77
 
60
78
  Object.keys(infoPlistJson).forEach((option) => {
61
79
  if (infoPlistJson[option] === undefined) {
@@ -64,6 +82,10 @@ const setOsxConfig = async (app, outDir) => {
64
82
  });
65
83
 
66
84
  await writeFile(infoPlistPath, plist.build(infoPlistJson));
85
+ await writeFile(
86
+ infoPlistStringsPath,
87
+ infoPlistStringsDataArray.toString().replace(/,/g, "\n"),
88
+ );
67
89
  } catch (error) {
68
90
  log.error(error);
69
91
  }
package/src/bld/winCfg.js CHANGED
@@ -13,6 +13,7 @@ import { log } from "../log.js";
13
13
  * @property {string} company Company that produced the file—for example, Microsoft Corporation or Standard Microsystems Corporation, Inc. This string is required.
14
14
  * @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.
15
15
  * @property {string} fileVersion Version number of the file. For example, 3.10 or 5.00.RC2. This string is required.
16
+ * @property {string} icon The path to the icon file. It should be a .ico file.
16
17
  * @property {string} internalName 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.
17
18
  * @property {string} legalCopyright 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.
18
19
  * @property {string} legalTrademark 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.
@@ -55,17 +56,23 @@ const setWinConfig = async (app, outDir) => {
55
56
  }
56
57
  });
57
58
 
59
+ const rcEditOptions = {
60
+ "file-version": app.version,
61
+ "product-version": app.version,
62
+ "version-string": versionString,
63
+ }
64
+
65
+ if (app.icon) {
66
+ rcEditOptions.icon = app.icon
67
+ }
68
+
58
69
  try {
59
70
  const outDirAppExe = resolve(outDir, `${app.name}.exe`);
60
71
  await rename(resolve(outDir, "nw.exe"), outDirAppExe);
61
- await rcedit(outDirAppExe, {
62
- "file-version": app.version,
63
- "product-version": app.version,
64
- "version-string": versionString,
65
- });
72
+ await rcedit(outDirAppExe, rcEditOptions);
66
73
  } catch (error) {
67
74
  log.warn(
68
- "Renaming EXE failed or unable to modify EXE. If it's the latter, ensure WINE is installed or build your application Windows platform"
75
+ "Renaming EXE failed or unable to modify EXE. If it's the latter, ensure WINE is installed or build your application Windows platform",
69
76
  );
70
77
  log.error(error);
71
78
  }
package/src/get.js ADDED
@@ -0,0 +1,195 @@
1
+ import { createWriteStream } from "node:fs";
2
+
3
+ import { mkdir, readdir, rm, rmdir } from "node:fs/promises";
4
+ import { get as getRequest } from "node:https";
5
+ import { resolve } from "node:path";
6
+ import { arch as ARCH, platform as PLATFORM } from "node:process";
7
+
8
+ import progress from "cli-progress";
9
+ import compressing from "compressing";
10
+
11
+ const PLATFORM_KV = {
12
+ darwin: "osx",
13
+ linux: "linux",
14
+ win32: "win",
15
+ };
16
+
17
+ const ARCH_KV = {
18
+ x64: "x64",
19
+ ia32: "ia32",
20
+ arm64: "arm64",
21
+ };
22
+
23
+ /**
24
+ * _Note: This an internal function which is not called directly. Please see example usage below._
25
+ *
26
+ * Get NW.js binaries.
27
+ *
28
+ * @example
29
+ * // Minimal Usage (uses default values)
30
+ * nwbuild({
31
+ * mode: "get",
32
+ * });
33
+ *
34
+ * @example
35
+ * // Unofficial MacOS builds (upto v0.75.0)
36
+ * nwbuild({
37
+ * mode: "get",
38
+ * platform: "osx",
39
+ * arch: "arm64",
40
+ * downloadUrl: "https://github.com/corwin-of-amber/nw.js/releases/download",
41
+ * manifestUrl: "https://raw.githubusercontent.com/nwutils/nw-builder/main/src/util/osx.arm.versions.json",
42
+ * });
43
+ *
44
+ * @example
45
+ * // China mirror
46
+ * nwbuild({
47
+ * mode: "get",
48
+ * downloadUrl: "https://npm.taobao.org/mirrors/nwjs",
49
+ * });
50
+ *
51
+ * @example
52
+ * // Singapore mirror
53
+ * nwbuild({
54
+ * mode: "get",
55
+ * downloadUrl: "https://cnpmjs.org/mirrors/nwjs/",
56
+ * });
57
+ *
58
+ * @example
59
+ * // FFmpeg (proprietary codecs)
60
+ * // Please read the license's constraints: https://nwjs.readthedocs.io/en/latest/For%20Developers/Enable%20Proprietary%20Codecs/#get-ffmpeg-binaries-from-the-community
61
+ * nwbuild({
62
+ * mode: "get",
63
+ * ffmpeg: true,
64
+ * });
65
+ *
66
+ * @param {object} options Get mode options
67
+ * @param {string} options.version NW.js runtime version. Defaults to "latest".
68
+ * @param {"normal" | "sdk"} options.flavor NW.js build flavor. Defaults to "normal".
69
+ * @param {"linux" | "osx" | "win"} options.platform Target platform. Defaults to host platform.
70
+ * @param {"ia32" | "x64" | "arm64"} options.arch Target architecture. Defaults to host architecture.
71
+ * @param {string} options.downloadUrl File server to download from. Defaults to "https://dl.nwjs.io". Set "https://npm.taobao.org/mirrors/nwjs" for China mirror or "https://cnpmjs.org/mirrors/nwjs/" for Singapore mirror.
72
+ * @param {string} options.cacheDir Cache directory path. Defaults to "./cache"
73
+ * @param {boolean} options.cache If false, remove cache before download. Defaults to true.
74
+ * @param {boolean} options.ffmpeg If true, download ffmpeg. Defaults to false since it contains proprietary codecs. Please read the license's constraints: https://nwjs.readthedocs.io/en/latest/For%20Developers/Enable%20Proprietary%20Codecs/#get-ffmpeg-binaries-from-the-community
75
+ * @return {Promise<void>}
76
+ */
77
+ export async function get({
78
+ version = "latest",
79
+ flavor = "normal",
80
+ platform = PLATFORM_KV[PLATFORM],
81
+ arch = ARCH_KV[ARCH],
82
+ downloadUrl = "https://dl.nwjs.io",
83
+ cacheDir = "./cache",
84
+ cache = true,
85
+ ffmpeg = false,
86
+ }) {
87
+ let nwCached = true;
88
+ const nwDir = resolve(
89
+ cacheDir,
90
+ `nwjs${flavor === "sdk" ? "-sdk" : ""}-v${version}-${platform}-${arch}`,
91
+ );
92
+ let out = undefined;
93
+ let url = undefined;
94
+ const bar = new progress.SingleBar({}, progress.Presets.rect);
95
+
96
+ // Set download url and destination.
97
+ if (
98
+ downloadUrl === "https://dl.nwjs.io" ||
99
+ downloadUrl === "https://npm.taobao.org/mirrors/nwjs" ||
100
+ downloadUrl === "https://npmmirror.com/mirrors/nwjs"
101
+ ) {
102
+ url = `${downloadUrl}/v${version}/nwjs${
103
+ flavor === "sdk" ? "-sdk" : ""
104
+ }-v${version}-${platform}-${arch}.${
105
+ platform === "linux" ? "tar.gz" : "zip"
106
+ }`;
107
+ out = resolve(cacheDir, `nw.${platform === "linux" ? "tgz" : "zip"}`);
108
+ }
109
+
110
+ // If options.ffmpeg is true, then download ffmpeg.
111
+ if (ffmpeg === true) {
112
+ downloadUrl =
113
+ "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download";
114
+ url = `${downloadUrl}/${version}/${version}-${platform}-${arch}.zip`;
115
+ out = resolve(cacheDir, `ffmpeg.zip`);
116
+ }
117
+
118
+ // If options.cache is false, remove cache.
119
+ if (cache === false) {
120
+ rmdir(nwDir, { recursive: true, force: true });
121
+ }
122
+
123
+ // Check if cache exists.
124
+ try {
125
+ await readdir(nwDir);
126
+ } catch (error) {
127
+ nwCached = false;
128
+ }
129
+
130
+ // If not cached, then download.
131
+ if (nwCached === false) {
132
+ await mkdir(nwDir, { recursive: true });
133
+
134
+ const stream = createWriteStream(out);
135
+ const request = new Promise((resolve, reject) => {
136
+ getRequest(url, (response) => {
137
+ // For GitHub releases and mirrors, we need to follow the redirect.
138
+ if (
139
+ downloadUrl ===
140
+ "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download" ||
141
+ downloadUrl === "https://npm.taobao.org/mirrors/nwjs" ||
142
+ downloadUrl === "https://npmmirror.com/mirrors/nwjs"
143
+ ) {
144
+ url = response.headers.location;
145
+ }
146
+
147
+ getRequest(url, (response) => {
148
+ let chunks = 0;
149
+ bar.start(Number(response.headers["content-length"]), 0);
150
+ response.on("data", async (chunk) => {
151
+ chunks += chunk.length;
152
+ bar.increment();
153
+ bar.update(chunks);
154
+ });
155
+
156
+ response.on("error", (error) => {
157
+ reject(error);
158
+ });
159
+
160
+ response.on("end", () => {
161
+ bar.stop();
162
+ if (platform === "linux") {
163
+ compressing.tgz
164
+ .uncompress(out, ffmpeg ? nwDir : cacheDir)
165
+ .then(() => resolve());
166
+ } else {
167
+ compressing.zip
168
+ .uncompress(out, ffmpeg ? nwDir : cacheDir)
169
+ .then(() => resolve());
170
+ }
171
+ });
172
+
173
+ response.pipe(stream);
174
+ });
175
+
176
+ response.on("error", (error) => {
177
+ reject(error);
178
+ });
179
+ });
180
+ });
181
+
182
+ // Remove compressed file after download and decompress.
183
+ request.then(async () => {
184
+ await rm(resolve(cacheDir, "ffmpeg.zip"), {
185
+ recursive: true,
186
+ force: true,
187
+ });
188
+
189
+ await rm(
190
+ resolve(cacheDir, `nw.${platform === "linux" ? "tgz" : "zip"}`),
191
+ { recursive: true, force: true },
192
+ );
193
+ });
194
+ }
195
+ }
package/src/index.js CHANGED
@@ -1,21 +1,18 @@
1
- import { mkdir, rm } from "node:fs/promises";
1
+ import { mkdir } from "node:fs/promises";
2
2
  import { resolve } from "node:path";
3
3
  import { arch, platform, version } from "node:process";
4
4
 
5
- import { decompress } from "./get/decompress.js";
6
- import { download } from "./get/download.js";
7
- import { getReleaseInfo } from "./get/getReleaseInfo.js";
8
- import { remove } from "./get/remove.js";
9
5
  import { build } from "./bld/build.js";
10
6
  import { develop } from "./run/develop.js";
11
7
  import { isCached } from "./util/cache.js";
12
- import { replaceFfmpeg } from "./util/ffmpeg.js";
13
8
  import { getFiles } from "./util/files.js";
14
9
  import { getVersionManifest } from "./util/versionManifest.js";
15
10
  import { parse } from "./util/parse.js";
16
11
  import { validate } from "./util/validate.js";
17
12
 
13
+ import { get } from "./get.js";
18
14
  import { log, setLogLevel } from "./log.js";
15
+ import { getReleaseInfo } from "./util.js";
19
16
 
20
17
  /**
21
18
  * @typedef {object} Options Configuration options
@@ -46,9 +43,6 @@ import { log, setLogLevel } from "./log.js";
46
43
  */
47
44
  const nwbuild = async (options) => {
48
45
  let nwDir = "";
49
- let ffmpegFile = "";
50
- let cached;
51
- let nwCached;
52
46
  let built;
53
47
  let releaseInfo = {};
54
48
  let files = [];
@@ -68,9 +62,8 @@ const nwbuild = async (options) => {
68
62
 
69
63
  options = await parse(options, manifest);
70
64
 
71
- // Create cacheDir if it does not exist
72
- cached = await isCached(options.cacheDir);
73
- if (cached === false) {
65
+ built = await isCached(options.cacheDir);
66
+ if (built === false) {
74
67
  await mkdir(options.cacheDir, { recursive: true });
75
68
  }
76
69
 
@@ -88,7 +81,7 @@ const nwbuild = async (options) => {
88
81
  options.platform,
89
82
  options.arch,
90
83
  options.cacheDir,
91
- options.manifestUrl
84
+ options.manifestUrl,
92
85
  );
93
86
 
94
87
  await validate(options, releaseInfo);
@@ -105,86 +98,42 @@ const nwbuild = async (options) => {
105
98
  log.debug(`NW.js Version: ${options.version}\n`);
106
99
  }
107
100
 
108
- // Variable to store nwDir file path
109
101
  nwDir = resolve(
110
102
  options.cacheDir,
111
103
  `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${
112
104
  options.platform
113
- }-${options.arch}`
105
+ }-${options.arch}`,
114
106
  );
115
107
 
116
- nwCached = await isCached(nwDir);
117
- // Remove cached NW binary
118
- if (options.cache === false && nwCached === true) {
119
- log.debug("Remove cached NW binary");
120
- await rm(nwDir, { force: true, recursive: true });
121
- }
122
- // Download relevant NW.js binaries
123
- if (nwCached === false) {
124
- log.debug("Download relevant NW.js binaries");
125
- await download(
126
- options.version,
127
- options.flavor,
128
- options.platform,
129
- options.arch,
130
- options.downloadUrl,
131
- options.cacheDir
132
- );
133
- await decompress(options.platform, options.cacheDir, options.downloadUrl);
134
- await remove(options.platform, options.cacheDir, options.downloadUrl);
135
- } else {
136
- log.debug("Using cached NW.js binaries");
137
- }
138
-
108
+ // Download NW.js binaries
109
+ await get({
110
+ version: options.version,
111
+ flavor: options.flavor,
112
+ platform: options.platform,
113
+ arch: options.arch,
114
+ downloadUrl: options.downloadUrl,
115
+ cacheDir: options.cacheDir,
116
+ cache: options.cache,
117
+ ffmpeg: false,
118
+ });
119
+
120
+ // Download ffmpeg binaries and replace chromium ffmpeg
139
121
  if (options.ffmpeg === true) {
140
- log.warn(
141
- "Using MP3 and H.264 codecs requires you to pay attention to the patent royalties and the license of the source code. Consult a lawyer if you do not understand the licensing constraints and using patented media formats in your app. See https://chromium.googlesource.com/chromium/third_party/ffmpeg.git/+/master/CREDITS.chromium for more information."
142
- );
143
- if (options.platform === "win") {
144
- ffmpegFile = "libffmpeg.dll";
145
- } else if (options.platform === "osx") {
146
- ffmpegFile = "libffmpeg.dylib";
147
- } else if (options.platform === "linux") {
148
- ffmpegFile = "libffmpeg.so";
149
- }
150
- ffmpegFile = resolve(options.cacheDir, ffmpegFile);
151
- const ffmpegCached = await isCached(ffmpegFile);
152
- // Remove cached ffmpeg binary
153
- if (options.cache === false && ffmpegCached === true) {
154
- log.debug("Remove cached ffmpeg binary");
155
- await rm(ffmpegFile, { force: true, recursive: true });
156
- }
157
-
158
- // Download relevant ffmpeg binaries
159
- if (ffmpegCached === false) {
160
- log.debug("Download relevant ffmpeg binaries");
161
- await download(
162
- options.version,
163
- options.flavor,
164
- options.platform,
165
- options.arch,
166
- "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download",
167
- options.cacheDir
168
- );
169
- await decompress(
170
- options.platform,
171
- options.cacheDir,
172
- "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download"
173
- );
174
- await remove(
175
- options.platform,
176
- options.cacheDir,
177
- "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download"
178
- );
179
-
180
- await replaceFfmpeg(options.platform, nwDir, ffmpegFile);
181
- }
122
+ await get({
123
+ version: options.version,
124
+ flavor: options.flavor,
125
+ platform: options.platform,
126
+ arch: options.arch,
127
+ downloadUrl: options.downloadUrl,
128
+ cacheDir: options.cacheDir,
129
+ cache: options.cache,
130
+ ffmpeg: true,
131
+ });
182
132
  }
183
133
 
184
- // Downloading binaries is required for run and build modes
185
- // If mode is get, exit function since we have gotten the binaries
186
134
  if (options.mode === "get") {
187
- return undefined;
135
+ // Do nothing since we have already downloaded the binaries
136
+ return;
188
137
  }
189
138
 
190
139
  if (options.mode === "run") {
@@ -193,10 +142,10 @@ const nwbuild = async (options) => {
193
142
  nwDir,
194
143
  options.platform,
195
144
  options.argv,
196
- options.glob
145
+ options.glob,
197
146
  );
198
147
  }
199
- if (options.mode === "build") {
148
+ else if (options.mode === "build") {
200
149
  await build(
201
150
  options.glob === true ? files : options.srcDir,
202
151
  nwDir,
@@ -204,7 +153,7 @@ const nwbuild = async (options) => {
204
153
  options.platform,
205
154
  options.zip,
206
155
  options.app,
207
- manifest
156
+ manifest,
208
157
  );
209
158
  }
210
159
  } catch (error) {
@@ -24,7 +24,7 @@ const develop = async (srcDir, nwDir, platform, argv, glob) => {
24
24
  await execute(
25
25
  srcDir,
26
26
  `${nwDir}/${getPlatformSpecificName(platform)}`,
27
- argv
27
+ argv,
28
28
  );
29
29
  } catch (error) {
30
30
  log.error(error);
@@ -23,8 +23,8 @@ export const replaceFfmpeg = async (platform, nwDir, ffmpegFile) => {
23
23
  "nwjs Framework.framework",
24
24
  "Versions",
25
25
  "Current",
26
- ffmpegFile
27
- )
26
+ ffmpegFile,
27
+ ),
28
28
  );
29
29
  }
30
30
  };
@@ -11,17 +11,17 @@ import { readdir } from "node:fs/promises";
11
11
  export const validate = async (options, releaseInfo) => {
12
12
  if (!["get", "run", "build"].includes(options.mode)) {
13
13
  throw new Error(
14
- `Unknown mode ${options.mode}. Expected "get", "run" or "build".`
14
+ `Unknown mode ${options.mode}. Expected "get", "run" or "build".`,
15
15
  );
16
16
  }
17
17
  if (typeof releaseInfo === "undefined") {
18
18
  throw new Error(
19
- "Either the specific version info does not exist or the version manifest itself does not exist. In case of the latter, please check your internet connection and try again later."
19
+ "Either the specific version info does not exist or the version manifest itself does not exist. In case of the latter, please check your internet connection and try again later.",
20
20
  );
21
21
  }
22
22
  if (!releaseInfo.flavors.includes(options.flavor)) {
23
23
  throw new Error(
24
- `${options.flavor} flavor is not supported by this download server.`
24
+ `${options.flavor} flavor is not supported by this download server.`,
25
25
  );
26
26
  }
27
27
  if (
@@ -30,7 +30,7 @@ export const validate = async (options, releaseInfo) => {
30
30
  !releaseInfo.files.includes(`${options.platform}-${options.arch}`)
31
31
  ) {
32
32
  throw new Error(
33
- `Platform ${options.platform} and architecture ${options.arch} is not supported by this download server.`
33
+ `Platform ${options.platform} and architecture ${options.arch} is not supported by this download server.`,
34
34
  );
35
35
  }
36
36
  // if (typeof options.cacheDir !== "string") {
@@ -38,12 +38,12 @@ export const validate = async (options, releaseInfo) => {
38
38
  // }
39
39
  if (typeof options.cache !== "boolean") {
40
40
  return new Error(
41
- "Expected options.cache to be a boolean. Got " + typeof options.cache
41
+ "Expected options.cache to be a boolean. Got " + typeof options.cache,
42
42
  );
43
43
  }
44
44
  if (typeof options.ffmpeg !== "boolean") {
45
45
  return new Error(
46
- "Expected options.ffmpeg to be a boolean. Got " + typeof options.ffmpeg
46
+ "Expected options.ffmpeg to be a boolean. Got " + typeof options.ffmpeg,
47
47
  );
48
48
  }
49
49
 
@@ -54,7 +54,7 @@ export const validate = async (options, releaseInfo) => {
54
54
  options.logLevel !== "debug"
55
55
  ) {
56
56
  throw new Error(
57
- "Expected 'error', 'warn', 'info' or 'debug'. Got " + options.logLevel
57
+ "Expected 'error', 'warn', 'info' or 'debug'. Got " + options.logLevel,
58
58
  );
59
59
  }
60
60
 
@@ -63,12 +63,12 @@ export const validate = async (options, releaseInfo) => {
63
63
  }
64
64
  if (Array.isArray(options.argv)) {
65
65
  return new Error(
66
- "Expected options.argv to be an array. Got " + typeof options.argv
66
+ "Expected options.argv to be an array. Got " + typeof options.argv,
67
67
  );
68
68
  }
69
69
  if (typeof options.glob !== "boolean") {
70
70
  return new Error(
71
- "Expected options.glob to be a boolean. Got " + typeof options.glob
71
+ "Expected options.glob to be a boolean. Got " + typeof options.glob,
72
72
  );
73
73
  }
74
74
 
@@ -1,9 +1,40 @@
1
1
  import { readFile, writeFile } from "node:fs/promises";
2
+ import { get } from "node:https";
2
3
  import { resolve } from "node:path";
3
4
 
4
- import { log } from "../log.js";
5
+ import { log } from "./log.js";
5
6
 
6
- import { getManifest } from "./getManifest.js";
7
+ /**
8
+ * Get manifest (array of NW release metadata) from URL
9
+ *
10
+ * @param {string} manifestUrl Url to manifest
11
+ * @return {Promise <object | undefined>}
12
+ */
13
+ function getManifest(manifestUrl) {
14
+ let chunks = undefined;
15
+
16
+ return new Promise((resolve) => {
17
+ const req = get(manifestUrl, (res) => {
18
+ res.on("data", (chunk) => {
19
+ chunks += chunk;
20
+ });
21
+
22
+ res.on("error", (e) => {
23
+ log.error(e);
24
+ resolve(undefined);
25
+ });
26
+
27
+ res.on("end", () => {
28
+ log.debug("Succesfully cached manifest metadata");
29
+ resolve(chunks);
30
+ });
31
+ });
32
+ req.on("error", (e) => {
33
+ log.warn(e);
34
+ resolve(undefined);
35
+ });
36
+ });
37
+ }
7
38
 
8
39
  /**
9
40
  * Get version specific release metadata
@@ -15,13 +46,13 @@ import { getManifest } from "./getManifest.js";
15
46
  * @param {string} manifestUrl Url to manifest
16
47
  * @return {object} Version specific release info
17
48
  */
18
- export const getReleaseInfo = async (
49
+ export async function getReleaseInfo(
19
50
  version,
20
51
  platform,
21
52
  arch,
22
53
  cacheDir,
23
- manifestUrl
24
- ) => {
54
+ manifestUrl,
55
+ ) {
25
56
  let releaseData = undefined;
26
57
  let manifestPath = undefined;
27
58
  if (platform === "osx" && arch === "arm64") {
@@ -43,12 +74,12 @@ export const getReleaseInfo = async (
43
74
  }
44
75
 
45
76
  releaseData = manifest.versions.find(
46
- (release) => release.version === `v${version}`
77
+ (release) => release.version === `v${version}`,
47
78
  );
48
79
  } catch (e) {
49
80
  log.debug(
50
- "The version manifest does not exist/was not downloaded. Please try again in some time."
81
+ "The version manifest does not exist/was not downloaded. Please try again in some time.",
51
82
  );
52
83
  }
53
84
  return releaseData;
54
- };
85
+ }
@@ -1,44 +0,0 @@
1
- import { resolve } from "node:path";
2
-
3
- import compressing from "compressing";
4
-
5
- import { log } from "../log.js";
6
-
7
- /**
8
- * Decompress NW.js binary
9
- *
10
- * @param {string} platform Platform
11
- * @param {string} cacheDir Output directory
12
- * @param {string} downloadUrl Download url
13
- * @return {Promise<void>}
14
- */
15
- const decompress = async (platform, cacheDir, downloadUrl) => {
16
- try {
17
- if (
18
- downloadUrl === "https://dl.nwjs.io" ||
19
- downloadUrl === "https://npm.taobao.org/mirrors/nwjs" ||
20
- downloadUrl === "https://npmmirror.com/mirrors/nwjs" ||
21
- downloadUrl ===
22
- "https://github.com/corwin-of-amber/nw.js/releases/download"
23
- ) {
24
- if (platform === "linux") {
25
- await compressing.tgz.uncompress(resolve(cacheDir, "nw.tgz"), cacheDir);
26
- } else {
27
- await compressing.zip.uncompress(resolve(cacheDir, "nw.zip"), cacheDir);
28
- }
29
- } else if (
30
- downloadUrl ===
31
- "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download"
32
- ) {
33
- await compressing.zip.uncompress(
34
- resolve(cacheDir, "ffmpeg.zip"),
35
- cacheDir
36
- );
37
- }
38
- } catch (error) {
39
- log.error(error);
40
- throw error;
41
- }
42
- };
43
-
44
- export { decompress };
@@ -1,103 +0,0 @@
1
- import fs from "node:fs";
2
- import { resolve } from "node:path";
3
- import https from "https";
4
-
5
- import progress from "cli-progress";
6
-
7
- const bar = new progress.SingleBar({}, progress.Presets.rect);
8
-
9
- /**
10
- * Download NW.js binary
11
- *
12
- * @param {string} version Version
13
- * @param {string} flavor Flavor
14
- * @param {string} platform Platform
15
- * @param {string} architecture Architecture
16
- * @param {string} downloadUrl Download url
17
- * @param {string} cacheDir Output directory
18
- * @return {Promise<void>}
19
- */
20
- const download = (
21
- version,
22
- flavor,
23
- platform,
24
- architecture,
25
- downloadUrl,
26
- cacheDir
27
- ) => {
28
- let url;
29
- let out;
30
- return new Promise((res, rej) => {
31
- if (
32
- downloadUrl === "https://dl.nwjs.io" ||
33
- downloadUrl === "https://npm.taobao.org/mirrors/nwjs" ||
34
- downloadUrl === "https://npmmirror.com/mirrors/nwjs"
35
- ) {
36
- url = `${downloadUrl}/v${version}/nwjs${
37
- flavor === "sdk" ? "-sdk" : ""
38
- }-v${version}-${platform}-${architecture}.${
39
- platform === "linux" ? "tar.gz" : "zip"
40
- }`;
41
- out = resolve(cacheDir, `nw.${platform === "linux" ? "tgz" : "zip"}`);
42
- } else if (
43
- downloadUrl ===
44
- "https://github.com/corwin-of-amber/nw.js/releases/download"
45
- ) {
46
- url = `${downloadUrl}/nw-v${version}/nwjs-${
47
- flavor === "sdk" ? "sdk-" : ""
48
- }v${version}-${platform}-${architecture}.zip`;
49
- out = resolve(cacheDir, `nw.zip`);
50
- } else if (
51
- downloadUrl ===
52
- "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download"
53
- ) {
54
- url = `${downloadUrl}/${version}/${version}-${platform}-${architecture}.zip`;
55
- out = resolve(cacheDir, `ffmpeg.zip`);
56
- } else {
57
- rej(new Error("Invalid download url. Please try again."));
58
- }
59
-
60
- https.get(url, (response) => {
61
- // For GitHub releases, we need to follow the redirect
62
- if (
63
- downloadUrl ===
64
- "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download" ||
65
- downloadUrl ===
66
- "https://github.com/corwin-of-amber/nw.js/releases/download" ||
67
- downloadUrl === "https://npm.taobao.org/mirrors/nwjs" ||
68
- downloadUrl === "https://npmmirror.com/mirrors/nwjs"
69
- ) {
70
- url = response.headers.location;
71
- }
72
-
73
- https.get(url, (response) => {
74
- let chunks = 0;
75
- bar.start(Number(response.headers["content-length"]), 0);
76
- response.on("data", (chunk) => {
77
- chunks += chunk.length;
78
- bar.increment();
79
- bar.update(chunks);
80
- });
81
-
82
- response.on("error", (error) => {
83
- rej(error);
84
- });
85
-
86
- response.on("end", () => {
87
- bar.stop();
88
- res();
89
- });
90
-
91
- fs.mkdirSync(cacheDir, { recursive: true });
92
- const stream = fs.createWriteStream(out);
93
- response.pipe(stream);
94
- });
95
-
96
- response.on("error", (error) => {
97
- rej(error);
98
- });
99
- });
100
- });
101
- };
102
-
103
- export { download };
@@ -1,35 +0,0 @@
1
- import { get } from "node:https";
2
-
3
- import { log } from "../log.js";
4
-
5
- /**
6
- * Get manifest (array of NW release metadata) from URL
7
- *
8
- * @param {string} manifestUrl Url to manifest
9
- * @return {Promise <object | undefined>}
10
- */
11
- export const getManifest = (manifestUrl) => {
12
- let chunks = undefined;
13
-
14
- return new Promise((resolve) => {
15
- const req = get(manifestUrl, (res) => {
16
- res.on("data", (chunk) => {
17
- chunks += chunk;
18
- });
19
-
20
- res.on("error", (e) => {
21
- log.error(e);
22
- resolve(undefined);
23
- });
24
-
25
- res.on("end", () => {
26
- log.debug("Succesfully cached manifest metadata");
27
- resolve(chunks);
28
- });
29
- });
30
- req.on("error", (e) => {
31
- log.warn(e);
32
- resolve(undefined);
33
- });
34
- });
35
- };
package/src/get/remove.js DELETED
@@ -1,37 +0,0 @@
1
- import { rm } from "node:fs/promises";
2
- import { resolve } from "node:path";
3
-
4
- import { log } from "../log.js";
5
-
6
- /**
7
- * Remove NW.js binary
8
- *
9
- * @param {string} platform - linux, macos, win32
10
- * @param {string} cacheDir - Output directory
11
- * @param {string} downloadUrl - Download URL
12
- * @return {Promise<void>} - Promise
13
- */
14
- const remove = async (platform, cacheDir, downloadUrl) => {
15
- try {
16
- if (downloadUrl === "https://dl.nwjs.io/") {
17
- if (platform === "linux") {
18
- await rm(resolve(cacheDir, "nw.tgz"), { recursive: true, force: true });
19
- } else {
20
- await rm(resolve(cacheDir, "nw.zip"), { recursive: true, force: true });
21
- }
22
- } else if (
23
- downloadUrl ===
24
- "https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt/releases/download"
25
- ) {
26
- await rm(resolve(cacheDir, "ffmpeg.zip"), {
27
- recursive: true,
28
- force: true,
29
- });
30
- }
31
- } catch (error) {
32
- log.error(error);
33
- throw error;
34
- }
35
- };
36
-
37
- export { remove };