nw-builder 4.5.2 → 4.5.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/util.js CHANGED
@@ -1,15 +1,19 @@
1
1
  import console from "node:console";
2
- import fsm from "node:fs/promises";
2
+ import fs from "node:fs";
3
3
  import https from "node:https";
4
4
  import path from "node:path";
5
+ import process from "node:process";
6
+ import stream from "node:stream";
5
7
 
6
8
  import * as GlobModule from "glob";
9
+ import semver from "semver";
10
+ import yauzl from "yauzl-promise";
7
11
 
8
12
  /**
9
13
  * Get manifest (array of NW release metadata) from URL
10
14
  *
11
15
  * @param {string} manifestUrl Url to manifest
12
- * @return {Promise <object | undefined>}
16
+ * @returns {Promise<object | undefined>} - Manifest object
13
17
  */
14
18
  function getManifest(manifestUrl) {
15
19
  let chunks = undefined;
@@ -44,7 +48,7 @@ function getManifest(manifestUrl) {
44
48
  * @param {string} arch NW architecture
45
49
  * @param {string} cacheDir Directory to store NW binaries
46
50
  * @param {string} manifestUrl Url to manifest
47
- * @return {object} Version specific release info
51
+ * @returns {object} Version specific release info
48
52
  */
49
53
  async function getReleaseInfo(
50
54
  version,
@@ -64,10 +68,10 @@ async function getReleaseInfo(
64
68
  try {
65
69
  const data = await getManifest(manifestUrl);
66
70
  if (data !== undefined) {
67
- await fsm.writeFile(manifestPath, data.slice(9));
71
+ await fs.promises.writeFile(manifestPath, data.slice(9));
68
72
  }
69
73
 
70
- let manifest = JSON.parse(await fsm.readFile(manifestPath));
74
+ let manifest = JSON.parse(await fs.promises.readFile(manifestPath));
71
75
  if (version === "latest" || version === "stable" || version === "lts") {
72
76
  // Remove leading "v" from version string
73
77
  version = manifest[version].slice(1);
@@ -120,7 +124,7 @@ const replaceFfmpeg = async (platform, nwDir) => {
120
124
  const src = path.resolve(nwDir, ffmpegFile);
121
125
  if (platform === "linux") {
122
126
  const dest = path.resolve(nwDir, "lib", ffmpegFile);
123
- await fsm.copyFile(src, dest);
127
+ await fs.promises.copyFile(src, dest);
124
128
  } else if (platform === "win") {
125
129
  // don't do anything for windows because the extracted file is already in the correct path
126
130
  // await copyFile(src, path.resolve(nwDir, ffmpegFile));
@@ -137,7 +141,7 @@ const replaceFfmpeg = async (platform, nwDir) => {
137
141
  );
138
142
 
139
143
  try {
140
- await fsm.copyFile(src, dest);
144
+ await fs.promises.copyFile(src, dest);
141
145
  } catch (e) {
142
146
  //some versions of node/macOS complain about destination being a file, and others complain when it is only a directory.
143
147
  //the only thing I can think to do is to try both
@@ -150,11 +154,23 @@ const replaceFfmpeg = async (platform, nwDir) => {
150
154
  "Versions",
151
155
  "Current",
152
156
  );
153
- await fsm.copyFile(src, dest);
157
+ await fs.promises.copyFile(src, dest);
154
158
  }
155
159
  }
156
160
  };
157
161
 
162
+ /**
163
+ * Glob files
164
+ *
165
+ * @async
166
+ * @function
167
+ *
168
+ * @param {object} options - glob file options
169
+ * @param {string | string[]} options.srcDir - app src dir
170
+ * @param {boolean} options.glob - glob flag
171
+ * @returns {Promise<string[]>} - Returns array of file paths
172
+
173
+ */
158
174
  async function globFiles({
159
175
  srcDir,
160
176
  glob,
@@ -173,27 +189,321 @@ async function globFiles({
173
189
  return files;
174
190
  }
175
191
 
192
+ /**
193
+ * @async
194
+ * @function
195
+ * @param {object} options - node manifest options
196
+ * @param {string | string []} options.srcDir - src dir
197
+ * @param {boolean} options.glob - glob flag
198
+ * @returns {object} - Node manifest
199
+ */
176
200
  async function getNodeManifest({
177
201
  srcDir, glob
178
202
  }) {
179
203
  let manifest;
180
204
  let files;
181
205
  if (glob) {
182
- files = await globFiles({srcDir, glob});
206
+ files = await globFiles({ srcDir, glob });
183
207
  for (const file of files) {
184
208
  if (path.basename(file) === "package.json" && manifest === undefined) {
185
- manifest = JSON.parse(await fsm.readFile(file));
209
+ manifest = JSON.parse(await fs.promises.readFile(file));
186
210
  }
187
211
  }
188
212
  } else {
189
- manifest = JSON.parse(await fsm.readFile(path.resolve(srcDir, "package.json")));
213
+ manifest = JSON.parse(await fs.promises.readFile(path.resolve(srcDir, "package.json")));
190
214
  }
191
215
 
192
216
  if (manifest === undefined) {
193
217
  throw new Error("package.json not found in srcDir file glob patterns.");
194
218
  }
195
-
219
+
196
220
  return manifest;
197
221
  }
198
222
 
199
- export default { getReleaseInfo, PLATFORM_KV, ARCH_KV, EXE_NAME, replaceFfmpeg, globFiles, getNodeManifest };
223
+ /**
224
+ * Parse options
225
+ *
226
+ * @param {import("../../index.js").Options} options Options
227
+ * @param {object} pkg Package.json as JSON
228
+ * @returns {Promise<object>} Options
229
+ */
230
+ export const parse = async (options, pkg) => {
231
+ options = options ?? {};
232
+ options.mode = options.mode ?? "build";
233
+
234
+ options.version = options.version ?? "latest";
235
+ options.flavor = options.flavor ?? "normal";
236
+ options.platform = options.platform ?? PLATFORM_KV[process.platform];
237
+ options.arch = options.arch ?? ARCH_KV[process.arch];
238
+ options.downloadUrl = options.downloadUrl ?? "https://dl.nwjs.io";
239
+ options.manifestUrl = options.manifestUrl ?? "https://nwjs.io/versions";
240
+ options.cacheDir = options.cacheDir ?? "./cache";
241
+ options.cache = options.cache ?? true;
242
+ options.ffmpeg = options.ffmpeg ?? false;
243
+ options.logLevel = options.logLevel ?? "info";
244
+
245
+ if (options.mode === "get") {
246
+ return { ...options };
247
+ }
248
+
249
+ options.argv = options.argv ?? [];
250
+ options.glob = options.glob ?? true;
251
+ options.srcDir = options.srcDir ?? (options.glob ? "./*" : ".");
252
+
253
+ if (options.mode === "run") {
254
+ return { ...options };
255
+ }
256
+
257
+ options.outDir = path.resolve(options.outDir ?? "./out");
258
+ options.zip = options.zip ?? false;
259
+
260
+ options.managedManifest = options.managedManifest ?? false;
261
+ options.nativeAddon = options.nativeAddon ?? false;
262
+
263
+ options.app = options.app ?? {};
264
+ options.app.name = options.app.name ?? pkg.name;
265
+ options.app.icon = options.app.icon ?? undefined;
266
+
267
+ // TODO(#737): move this out
268
+ if (options.platform === "linux") {
269
+ // linux desktop entry file configurations options
270
+ options.app.genericName = options.app.genericName ?? undefined;
271
+ options.app.noDisplay = options.app.noDisplay ?? undefined;
272
+ options.app.comment = options.app.comment ?? undefined;
273
+ options.app.hidden = options.app.hidden ?? undefined;
274
+ options.app.onlyShowIn = options.app.onlyShowIn ?? undefined;
275
+ options.app.notShowIn = options.app.notShowIn ?? undefined;
276
+ options.app.dBusActivatable = options.app.dBusActivatable ?? undefined;
277
+ options.app.tryExec = options.app.tryExec ?? undefined;
278
+ options.app.exec = options.app.name ?? undefined;
279
+ options.app.path = options.app.path ?? undefined;
280
+ options.app.terminal = options.app.terminal ?? undefined;
281
+ options.app.actions = options.app.actions ?? undefined;
282
+ options.app.mimeType = options.app.mimeType ?? undefined;
283
+ options.app.categories = options.app.categories ?? undefined;
284
+ options.app.implements = options.app.implements ?? undefined;
285
+ options.app.keywords = options.app.keywords ?? undefined;
286
+ options.app.startupNotify = options.app.startupNotify ?? undefined;
287
+ options.app.startupWMClass = options.app.startupWMClass ?? undefined;
288
+ options.app.prefersNonDefaultGPU =
289
+ options.app.prefersNonDefaultGPU ?? undefined;
290
+ options.app.singleMainWindow = options.app.singleMainWindow ?? undefined;
291
+ }
292
+ if (options.platform === "win") {
293
+ // windows configuration options
294
+ options.app.version = options.app.version ?? pkg.version;
295
+ options.app.comments = options.app.comments ?? undefined;
296
+ options.app.company = options.app.company ?? pkg.author;
297
+ options.app.fileDescription =
298
+ options.app.fileDescription ?? pkg.description;
299
+ options.app.fileVersion = options.app.fileVersion ?? pkg.version;
300
+ options.app.internalName = options.app.internalName ?? pkg.name;
301
+ options.app.legalCopyright = options.app.legalCopyright ?? undefined;
302
+ options.app.legalTrademark = options.app.legalTrademark ?? undefined;
303
+ options.app.originalFilename = options.app.originalFilename ?? pkg.name;
304
+ options.app.privateBuild = options.app.privateBuild ?? undefined;
305
+ options.app.productName = options.app.productName ?? pkg.name;
306
+ options.app.productVersion = options.app.productVersion ?? pkg.version;
307
+ options.app.specialBuild = options.app.specialBuild ?? undefined;
308
+ }
309
+
310
+ if (options.platform === "osx") {
311
+ options.app.LSApplicationCategoryType =
312
+ options.app.LSApplicationCategoryType ?? undefined;
313
+ options.app.CFBundleIdentifier =
314
+ options.app.CFBundleIdentifier ?? options.app.name;
315
+ options.app.CFBundleName = options.app.CFBundleName ?? pkg.name;
316
+ options.app.CFBundleDisplayName =
317
+ options.app.CFBundleDisplayName ?? pkg.name;
318
+ options.app.CFBundleSpokenName = options.app.CFBundleSpokenName ?? pkg.name;
319
+ options.app.CFBundleShortVersionString =
320
+ options.app.CFBundleVersion ?? pkg.version;
321
+ options.app.CFBundleVersion =
322
+ options.app.CFBundleShortVersionString ?? pkg.version;
323
+ options.app.NSHumanReadableCopyright =
324
+ options.app.NSHumanReadableCopyright ?? undefined;
325
+ }
326
+
327
+ return { ...options };
328
+ };
329
+
330
+ /**
331
+ * Validate options
332
+ *
333
+ * @param {import("../index.js").Options} options Options
334
+ * @param {object} releaseInfo Version specific NW release info
335
+ * @returns {Promise<undefined>} Return undefined if options are valid
336
+ * @throws {Error} Throw error if options are invalid
337
+ */
338
+ export const validate = async (options, releaseInfo) => {
339
+ if (!["get", "run", "build"].includes(options.mode)) {
340
+ throw new Error(
341
+ `Unknown mode ${options.mode}. Expected "get", "run" or "build".`,
342
+ );
343
+ }
344
+ if (typeof releaseInfo === "undefined") {
345
+ throw new Error(
346
+ "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.",
347
+ );
348
+ }
349
+ if (!releaseInfo.flavors.includes(options.flavor)) {
350
+ throw new Error(
351
+ `${options.flavor} flavor is not supported by this download server.`,
352
+ );
353
+ }
354
+ if (
355
+ options.platform &&
356
+ options.arch &&
357
+ !releaseInfo.files.includes(`${options.platform}-${options.arch}`)
358
+ ) {
359
+ throw new Error(
360
+ `Platform ${options.platform} and architecture ${options.arch} is not supported by this download server.`,
361
+ );
362
+ }
363
+ // if (typeof options.cacheDir !== "string") {
364
+ // throw new Error("Expected options.cacheDir to be a string. Got " + typeof options.cacheDir);
365
+ // }
366
+ if (typeof options.cache !== "boolean") {
367
+ return new Error(
368
+ "Expected options.cache to be a boolean. Got " + typeof options.cache,
369
+ );
370
+ }
371
+ if (typeof options.ffmpeg !== "boolean") {
372
+ return new Error(
373
+ "Expected options.ffmpeg to be a boolean. Got " + typeof options.ffmpeg,
374
+ );
375
+ }
376
+
377
+ if (
378
+ options.logLevel !== "error" &&
379
+ options.logLevel !== "warn" &&
380
+ options.logLevel !== "info" &&
381
+ options.logLevel !== "debug"
382
+ ) {
383
+ throw new Error(
384
+ "Expected options.logLevel to be 'error', 'warn', 'info' or 'debug'. Got " +
385
+ options.logLevel,
386
+ );
387
+ }
388
+
389
+ if (options.mode === "get") {
390
+ return undefined;
391
+ }
392
+ if (Array.isArray(options.argv)) {
393
+ return new Error(
394
+ "Expected options.argv to be an array. Got " + typeof options.argv,
395
+ );
396
+ }
397
+ if (typeof options.glob !== "boolean") {
398
+ return new Error(
399
+ "Expected options.glob to be a boolean. Got " + typeof options.glob,
400
+ );
401
+ }
402
+
403
+ if (options.srcDir) {
404
+ await fs.promises.readdir(options.srcDir);
405
+ }
406
+
407
+ if (options.mode === "run") {
408
+ return undefined;
409
+ }
410
+
411
+ if (options.outDir) {
412
+ await fs.promises.readdir(options.outDir);
413
+ }
414
+
415
+ if (
416
+ typeof options.managedManifest !== "boolean" &&
417
+ typeof options.managedManifest !== "object" &&
418
+ typeof options.managedManifest !== "string"
419
+ ) {
420
+ return new Error(
421
+ "Expected options.managedManifest to be a boolean, object or string. Got " +
422
+ typeof options.managedManifest,
423
+ );
424
+ }
425
+
426
+ if (typeof options.managedManifest === "object") {
427
+ if (options.managedManifest.name === undefined) {
428
+ return new Error("Expected NW.js Manifest to have a `name` property.");
429
+ }
430
+ if (options.managedManifest.main === undefined) {
431
+ return new Error("Expected NW.js Manifest to have a `main` property.");
432
+ }
433
+ }
434
+
435
+ if (typeof options.nativeAddon !== "boolean") {
436
+ if (typeof options.nativeAddon !== "boolean" && typeof options.nativeAddon !== "string") {
437
+ return new Error("Expected options.nativeAddon to be a boolean or string type. Got " + typeof options.nativeAddon);
438
+ }
439
+
440
+ if (semver.parse(options.version).minor >= "83" && options.nativeAddon !== false) {
441
+ return new Error("Native addons are not supported for NW.js v0.82.0 and below");
442
+ }
443
+ }
444
+
445
+ // TODO: Validate app options
446
+ return undefined;
447
+ };
448
+
449
+ /**
450
+ * Get path to various NW specific file paths.
451
+ *
452
+ * @async
453
+ * @function
454
+ *
455
+ * @param {"chromedriver"} type - NW specific file or directory
456
+ * @param {object} options - nwbuild options
457
+ * @returns {string} - Path to chromedriver
458
+ * @throws {Error}
459
+ */
460
+ async function getPath(type, options) {
461
+ if (type === "chromedriver") {
462
+ return path.resolve(
463
+ options.cacheDir,
464
+ `nwjs${options.flavor === "sdk" ? "-sdk" : ""}-v${options.version}-${options.platform
465
+ }-${options.arch}`,
466
+ `chromedriver${options.platform === "win" ? ".exe" : ""}`,
467
+ );
468
+ } else {
469
+ throw new Error("Invalid type. Expected `chromedriver` but got ", type);
470
+ }
471
+ }
472
+
473
+ /**
474
+ * Wrapper for unzipping using `yauzl-promise`.
475
+ *
476
+ * @async
477
+ * @function
478
+ * @param {string} nwZip - file path to .zip file
479
+ * @param {string} cacheDir - directory to unzip in
480
+ */
481
+ async function unzip(nwZip, cacheDir) {
482
+ const zip = await yauzl.open(nwZip, {
483
+ supportMacArchive: false
484
+ });
485
+ try {
486
+ for await (const entry of zip) {
487
+ const fullEntryPath = path.resolve(cacheDir, entry.filename);
488
+
489
+ if (entry.filename.endsWith("/")) {
490
+ // Create directory
491
+ await fs.promises.mkdir(fullEntryPath, { recursive: true });
492
+ } else {
493
+ // Create the file's directory first, if it doesn't exist
494
+ const directory = path.dirname(fullEntryPath);
495
+ await fs.promises.mkdir(directory, { recursive: true });
496
+
497
+ const readStream = await entry.openReadStream();
498
+ const writeStream = fs.createWriteStream(fullEntryPath);
499
+ await stream.promises.pipeline(readStream, writeStream);
500
+ }
501
+ }
502
+ } catch (e) {
503
+ console.error(e);
504
+ } finally {
505
+ await zip.close();
506
+ }
507
+ }
508
+
509
+ export default { getReleaseInfo, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, replaceFfmpeg, globFiles, getNodeManifest, parse, unzip, validate };
@@ -1,4 +0,0 @@
1
- 68c68
2
- < 'v8_host_byteorder': '<!(python -c "import sys; print sys.byteorder")',
3
- ---
4
- > 'v8_host_byteorder': '<!(python3 -c "import sys; print(sys.byteorder)")',
package/src/util/parse.js DELETED
@@ -1,112 +0,0 @@
1
- import { resolve } from "node:path";
2
- import { arch, platform } from "node:process";
3
-
4
- import util from "../util.js";
5
-
6
- /**
7
- * Parse options
8
- *
9
- * @param {import("../../index.js").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
- options = options ?? {};
15
- options.mode = options.mode ?? "build";
16
-
17
- options.version = options.version ?? "latest";
18
- options.flavor = options.flavor ?? "normal";
19
- options.platform = options.platform ?? util.PLATFORM_KV[platform];
20
- options.arch = options.arch ?? util.ARCH_KV[arch];
21
- options.downloadUrl = options.downloadUrl ?? "https://dl.nwjs.io";
22
- options.manifestUrl = options.manifestUrl ?? "https://nwjs.io/versions";
23
- options.cacheDir = options.cacheDir ?? "./cache";
24
- options.cache = options.cache ?? true;
25
- options.ffmpeg = options.ffmpeg ?? false;
26
- options.logLevel = options.logLevel ?? "info";
27
-
28
- if (options.mode === "get") {
29
- return { ...options };
30
- }
31
-
32
- options.argv = options.argv ?? [];
33
- options.glob = options.glob ?? true;
34
- options.srcDir = options.srcDir ?? (options.glob ? "./*" : ".");
35
-
36
- if (options.mode === "run") {
37
- return { ...options };
38
- }
39
-
40
- options.outDir = resolve(options.outDir ?? "./out");
41
- options.zip = options.zip ?? false;
42
-
43
- options.managedManifest = options.managedManifest ?? false;
44
- // Node Native addons are disabled for now. See https://github.com/nwutils/nw-builder/pull/993
45
- options.nativeAddon = false;
46
-
47
- options.app = options.app ?? {};
48
- options.app.name = options.app.name ?? pkg.name;
49
- options.app.icon = options.app.icon ?? undefined;
50
-
51
- // TODO(#737): move this out
52
- if (options.platform === "linux") {
53
- // linux desktop entry file configurations options
54
- options.app.genericName = options.app.genericName ?? undefined;
55
- options.app.noDisplay = options.app.noDisplay ?? undefined;
56
- options.app.comment = options.app.comment ?? undefined;
57
- options.app.hidden = options.app.hidden ?? undefined;
58
- options.app.onlyShowIn = options.app.onlyShowIn ?? undefined;
59
- options.app.notShowIn = options.app.notShowIn ?? undefined;
60
- options.app.dBusActivatable = options.app.dBusActivatable ?? undefined;
61
- options.app.tryExec = options.app.tryExec ?? undefined;
62
- options.app.exec = options.app.name ?? undefined;
63
- options.app.path = options.app.path ?? undefined;
64
- options.app.terminal = options.app.terminal ?? undefined;
65
- options.app.actions = options.app.actions ?? undefined;
66
- options.app.mimeType = options.app.mimeType ?? undefined;
67
- options.app.categories = options.app.categories ?? undefined;
68
- options.app.implements = options.app.implements ?? undefined;
69
- options.app.keywords = options.app.keywords ?? undefined;
70
- options.app.startupNotify = options.app.startupNotify ?? undefined;
71
- options.app.startupWMClass = options.app.startupWMClass ?? undefined;
72
- options.app.prefersNonDefaultGPU =
73
- options.app.prefersNonDefaultGPU ?? undefined;
74
- options.app.singleMainWindow = options.app.singleMainWindow ?? undefined;
75
- }
76
- if (options.platform === "win") {
77
- // windows configuration options
78
- options.app.version = options.app.version ?? pkg.version;
79
- options.app.comments = options.app.comments ?? undefined;
80
- options.app.company = options.app.company ?? pkg.author;
81
- options.app.fileDescription =
82
- options.app.fileDescription ?? pkg.description;
83
- options.app.fileVersion = options.app.fileVersion ?? pkg.version;
84
- options.app.internalName = options.app.internalName ?? pkg.name;
85
- options.app.legalCopyright = options.app.legalCopyright ?? undefined;
86
- options.app.legalTrademark = options.app.legalTrademark ?? undefined;
87
- options.app.originalFilename = options.app.originalFilename ?? pkg.name;
88
- options.app.privateBuild = options.app.privateBuild ?? undefined;
89
- options.app.productName = options.app.productName ?? pkg.name;
90
- options.app.productVersion = options.app.productVersion ?? pkg.version;
91
- options.app.specialBuild = options.app.specialBuild ?? undefined;
92
- }
93
-
94
- if (options.platform === "osx") {
95
- options.app.LSApplicationCategoryType =
96
- options.app.LSApplicationCategoryType ?? undefined;
97
- options.app.CFBundleIdentifier =
98
- options.app.CFBundleIdentifier ?? options.app.name;
99
- options.app.CFBundleName = options.app.CFBundleName ?? pkg.name;
100
- options.app.CFBundleDisplayName =
101
- options.app.CFBundleDisplayName ?? pkg.name;
102
- options.app.CFBundleSpokenName = options.app.CFBundleSpokenName ?? pkg.name;
103
- options.app.CFBundleShortVersionString =
104
- options.app.CFBundleVersion ?? pkg.version;
105
- options.app.CFBundleVersion =
106
- options.app.CFBundleShortVersionString ?? pkg.version;
107
- options.app.NSHumanReadableCopyright =
108
- options.app.NSHumanReadableCopyright ?? undefined;
109
- }
110
-
111
- return { ...options };
112
- };
@@ -1,117 +0,0 @@
1
- import { readdir } from "node:fs/promises";
2
-
3
- /**
4
- * Validate options
5
- *
6
- * @param {import("../index.js").Options} options Options
7
- * @param {object} releaseInfo Version specific NW release info
8
- * @return {Promise<undefined>} Return undefined if options are valid
9
- * @throws {Error} Throw error if options are invalid
10
- */
11
- export const validate = async (options, releaseInfo) => {
12
- if (!["get", "run", "build"].includes(options.mode)) {
13
- throw new Error(
14
- `Unknown mode ${options.mode}. Expected "get", "run" or "build".`,
15
- );
16
- }
17
- if (typeof releaseInfo === "undefined") {
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.",
20
- );
21
- }
22
- if (!releaseInfo.flavors.includes(options.flavor)) {
23
- throw new Error(
24
- `${options.flavor} flavor is not supported by this download server.`,
25
- );
26
- }
27
- if (
28
- options.platform &&
29
- options.arch &&
30
- !releaseInfo.files.includes(`${options.platform}-${options.arch}`)
31
- ) {
32
- throw new Error(
33
- `Platform ${options.platform} and architecture ${options.arch} is not supported by this download server.`,
34
- );
35
- }
36
- // if (typeof options.cacheDir !== "string") {
37
- // throw new Error("Expected options.cacheDir to be a string. Got " + typeof options.cacheDir);
38
- // }
39
- if (typeof options.cache !== "boolean") {
40
- return new Error(
41
- "Expected options.cache to be a boolean. Got " + typeof options.cache,
42
- );
43
- }
44
- if (typeof options.ffmpeg !== "boolean") {
45
- return new Error(
46
- "Expected options.ffmpeg to be a boolean. Got " + typeof options.ffmpeg,
47
- );
48
- }
49
-
50
- if (
51
- options.logLevel !== "error" &&
52
- options.logLevel !== "warn" &&
53
- options.logLevel !== "info" &&
54
- options.logLevel !== "debug"
55
- ) {
56
- throw new Error(
57
- "Expected options.logLevel to be 'error', 'warn', 'info' or 'debug'. Got " +
58
- options.logLevel,
59
- );
60
- }
61
-
62
- if (options.mode === "get") {
63
- return undefined;
64
- }
65
- if (Array.isArray(options.argv)) {
66
- return new Error(
67
- "Expected options.argv to be an array. Got " + typeof options.argv,
68
- );
69
- }
70
- if (typeof options.glob !== "boolean") {
71
- return new Error(
72
- "Expected options.glob to be a boolean. Got " + typeof options.glob,
73
- );
74
- }
75
-
76
- if (options.srcDir) {
77
- await readdir(options.srcDir);
78
- }
79
-
80
- if (options.mode === "run") {
81
- return undefined;
82
- }
83
-
84
- if (options.outDir) {
85
- await readdir(options.outDir);
86
- }
87
-
88
- if (
89
- typeof options.managedManifest !== "boolean" &&
90
- typeof options.managedManifest !== "object" &&
91
- typeof options.managedManifest !== "string"
92
- ) {
93
- return new Error(
94
- "Expected options.managedManifest to be a boolean, object or string. Got " +
95
- typeof options.managedManifest,
96
- );
97
- }
98
-
99
- if (typeof options.managedManifest === "object") {
100
- if (options.managedManifest.name === undefined) {
101
- return new Error(
102
- "Expected NW.js Manifest to be a boolean. Got " +
103
- typeof options.nativeAddon,
104
- );
105
- }
106
- if (options.managedManifest.main === undefined) {
107
- return new Error("Expected NW.js Manifest to have a `main` property.");
108
- }
109
- }
110
-
111
- if (typeof options.nativeAddon !== "boolean") {
112
- return new Error("Expected options.nativeAddon to have a `name` property.");
113
- }
114
-
115
- // TODO: Validate app options
116
- return undefined;
117
- };