nw-builder 4.0.2 → 4.0.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/src/bld/winCfg.js CHANGED
@@ -2,27 +2,55 @@ import { rename } from "node:fs/promises";
2
2
 
3
3
  import rcedit from "rcedit";
4
4
 
5
+ import { log } from "../log.js";
6
+
5
7
  /**
6
8
  * Windows specific configuration steps
9
+ * https://learn.microsoft.com/en-us/windows/win32/msi/version
10
+ * https://learn.microsoft.com/en-gb/windows/win32/sbscs/application-manifests
11
+ * https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/deployment/trustinfo-element-clickonce-application?view=vs-2015#requestedexecutionlevel
12
+ * https://learn.microsoft.com/en-gb/windows/win32/menurc/versioninfo-resource
7
13
  *
8
- * @param {object} pkg The srcDir/package.json as a JSON
14
+ * @param {object} app Multi platform configuration options
9
15
  * @param {string} outDir The directory to hold build artifacts
10
16
  */
11
- const setWinConfig = async (pkg, outDir) => {
12
- await rename(`${outDir}/nw.exe`, `${outDir}/${pkg.name}.exe`);
17
+ const setWinConfig = async (app, outDir) => {
18
+ let versionString = {
19
+ Comments: app.comments,
20
+ CompanyName: app.author,
21
+ FileDescription: app.fileDescription,
22
+ FileVersion: app.fileVersion,
23
+ InternalName: app.name,
24
+ LegalCopyright: app.legalCopyright,
25
+ LegalTrademarks: app.legalTrademark,
26
+ OriginalFilename: app.name,
27
+ PrivateBuild: app.name,
28
+ ProductName: app.name,
29
+ ProductVersion: app.version,
30
+ SpecialBuild: app.name,
31
+ };
13
32
 
14
- // https://learn.microsoft.com/en-gb/windows/win32/menurc/versioninfo-resource?redirectedfrom=MSDN#string-name
15
- await rcedit(`${outDir}/${pkg.name}.exe`, {
16
- "file-version": pkg.version,
17
- "product-version": pkg.version,
18
- "icon": pkg.icon,
19
- "version-string": {
20
- FileDescription: pkg.description,
21
- LegalCopyright: pkg.copyright,
22
- ProductName: pkg.name,
23
- OriginalFilename: pkg.name,
24
- },
33
+ Object.keys(versionString).forEach((option) => {
34
+ if (versionString[option] === undefined) {
35
+ delete versionString[option];
36
+ }
25
37
  });
38
+
39
+ try {
40
+ await rename(`${outDir}/nw.exe`, `${outDir}/${app.name}.exe`);
41
+
42
+ await rcedit(`${outDir}/${app.name}.exe`, {
43
+ "file-version": app.version,
44
+ "icon": app.icon,
45
+ "product-version": app.version,
46
+ "version-string": versionString,
47
+ });
48
+ } catch (error) {
49
+ log.warn(
50
+ "Unable to modify EXE. Ensure WINE is installed or build in Windows",
51
+ );
52
+ log.error(error);
53
+ }
26
54
  };
27
55
 
28
56
  export { setWinConfig };
package/src/cli.js CHANGED
@@ -3,18 +3,22 @@
3
3
  import yargs from "yargs/yargs";
4
4
  import { hideBin } from "yargs/helpers";
5
5
 
6
- import { nwbuild } from "./nwbuild.js";
6
+ import nwbuild from "./nwbuild.js";
7
7
 
8
8
  const cli = yargs(hideBin(process.argv))
9
9
  .version(false)
10
10
  .command("[srcDir] [options]")
11
+ .option("mode", {
12
+ type: "string",
13
+ description: "`run` or `build` application",
14
+ })
11
15
  .option("version", {
12
16
  type: "string",
13
17
  description: "NW.js version",
14
18
  })
15
- .option("flavour", {
19
+ .option("flavor", {
16
20
  type: "string",
17
- description: "NW.js build flavour",
21
+ description: "NW.js build flavor",
18
22
  })
19
23
  .option("platform", {
20
24
  type: "string",
@@ -28,10 +32,9 @@ const cli = yargs(hideBin(process.argv))
28
32
  type: "string",
29
33
  description: "NW.js build artifacts",
30
34
  })
31
- .demandOption(["version", "flavour", "platform", "arch", "outDir"])
32
35
  .parse();
33
36
 
34
37
  nwbuild({
35
38
  ...cli,
36
- srcDir: cli._[0],
37
- });
39
+ srcDir: cli._.join(" "),
40
+ });
@@ -7,7 +7,7 @@ const bar = new progress.SingleBar({}, progress.Presets.rect);
7
7
 
8
8
  const download = (
9
9
  version,
10
- flavour,
10
+ flavor,
11
11
  platform,
12
12
  architecture,
13
13
  downloadUrl,
@@ -15,12 +15,11 @@ const download = (
15
15
  ) => {
16
16
  return new Promise((resolve, reject) => {
17
17
  if (downloadUrl !== "https://dl.nwjs.io") {
18
- console.log("Invalid download url. Please try again.");
19
- reject(1);
18
+ reject(new Error("Invalid download url. Please try again."));
20
19
  }
21
20
 
22
21
  let url = `${downloadUrl}/v${version}/nwjs${
23
- flavour === "sdk" ? "-sdk" : ""
22
+ flavor === "sdk" ? "-sdk" : ""
24
23
  }-v${version}-${platform}-${architecture}.${
25
24
  platform === "linux" ? "tar.gz" : "zip"
26
25
  }`;
@@ -36,13 +35,12 @@ const download = (
36
35
  });
37
36
 
38
37
  res.on("error", (error) => {
39
- console.log(error);
40
- reject(1);
38
+ reject(error);
41
39
  });
42
40
 
43
41
  res.on("end", () => {
44
42
  bar.stop();
45
- resolve(0);
43
+ resolve();
46
44
  });
47
45
 
48
46
  fs.mkdirSync(outDir, { recursive: true });
@@ -28,6 +28,10 @@ export const getReleaseInfo = async (version, cacheDir, manifestUrl) => {
28
28
  log.debug("Convert manifest data into JSON");
29
29
  let manifestJson = JSON.parse(manifestData);
30
30
  log.debug(`Search for ${version} specific release data`);
31
+ if (version === "latest" || version === "stable" || version === "lts") {
32
+ version = manifestData[version].slice(1);
33
+ }
34
+
31
35
  releaseData = manifestJson.versions.find(
32
36
  (release) => release.version === `v${version}`,
33
37
  );
package/src/nwbuild.js CHANGED
@@ -1,96 +1,197 @@
1
- import { access, constants, readFile, rm } from "node:fs/promises";
2
- import { cwd } from "node:process";
1
+ import { mkdir, readFile, rm } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+
4
+ import glob from "glob-promise";
3
5
 
4
6
  import { decompress } from "./get/decompress.js";
5
- import { develop } from "./run/develop.js";
6
7
  import { download } from "./get/download.js";
7
8
  import { getReleaseInfo } from "./get/getReleaseInfo.js";
8
9
  import { remove } from "./get/remove.js";
9
10
  import { packager } from "./bld/package.js";
11
+ import { develop } from "./run/develop.js";
12
+ import { isCached } from "./util/cache.js";
13
+ import { parse } from "./util/parse.js";
14
+ import { validate } from "./util/validate.js";
15
+
16
+ import { log } from "./log.js";
10
17
 
11
18
  /**
12
- * Options schema
13
- *
14
- * @typedef {Object} OptionsSchema
15
- * @property {string} srcDir
16
- * @property {string} cacheDir
17
- * @property {string} version
18
- * @property {"sdk" | "normal"} flavour
19
- * @property {"linux" | "osx" | "win"} platform
20
- * @property {"ia32" | "x64"} arch
21
- * @property {string} outDir
19
+ * @typedef {object} App
20
+ * @property {string} name Name of the application
21
+ * Linux configuration options
22
+ * @property {string} genericName Generic name of the application
23
+ * @property {boolean} noDisplay If true the application is not displayed
24
+ * @property {string} comment Tooltip for the entry, for example "View sites on the Internet".
25
+ * @property {string} icon Icon to display in file manager, menus, etc.
26
+ * @property {boolean} hidden TBD
27
+ * @property {string[]} onlyShowIn A list of strings identifying the desktop environments that should (/not) display a given desktop entry
28
+ * @property {string[]} notShowIn A list of strings identifying the desktop environments that should (/not) display a given desktop entry
29
+ * @property {boolean} dBusActivatable A boolean value specifying if D-Bus activation is supported for this application
30
+ * @property {string} tryExec Path to an executable file on disk used to determine if the program is actually installed
31
+ * @property {string} exec Program to execute, possibly with arguments.
32
+ * @property {string} path If entry is of type Application, the working directory to run the program in.
33
+ * @property {boolean} terminal Whether the program runs in a terminal window.
34
+ * @property {string[]} actions Identifiers for application actions.
35
+ * @property {string[]} mimeType The MIME type(s) supported by this application.
36
+ * @property {string[]} categories Categories in which the entry should be shown in a menu
37
+ * @property {string[]} implements A list of interfaces that this application implements.
38
+ * @property {string[]} keywords A list of strings which may be used in addition to other metadata to describe this entry.
39
+ * @property {boolean} startupNotify If true, it is KNOWN that the application will send a "remove" message when started with the DESKTOP_STARTUP_ID environment variable set. If false, it is KNOWN that the application does not work with startup notification at all.
40
+ * @property {string} startupWMClass If specified, it is known that the application will map at least one window with the given string as its WM class or WM name hin
41
+ * @property {boolean} prefersNonDefaultGPU If true, the application prefers to be run on a more powerful discrete GPU if available.
42
+ * @property {string} singleMainWindow If true, the application has a single main window, and does not support having an additional one opened.
43
+ * Windows configuration options
44
+ * @property {string} comments Additional information that should be displayed for diagnostic purposes.
45
+ * @property {string} company Company that produced the file—for example, Microsoft Corporation or Standard Microsystems Corporation, Inc. This string is required.
46
+ * @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.
47
+ * @property {string} fileVersion Version number of the file. For example, 3.10 or 5.00.RC2. This string is required.
48
+ * @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.
49
+ * @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.
50
+ * @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.
51
+ * @property {string} originalFilename Original name of the file, not including a path. This information enables an application to determine whether a file has been renamed by a user. The format of the name depends on the file system for which the file was created. This string is required.
52
+ * @property {string} privateBuild Information about a private version of the file—for example, Built by TESTER1 on \\TESTBED. This string should be present only if VS_FF_PRIVATEBUILD is specified in the fileflags parameter of the root block.
53
+ * @property {string} productName Name of the product with which the file is distributed. This string is required.
54
+ * @property {string} productVersion Version of the product with which the file is distributed—for example, 3.10 or 5.00.RC2. This string is required.
55
+ * @property {string} specialBuild Text that specifies how this version of the file differs from the standard version—for example, Private build for TESTER1 solving mouse problems on M250 and M250E computers. This string should be present only if VS_FF_SPECIALBUILD is specified in the fileflags parameter of the root block.
22
56
  */
23
57
 
24
58
  /**
25
- *
26
- * @param {OptionsSchema} obj
27
- * @return {void}
59
+ * @typedef {object} Options
60
+ * @property {string} srcDir Directory to hold NW app files unless or array of file glob patterns
61
+ * @property {"run" | "build"} mode Run or build application
62
+ * @property {"latest" | "stable" | string} version NW runtime version
63
+ * @property {"normal" | "sdk"} flavor NW runtime build flavor
64
+ * @property {"linux" | "osx" | "win"} platform NW supported platforms
65
+ * @property {"ia32" | "x64"} arch NW supported architectures
66
+ * @property {string} outDir Directory to store build artifacts
67
+ * @property {"./cache" | string} cacheDir Directory to store NW binaries
68
+ * @property {"https://dl.nwjs.io"} downloadUrl URI to download NW binaries from
69
+ * @property {"https://nwjs.io/versions"} manifestUrl URI to download manifest from
70
+ * @property {App} app Multi platform configuration options
71
+ * @property {boolean} cache If true the existing cache is used. Otherwise it removes and redownloads it.
72
+ * @property {boolean} zip If true the outDir directory is zipped
28
73
  */
29
- const nwbuild = async ({
30
- srcDir,
31
- cacheDir = `${cwd()}/cache`,
32
- version,
33
- flavour,
34
- platform,
35
- arch,
36
- outDir,
37
- // flags
38
- downloadUrl = "https://dl.nwjs.io",
39
- manifestUrl = "https://nwjs.io/versions",
40
- noCache = false,
41
- zip = false,
42
- run = false,
43
- }) => {
44
- let pkgPath = `${srcDir}/package.json`;
45
- let pkgExist = true;
46
- let pkgData = null;
47
74
 
75
+ /**
76
+ * Entry point for nw-builder application
77
+ *
78
+ * @param {...Options} options Options
79
+ * @return {Promise<undefined>}
80
+ */
81
+ const nwbuild = async (options) => {
82
+ let nwDir = "";
83
+ let nwPkg = undefined;
84
+ let cached;
85
+ let built;
86
+ let releaseInfo = {};
48
87
  try {
49
- await access(pkgPath, constants.F_OK);
50
- } catch (e) {
51
- pkgExist = false;
52
- }
88
+ let files = [];
89
+ let patterns = options.srcDir.split(" ");
53
90
 
54
- if (pkgExist === true) {
55
- pkgData = await readFile(pkgPath, "utf8");
56
- pkgData = JSON.parse(pkgData);
57
- if (pkgData.nwbuild !== undefined) {
58
- srcDir = pkgData.nwbuild.srcDir ?? srcDir;
59
- cacheDir = pkgData.nwbuild.cacheDir ?? cacheDir;
60
- version = pkgData.nwbuild.version ?? version;
61
- flavour = pkgData.nwbuild.flavour ?? flavour;
62
- platform = pkgData.nwbuild.platform ?? platform;
63
- arch = pkgData.nwbuild.arch ?? arch;
64
- outDir = pkgData.nwbuild.outDir ?? outDir;
91
+ for (const pattern of patterns) {
92
+ let contents = await glob(pattern);
93
+ for (const content of contents) {
94
+ if (basename(content) === "package.json" && nwPkg === undefined) {
95
+ nwPkg = JSON.parse(await readFile(content));
96
+ }
97
+ files.push(...contents);
98
+ }
65
99
  }
66
- }
67
100
 
68
- let nwDir = `${cacheDir}/nwjs${
69
- flavour === "sdk" ? "-sdk" : ""
70
- }-v${version}-${platform}-${arch}`;
101
+ if (files.length === 0) {
102
+ throw new Error(`The globbing pattern ${options.srcDir} is invalid.`);
103
+ }
71
104
 
72
- let fileExists = true;
105
+ // The name property is required for NW.js applications
106
+ if (nwPkg.name === undefined) {
107
+ throw new Error(`name property is missing from package.json`);
108
+ }
73
109
 
74
- try {
75
- await access(nwDir, constants.F_OK);
76
- } catch (e) {
77
- fileExists = false;
78
- }
110
+ // The main property is required for NW.js applications
111
+ if (nwPkg.main === undefined) {
112
+ throw new Error(`main property is missing from package.json`);
113
+ }
79
114
 
80
- if (noCache === true || fileExists === false) {
81
- await rm(nwDir, { force: true, recursive: true });
82
- await download(version, flavour, platform, arch, downloadUrl, cacheDir);
83
- await decompress(platform, cacheDir);
84
- await remove(platform, cacheDir);
85
- }
115
+ // If the nwbuild property exists in srcDir/package.json, then they take precedence
116
+ if (typeof nwPkg.nwbuild === "object") {
117
+ options = { ...nwPkg.nwbuild };
118
+ }
119
+ if (typeof nwPkg.nwbuild === "undefined") {
120
+ log.debug(`nwbuild property is not defined in package.json`);
121
+ } else {
122
+ throw new Error(
123
+ `nwbuild property in the package.json is of type ${typeof nwPkg.nwbuild}. Expected type object.`,
124
+ );
125
+ }
126
+
127
+ // Parse options, set required values to undefined and flags with default values unless specified by user
128
+ options = await parse(options, nwPkg);
86
129
 
87
- let releaseInfo = await getReleaseInfo(version, cacheDir, manifestUrl);
130
+ // Variable to store nwDir file path
131
+ nwDir = `${options.cacheDir}/nwjs${
132
+ options.flavor === "sdk" ? "-sdk" : ""
133
+ }-v${options.version}-${options.platform}-${options.arch}`;
134
+
135
+ // Create cacheDir if it does not exist
136
+ cached = await isCached(nwDir);
137
+ if (cached === false) {
138
+ await mkdir(nwDir, { recursive: true });
139
+ }
140
+
141
+ // Create outDir if it does not exist
142
+ built = await isCached(options.outDir);
143
+ if (built === false) {
144
+ await mkdir(options.outDir, { recursive: true });
145
+ }
88
146
 
89
- if (run === true) {
90
- await develop(srcDir, nwDir, platform);
91
- } else {
92
- await packager(srcDir, nwDir, outDir, platform, zip, releaseInfo);
147
+ // Validate options.version here
148
+ // We need to do this to get the version specific release info
149
+ releaseInfo = await getReleaseInfo(
150
+ options.version,
151
+ options.cacheDir,
152
+ options.manifestUrl,
153
+ );
154
+
155
+ validate(options, releaseInfo);
156
+
157
+ // Remove cached NW binary
158
+ if (options.cache === false && cached === true) {
159
+ log.debug("Remove cached NW binary");
160
+ await rm(nwDir, { force: true, recursive: true });
161
+ }
162
+ // Download relevant NW.js binaries
163
+ if (cached === false) {
164
+ log.debug("Download relevant NW.js binaries");
165
+ await download(
166
+ options.version,
167
+ options.flavor,
168
+ options.platform,
169
+ options.arch,
170
+ options.downloadUrl,
171
+ options.cacheDir,
172
+ );
173
+ await decompress(options.platform, options.cacheDir);
174
+ await remove(options.platform, options.cacheDir);
175
+ }
176
+
177
+ if (options.mode === "run") {
178
+ await develop(options.srcDir, nwDir, options.platform, options.argv);
179
+ }
180
+ if (options.mode === "build") {
181
+ await packager(
182
+ files,
183
+ nwDir,
184
+ options.outDir,
185
+ options.platform,
186
+ options.zip,
187
+ releaseInfo,
188
+ options.app,
189
+ );
190
+ }
191
+ } catch (error) {
192
+ log.error(error);
193
+ return error;
93
194
  }
94
195
  };
95
196
 
96
- export { nwbuild };
197
+ export default nwbuild;
@@ -1,14 +1,30 @@
1
1
  import { execute } from "./execute.js";
2
2
  import { getPlatformSpecificName } from "./getPlatformSpecificName.js";
3
3
 
4
- const develop = async (srcDir, nwDir, platform) => {
5
- if (getPlatformSpecificName(platform) === null) {
6
- console.log("Unsupported platform.");
7
- return 1;
8
- }
4
+ import { log } from "../log.js";
9
5
 
10
- await execute(srcDir, `${nwDir}/${getPlatformSpecificName(platform)}`);
11
- return 0;
6
+ /**
7
+ * Runs the NW app by spawning a child process
8
+ *
9
+ * @param {string} srcDir The directory to run from
10
+ * @param {string} nwDir The directory to run nw.js from
11
+ * @param {"win" | "osx" | "linux"} platform The platform to run for
12
+ * @param {string[]} argv The arguments to pass to the nw.js development server
13
+ * @return {Promise<undefined>}
14
+ */
15
+ const develop = async (srcDir, nwDir, platform, argv) => {
16
+ try {
17
+ if (getPlatformSpecificName(platform) === null) {
18
+ throw new Error("Unsupported platform.");
19
+ }
20
+ await execute(
21
+ srcDir,
22
+ `${nwDir}/${getPlatformSpecificName(platform)}`,
23
+ argv,
24
+ );
25
+ } catch (error) {
26
+ log.error(error);
27
+ }
12
28
  };
13
29
 
14
30
  export { develop };
@@ -1,16 +1,32 @@
1
- import child_process from "node:child_process";
1
+ import { spawn } from "node:child_process";
2
2
 
3
- const execute = (srcDir, nwPath) => {
3
+ import { log } from "../log.js";
4
+
5
+ /**
6
+ * Executes the NW.js process
7
+ * @param {string} srcDir The source directory
8
+ * @param {string} nwPath The path to the NW.js executable
9
+ * @param {string} argv The arguments to pass to the NW.js process
10
+ * @return {Promise<undefined>} The exit code of the NW.js process
11
+ * @throws {Error} - If the NW.js process fails to start
12
+ */
13
+ const execute = (srcDir, nwPath, argv) => {
4
14
  return new Promise((resolve, reject) => {
5
- const nwProcess = child_process.spawn(nwPath, [srcDir]);
15
+ // It is assumed that the first glob pattern p contains the package.json at p/package.json
16
+ srcDir = srcDir.split(" ")[0];
17
+ srcDir = srcDir.replace(/\*[/*]*/, "");
18
+ const nwProcess = spawn(nwPath, [srcDir.concat(argv)], {
19
+ detached: true,
20
+ windowsHide: true,
21
+ });
6
22
 
7
23
  nwProcess.on("close", () => {
8
- resolve(0);
24
+ resolve();
9
25
  });
10
26
 
11
27
  nwProcess.on("error", (error) => {
12
- console.log(error);
13
- reject(1);
28
+ log.error(error);
29
+ reject(error);
14
30
  });
15
31
  });
16
32
  };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Get user's computer architecture
3
+ *
4
+ * @param {string} arch Node's process.arch
5
+ * @return {"ia32"| "x64" | "string"} NW.js supported architectures
6
+ */
7
+ export const getArch = (arch) => {
8
+ return arch;
9
+ };
@@ -0,0 +1,9 @@
1
+ import { getArch } from "./arch.js";
2
+
3
+ test("x32 arch support", () => {
4
+ expect(getArch("ia32")).toBe("ia32");
5
+ });
6
+
7
+ test("x64 arch support", () => {
8
+ expect(getArch("x64")).toBe("x64");
9
+ });
@@ -0,0 +1,17 @@
1
+ import { access, constants } from "node:fs/promises";
2
+
3
+ /**
4
+ * Check if NW binaries are cached
5
+ *
6
+ * @param {string} nwDir Path to cached NW binaries
7
+ * @return {Promise<boolean>} Boolean value to denote if cache exists or not
8
+ */
9
+ export const isCached = async (nwDir) => {
10
+ let exists = true;
11
+ try {
12
+ await access(nwDir, constants.F_OK);
13
+ } catch (e) {
14
+ exists = false;
15
+ }
16
+ return exists;
17
+ };
@@ -0,0 +1,9 @@
1
+ import { isCached } from "./cache.js";
2
+
3
+ test("directory does not exist", () => {
4
+ expect(isCached("")).resolves.toBe(false);
5
+ });
6
+
7
+ test("directory exists", () => {
8
+ expect(isCached("./test/fixture/cacheDir")).resolves.toBe(true);
9
+ });
@@ -0,0 +1,70 @@
1
+ import { arch, cwd, platform } from "node:process";
2
+
3
+ import { getArch } from "./arch.js";
4
+ import { getPlatform } from "./platform.js";
5
+
6
+ /**
7
+ * Parse options
8
+ *
9
+ * @param {import("../nwbuild").Options} options Options
10
+ * @param {object} pkg Package.json as JSON
11
+ * @return {Promise<object>} Options
12
+ */
13
+ export const parse = async (options, pkg) => {
14
+ if (typeof pkg?.nwbuild === "object") {
15
+ options = { ...pkg.nwbuild };
16
+ }
17
+
18
+ options.srcDir = options.srcDir ?? "./";
19
+ options.mode = options.mode ?? "build";
20
+ options.version = options.version ?? "latest";
21
+ options.flavor = options.flavor || "normal";
22
+ options.platform = options.platform ?? getPlatform(platform);
23
+ options.arch = options.arch ?? getArch(arch);
24
+ options.outDir = options.outDir ?? "./out";
25
+ options.cacheDir = options.cacheDir ?? `${cwd()}/cache`;
26
+ options.downloadUrl = options.downloadUrl ?? "https://dl.nwjs.io";
27
+ options.manifestUrl = options.manifestUrl ?? "https://nwjs.io/versions";
28
+ options.app = {};
29
+ options.argv = options.argv ?? [];
30
+ // linux desktop entry file configurations options
31
+ options.app.name = options.app.name ?? pkg.name;
32
+ options.app.genericName = options.app.genericName ?? undefined;
33
+ options.app.noDisplay = options.app.noDisplay ?? undefined;
34
+ options.app.comment = options.app.comment ?? undefined;
35
+ options.app.icon = options.app.icon ?? undefined;
36
+ options.app.hidden = options.app.hidden ?? undefined;
37
+ options.app.onlyShowIn = options.app.onlyShowIn ?? undefined;
38
+ options.app.notShowIn = options.app.notShowIn ?? undefined;
39
+ options.app.dBusActivatable = options.app.dBusActivatable ?? undefined;
40
+ options.app.tryExec = options.app.tryExec ?? undefined;
41
+ options.app.exec = options.app.name ?? undefined;
42
+ options.app.path = options.app.path ?? undefined;
43
+ options.app.terminal = options.app.terminal ?? undefined;
44
+ options.app.actions = options.app.actions ?? undefined;
45
+ options.app.mimeType = options.app.mimeType ?? undefined;
46
+ options.app.categories = options.app.categories ?? undefined;
47
+ options.app.implements = options.app.implements ?? undefined;
48
+ options.app.keywords = options.app.keywords ?? undefined;
49
+ options.app.startupNotify = options.app.startupNotify ?? undefined;
50
+ options.app.startupWMClass = options.app.startupWMClass ?? undefined;
51
+ options.app.prefersNonDefaultGPU =
52
+ options.app.prefersNonDefaultGPU ?? undefined;
53
+ options.app.singleMainWindow = options.app.singleMainWindow ?? undefined;
54
+ // windows configuration options
55
+ options.app.comments = options.app.comments ?? undefined;
56
+ options.app.company = options.app.company ?? pkg.author;
57
+ options.app.fileDescription = options.app.fileDescription ?? pkg.description;
58
+ options.app.fileVersion = options.app.fileVersion ?? pkg.version;
59
+ options.app.internalName = options.app.internalName ?? pkg.name;
60
+ options.app.legalCopyright = options.app.legalCopyright ?? undefined;
61
+ options.app.legalTrademark = options.app.legalTrademark ?? undefined;
62
+ options.app.originalFilename = options.app.originalFilename ?? pkg.name;
63
+ options.app.privateBuild = options.app.privateBuild ?? undefined;
64
+ options.app.productName = options.app.productName ?? pkg.name;
65
+ options.app.productVersion = options.app.productVersion ?? pkg.version;
66
+ options.app.specialBuild = options.app.specialBuild ?? undefined;
67
+ options.cache = options.cache ?? true;
68
+ options.zip = options.zip ?? false;
69
+ return options;
70
+ };
@@ -0,0 +1,5 @@
1
+ import { parse } from "./parse.js";
2
+
3
+ test("no options passed", () => {
4
+ expect(parse({})).rejects.toThrow();
5
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Get user's computer platform
3
+ *
4
+ * @param {string} platform Node's process.platform
5
+ * @return {"osx"| "win" | "linux" | "string"} Platform types
6
+ */
7
+ export const getPlatform = (platform) => {
8
+ switch (platform) {
9
+ case "darwin":
10
+ return "osx";
11
+ case "win32":
12
+ return "win";
13
+ case "linux":
14
+ return "linux";
15
+ default:
16
+ return platform;
17
+ }
18
+ };