nw-builder 3.8.6-beta.0 → 3.8.6-beta.2

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/lib/index.cjs CHANGED
@@ -1,1039 +1,942 @@
1
- const { existsSync } = require("node:fs");
1
+ const { basename, resolve } = require("node:path");
2
+ const { version } = require("node:process");
3
+ const { mkdir, cp, rm, rename } = require("node:fs/promises");
4
+ const { readFileSync } = require("node:fs");
5
+ const glob = require("simple-glob");
2
6
  var _ = require("lodash");
3
- var inherits = require("inherits");
4
- var EventEmitter = require("events").EventEmitter;
5
7
  var fs = require("graceful-fs-extra");
6
- var recursiveReaddirSync = require("recursive-readdir-sync");
7
8
  var path = require("path");
8
9
  var thenify = require("thenify");
9
10
  var rcedit = require("rcedit");
10
11
  var winresourcer = thenify(require("winresourcer"));
11
- var spawn = require("child_process").spawn;
12
12
  var semver = require("semver");
13
13
  var platformOverrides = require("./platformOverrides.cjs");
14
- var deprecate = require("deprecate");
15
- const { install } = require("nw-install");
16
14
 
17
15
  const {
18
16
  checkCache,
19
- detectCurrentPlatform,
17
+ get,
18
+ getReleaseInfo,
19
+ isCached,
20
+ log,
21
+ setLogLevel,
20
22
  Platforms,
21
- checkPkgOptions,
22
- Options,
23
- parseOptions,
23
+ parse,
24
+ run,
25
+ validate,
24
26
  } = require("../dist/index.cjs");
25
27
  var NwVersions = require("./versions.cjs");
26
28
  var Version = require("./Version.cjs");
27
29
  var Utils = require("./utils.cjs");
28
30
 
29
- // We inherit from EventEmitter for logging
30
- inherits(NwBuilder, EventEmitter);
31
+ class NwBuilder {
32
+ constructor(options) {
33
+ this.init(options).then(() => {
34
+ this._platforms = { ...Platforms };
31
35
 
32
- function NwBuilder(options) {
33
- const pkgOptions = checkPkgOptions(options.files);
34
- // Options are defined in package.json take precedence
35
- if (Object.entries(pkgOptions).length !== 0) {
36
- this.options = parseOptions(pkgOptions, Options);
37
- this.options.files = options.files;
38
- } else {
39
- this.options = parseOptions(options, Options);
36
+ // clear all unused platforms
37
+ for (const name in this._platforms) {
38
+ if (
39
+ this.options.platforms &&
40
+ this.options.platforms.indexOf(name) === -1
41
+ )
42
+ delete this._platforms[name];
43
+ }
44
+ });
40
45
  }
41
46
 
42
- if (this.options.currentPlatform === null) {
43
- this.options.currentPlatform = detectCurrentPlatform(process);
44
- }
47
+ async init(options) {
48
+ let manifest = {};
49
+ let releaseInfo = {};
50
+ try {
51
+ options = parse(options, manifest);
45
52
 
46
- if (this.options.platforms && this.options.platforms.length === 0) {
47
- this.options.platforms = [detectCurrentPlatform(process)];
48
- } else if (this.options.platforms && this.options.platforms.length === 1) {
49
- this.options.platforms = this.options.platforms[0].split(",");
50
- }
53
+ for (const file of glob(options.files)) {
54
+ if (basename(file) === "package.json" && manifest === undefined) {
55
+ manifest = JSON.parse(readFileSync(file));
56
+ }
57
+ }
51
58
 
52
- // Intercept the platforms and check for the legacy platforms of 'osx' and 'win' and
53
- // replace with 'osx32', 'osx64', and 'win32', 'win64' respectively.
54
- if (typeof this.options.platforms != "undefined") {
55
- if (this.options.platforms && this.options.platforms.indexOf("osx") >= 0) {
56
- this.options.platforms.splice(
57
- this.options.platforms.indexOf("osx"),
58
- 1,
59
- "osx32",
60
- "osx64",
61
- );
62
- }
63
- if (this.options.platforms && this.options.platforms.indexOf("win") >= 0) {
64
- this.options.platforms.splice(
65
- this.options.platforms.indexOf("win"),
66
- 1,
67
- "win32",
68
- "win64",
69
- );
70
- }
71
- if (
72
- this.options.platforms &&
73
- this.options.platforms.indexOf("linux") >= 0
74
- ) {
75
- this.options.platforms.splice(
76
- this.options.platforms.indexOf("linux"),
77
- 1,
78
- "linux32",
79
- "linux64",
59
+ if (manifest === undefined) {
60
+ throw new Error(
61
+ "package.json not found in options.files glob patterns.",
62
+ );
63
+ }
64
+
65
+ if (typeof manifest?.nwbuild === "object") {
66
+ options = manifest.nwbuild;
67
+ }
68
+
69
+ options = parse(options, manifest);
70
+
71
+ let platform = options.currentPlatform.slice(
72
+ 0,
73
+ options.currentPlatform.length - 2,
80
74
  );
81
- }
82
- }
75
+ let arch =
76
+ "x" + options.currentPlatform.slice(options.currentPlatform.length - 2);
77
+
78
+ getReleaseInfo(
79
+ options.version,
80
+ options.cacheDir,
81
+ options.manifestUrl,
82
+ ).then((info) => {
83
+ releaseInfo = info;
84
+ validate(options, info)
85
+ .then(() => {
86
+ // Remove leading "v" from version string
87
+ options.version = info.version.slice(1);
88
+ })
89
+ .catch((error) => {
90
+ log.error(error);
91
+ });
92
+ });
83
93
 
84
- // Some Option checking
85
- if (!this.options.files) {
86
- throw new Error("Please specify some files");
87
- }
94
+ setLogLevel(options.quiet);
88
95
 
89
- if (this.options.platforms && this.options.platforms.length === 0)
90
- throw new Error("No platform to build!");
96
+ if (options.quiet === "debug") {
97
+ log.debug(`Platform: ${platform}`);
98
+ log.debug(`Archicture: ${arch}`);
99
+ log.debug(`Node Version: ${version}`);
100
+ log.debug(`NW.js Version: ${options.version}\n`);
101
+ }
102
+ } catch (error) {
103
+ log.error(error);
104
+ } finally {
105
+ this.options = options;
106
+ }
107
+ }
91
108
 
92
- // verify all the platforms specifed by the user are supported
93
- // this + previous check assures as we have only buildable platforms specified
94
- this.options.platforms &&
95
- this.options.platforms.forEach(function (platform) {
96
- if (!(platform in Platforms))
97
- throw new Error("Unknown platform " + platform);
98
- });
109
+ build(callback) {
110
+ // Let's create a NWjs app
111
+ var build = this.checkFiles()
112
+ .then(this.downloadNwjs.bind(this))
113
+ .then(this.preparePlatformSpecificManifests.bind(this))
114
+ .then(this.createReleaseFolder.bind(this))
115
+ .then(this.copyNwjs.bind(this))
116
+ .then(this.handleLinuxApp.bind(this))
117
+ .then(this.handleMacApp.bind(this))
118
+ .then(this.handleWinApp.bind(this))
119
+ .then(this.zipAppFiles.bind(this))
120
+ .then(this.mergeAppFiles.bind(this))
121
+ .then(function (info) {
122
+ // the promise(s) resolves to nothing in some cases
123
+ return info || this;
124
+ });
99
125
 
100
- this._platforms = _.cloneDeep(Platforms);
126
+ if (typeof callback === "function") {
127
+ build
128
+ .then(function (result) {
129
+ callback(false, result);
130
+ })
131
+ .catch(callback);
132
+ return true;
133
+ }
101
134
 
102
- // clear all unused platforms
103
- for (var name in this._platforms) {
104
- if (this.options.platforms && this.options.platforms.indexOf(name) === -1)
105
- delete this._platforms[name];
135
+ return build;
106
136
  }
107
- }
108
137
 
109
- NwBuilder.prototype.build = function (callback) {
110
- // Let's create a NWjs app
111
- var build = this.checkFiles()
112
- .then(this.resolveLatestVersion.bind(this))
113
- .then(this.checkVersion.bind(this))
114
- .then(this.platformFilesForVersion.bind(this))
115
- .then(this.downloadNwjs.bind(this))
116
- .then(this.preparePlatformSpecificManifests.bind(this))
117
- .then(this.createReleaseFolder.bind(this))
118
- .then(this.copyNwjs.bind(this))
119
- .then(this.handleMacApp.bind(this))
120
- .then(this.handleWinApp.bind(this))
121
- .then(this.zipAppFiles.bind(this))
122
- .then(this.mergeAppFiles.bind(this))
123
- .then(function (info) {
124
- // the promise(s) resolves to nothing in some cases
125
- return info || this;
126
- });
138
+ run(callback) {
139
+ // We do not want to download nwjs for other platforms if are going to run the App
140
+ var platforms = this.options.platforms;
141
+ this.options.platforms = [this.options.currentPlatform];
142
+
143
+ // Let's run this NWjs app
144
+ var run = this.checkFiles()
145
+ .then(this.downloadNwjs.bind(this))
146
+ .then(this.runApp.bind(this));
147
+
148
+ if (typeof callback === "function") {
149
+ run
150
+ .then(function (result) {
151
+ this.options.platforms = platforms;
152
+ callback(false, result);
153
+ })
154
+ .catch(function (error) {
155
+ this.options.platforms = platforms;
156
+ callback(true, error);
157
+ });
158
+ return true;
159
+ }
127
160
 
128
- if (typeof callback === "function") {
129
- build
130
- .then(function (result) {
131
- callback(false, result);
132
- })
133
- .catch(callback);
134
- return true;
161
+ return run;
135
162
  }
136
163
 
137
- return build;
138
- };
164
+ checkFiles() {
165
+ var self = this;
139
166
 
140
- NwBuilder.prototype.run = function (callback) {
141
- // We do not want to download nwjs for other platforms if are going to run the App
142
- var platforms = this.options.platforms;
143
- this.options.platforms = [this.options.currentPlatform];
144
-
145
- // Let's run this NWjs app
146
- var run = this.checkFiles()
147
- .then(this.resolveLatestVersion.bind(this))
148
- .then(this.checkVersion.bind(this))
149
- .then(this.platformFilesForVersion.bind(this))
150
- .then(this.downloadNwjs.bind(this))
151
- .then(this.runApp.bind(this));
152
-
153
- if (typeof callback === "function") {
154
- run
155
- .then(function (result) {
156
- this.options.platforms = platforms;
157
- callback(false, result);
167
+ return Utils.getFileList(this.options.files)
168
+ .then(function (data) {
169
+ self._appPkg = data.json;
170
+ self._files = data.files;
171
+ return self._appPkg;
158
172
  })
159
- .catch(function (error) {
160
- this.options.platforms = platforms;
161
- callback(true, error);
173
+ .then(Utils.getPackageInfo)
174
+ .then(function (appPkg) {
175
+ self._appPkg = appPkg;
176
+
177
+ if (!self.options.appName || !self.options.appVersion) {
178
+ self.options.appName = self.options.appName
179
+ ? self.options.appName
180
+ : appPkg.name;
181
+ self.options.appVersion = self.options.appVersion
182
+ ? self.options.appVersion
183
+ : appPkg.version;
184
+ }
162
185
  });
163
- return true;
164
186
  }
165
187
 
166
- return run;
167
- };
188
+ resolveLatestVersion() {
189
+ var self = this;
168
190
 
169
- NwBuilder.prototype.checkFiles = function () {
170
- var self = this;
171
-
172
- return Utils.getFileList(this.options.files)
173
- .then(function (data) {
174
- self._appPkg = data.json;
175
- self._files = data.files;
176
- return self._appPkg;
177
- })
178
- .then(Utils.getPackageInfo)
179
- .then(function (appPkg) {
180
- self._appPkg = appPkg;
181
-
182
- if (!self.options.appName || !self.options.appVersion) {
183
- self.options.appName = self.options.appName
184
- ? self.options.appName
185
- : appPkg.name;
186
- self.options.appVersion = self.options.appVersion
187
- ? self.options.appVersion
188
- : appPkg.version;
189
- }
191
+ if (self.options.version !== "latest") return Promise.resolve();
192
+
193
+ return NwVersions.getLatestVersion(
194
+ self.options.downloadUrl,
195
+ self.options.manifestUrl,
196
+ self.options.flavor,
197
+ ).then(function (latestVersion) {
198
+ log.debug("Latest Version: v" + latestVersion.version);
199
+ self.options.version = latestVersion.version;
200
+ return latestVersion;
190
201
  });
191
- };
202
+ }
192
203
 
193
- NwBuilder.prototype.resolveLatestVersion = function () {
194
- var self = this;
204
+ checkVersion() {
205
+ var version = this.options.version,
206
+ flavor =
207
+ semver.valid(version) && semver.satisfies(version, "<0.12.3")
208
+ ? "sdk"
209
+ : this.options.flavor,
210
+ self = this;
195
211
 
196
- if (self.options.version !== "latest") return Promise.resolve();
212
+ if (!semver.valid(version)) {
213
+ return Promise.reject("The version " + version + " is not valid.");
214
+ }
197
215
 
198
- return NwVersions.getLatestVersion(
199
- self.options.downloadUrl,
200
- self.options.manifestUrl,
201
- self.options.flavor,
202
- ).then(function (latestVersion) {
203
- self.emit("log", "Latest Version: v" + latestVersion.version);
204
- self.options.version = latestVersion.version;
205
- return latestVersion;
206
- });
207
- };
216
+ var getVersionFromManifest = function () {
217
+ return NwVersions.getVersion({
218
+ desiredVersion: version,
219
+ downloadUrl: self.options.downloadUrl,
220
+ manifestUrl: self.options.manifestUrl,
221
+ flavor: flavor,
222
+ });
223
+ };
224
+ var getVersion;
225
+
226
+ // if the user specified the exact version and all its platforms are cached, don't hit the manifest at all;
227
+ // just trust the ones are cached and assume they're supported
228
+ if (self.options.version !== "latest") {
229
+ var areAllPlatformsCached = true;
230
+ this._forEachPlatform(function (name, platform) {
231
+ var platformToCheck = platform;
232
+
233
+ if (semver.satisfies(self.options.version, ">=0.12.3")) {
234
+ platformToCheck = _.clone(platform);
235
+ platformToCheck.files = ["*"]; // otherwise it'll try to check cache legacy version files
236
+ }
208
237
 
209
- NwBuilder.prototype.checkVersion = function () {
210
- var version = this.options.version,
211
- flavor =
212
- semver.valid(version) && semver.satisfies(version, "<0.12.3")
213
- ? "sdk"
214
- : this.options.flavor,
215
- self = this;
238
+ if (
239
+ !self.isPlatformCached(
240
+ name,
241
+ platformToCheck,
242
+ self.options.version,
243
+ flavor,
244
+ )
245
+ ) {
246
+ areAllPlatformsCached = false;
247
+ }
248
+ });
249
+ if (areAllPlatformsCached) {
250
+ getVersion = Promise.resolve(
251
+ new Version({
252
+ version: version,
253
+ flavors: [flavor],
254
+ downloadUrl: self.options.downloadUrl,
255
+ supportedPlatforms: Object.keys(this._platforms),
256
+ }),
257
+ );
258
+ } else {
259
+ // otherwise hit the manifest
260
+ getVersion = getVersionFromManifest();
261
+ }
262
+ } else {
263
+ // otherwise hit the manifest
264
+ getVersion = getVersionFromManifest();
265
+ }
216
266
 
217
- if (!semver.valid(version)) {
218
- return Promise.reject("The version " + version + " is not valid.");
267
+ return getVersion.then(function (version) {
268
+ self._version = version;
269
+ self._version.flavor = flavor;
270
+ log.debug(
271
+ "Using v" +
272
+ self._version.version +
273
+ " (" +
274
+ (self._version.flavor === "" ? "normal" : self._version.flavor + ")"),
275
+ );
276
+ if (self._version.isLegacy) {
277
+ log.warn("NW.js / node-webkit versions <0.12.3 are deprecated.");
278
+ }
279
+ });
219
280
  }
220
281
 
221
- var getVersionFromManifest = function () {
222
- return NwVersions.getVersion({
223
- desiredVersion: version,
224
- downloadUrl: self.options.downloadUrl,
225
- manifestUrl: self.options.manifestUrl,
226
- flavor: flavor,
227
- });
228
- };
229
- var getVersion;
282
+ platformFilesForVersion() {
283
+ var self = this;
230
284
 
231
- // if the user specified the exact version and all its platforms are cached, don't hit the manifest at all;
232
- // just trust the ones are cached and assume they're supported
233
- if (self.options.version !== "latest") {
234
- var areAllPlatformsCached = true;
235
285
  this._forEachPlatform(function (name, platform) {
236
- var platformToCheck = platform;
237
-
238
- if (semver.satisfies(self.options.version, ">=0.12.3")) {
239
- platformToCheck = _.clone(platform);
240
- platformToCheck.files = ["*"]; // otherwise it'll try to check cache legacy version files
241
- }
286
+ var satisfied = self.preparePlatformFiles(name, platform);
242
287
 
288
+ // need the second condition for newer NW.js versions
243
289
  if (
244
- !self.isPlatformCached(
245
- name,
246
- platformToCheck,
247
- self.options.version,
248
- flavor,
290
+ !(
291
+ satisfied &&
292
+ !!self._version.platforms[name + "-" + self._version.flavor]
249
293
  )
250
294
  ) {
251
- areAllPlatformsCached = false;
295
+ throw new Error(
296
+ "Unsupported NW.js version '" +
297
+ self._version.version +
298
+ " (" +
299
+ self._version.flavor +
300
+ ")' for platform '" +
301
+ name +
302
+ "'",
303
+ );
252
304
  }
253
305
  });
254
- if (areAllPlatformsCached) {
255
- getVersion = Promise.resolve(
256
- new Version({
257
- version: version,
258
- flavors: [flavor],
259
- downloadUrl: self.options.downloadUrl,
260
- supportedPlatforms: Object.keys(this._platforms),
261
- }),
262
- );
263
- } else {
264
- // otherwise hit the manifest
265
- getVersion = getVersionFromManifest();
266
- }
267
- } else {
268
- // otherwise hit the manifest
269
- getVersion = getVersionFromManifest();
306
+
307
+ return Promise.resolve();
270
308
  }
271
309
 
272
- return getVersion.then(function (version) {
273
- self._version = version;
274
- self._version.flavor = flavor;
275
- self.emit(
276
- "log",
277
- "Using v" +
278
- self._version.version +
279
- " (" +
280
- (self._version.flavor === "" ? "normal" : self._version.flavor + ")"),
281
- );
282
- if (self._version.isLegacy) {
283
- deprecate("NW.js / node-webkit versions <0.12.3 are deprecated.");
284
- }
285
- });
286
- };
310
+ async downloadNwjs() {
311
+ let options = this.options;
312
+ let built;
287
313
 
288
- NwBuilder.prototype.platformFilesForVersion = function () {
289
- var self = this;
314
+ built = await isCached(options.cacheDir);
315
+ if (built === false) {
316
+ await mkdir(options.cacheDir, { recursive: true });
317
+ }
318
+ for await (const os of options.platforms) {
319
+ let platform = os.slice(0, os.length - 2);
320
+ let arch = "x" + os.slice(os.length - 2);
321
+ await get({
322
+ version: options.version,
323
+ flavor: options.flavor,
324
+ platform: platform,
325
+ arch: arch,
326
+ downloadUrl: options.downloadUrl,
327
+ cacheDir: options.cacheDir,
328
+ cache: !options.forceDownload,
329
+ ffmpeg: false,
330
+ });
331
+ }
332
+ }
290
333
 
291
- this._forEachPlatform(function (name, platform) {
292
- var satisfied = self.preparePlatformFiles(name, platform);
334
+ buildGypModules() {
335
+ // @todo
336
+ // If we trigger a rebuild we have to copy
337
+ // the node_modules to a tmp location because
338
+ // we don't want to change the source files
339
+ }
293
340
 
294
- // need the second condition for newer NW.js versions
341
+ preparePlatformSpecificManifests() {
295
342
  if (
296
343
  !(
297
- satisfied &&
298
- !!self._version.platforms[name + "-" + self._version.flavor]
344
+ this._appPkg.platformOverrides &&
345
+ Object.keys(this._appPkg.platformOverrides).length
299
346
  )
300
347
  ) {
301
- throw new Error(
302
- "Unsupported NW.js version '" +
303
- self._version.version +
304
- " (" +
305
- self._version.flavor +
306
- ")' for platform '" +
307
- name +
308
- "'",
309
- );
348
+ return Promise.resolve();
310
349
  }
311
- });
312
-
313
- return Promise.resolve();
314
- };
315
350
 
316
- NwBuilder.prototype.downloadNwjs = async function () {
317
- let options = this.options;
318
- for await (let osName of options.platforms) {
319
- let plat = osName.slice(0, osName.length - 2);
320
- let arch =
321
- osName.slice(osName.length - 2, osName.length) === "32" ? "ia32" : "x64";
322
- this._platforms[osName].url =
323
- this._version.platforms[osName + "-" + this._version.flavor];
324
- this._platforms[
325
- osName
326
- ].cache = `${this.options.cacheDir}/${this.options.version}-${this.options.flavor}/${osName}/nwjs-${this.options.flavor}-v${this.options.version}-${plat}-${arch}`;
327
- if (
328
- options.forceDownload === true ||
329
- existsSync(
330
- `${this.options.cacheDir}/${this.options.version}-${this.options.flavor}/${osName}/nwjs-${this.options.flavor}-v${this.options.version}-${plat}-${arch}`,
331
- ) === false
332
- ) {
333
- await install(
334
- this.options.version,
335
- this.options.flavor,
336
- plat,
337
- arch,
338
- "https://nwjs.io",
339
- "https://dl.nwjs.io",
340
- `${this.options.cacheDir}/${this.options.version}-${this.options.flavor}/${osName}`,
341
- `nwjs-${this.options.flavor}-v${this.options.version}-${plat}-${arch}`,
351
+ var self = this;
352
+ var promises = [];
353
+
354
+ self._forEachPlatform(function (name, platform) {
355
+ promises.push(
356
+ new Promise(function (resolve, reject) {
357
+ var overrides = self._appPkg.platformOverrides;
358
+ if (overrides[name] || overrides[name.substr(0, name.length - 2)]) {
359
+ platformOverrides(
360
+ {
361
+ options: self._appPkg,
362
+ platform: name,
363
+ },
364
+ function (err, result) {
365
+ if (err) {
366
+ return reject(err);
367
+ }
368
+
369
+ platform.platformSpecificManifest = result;
370
+ resolve();
371
+ },
372
+ );
373
+ } else {
374
+ resolve();
375
+ }
376
+ }),
342
377
  );
343
- }
344
- }
345
- };
346
-
347
- NwBuilder.prototype.buildGypModules = function () {
348
- // @todo
349
- // If we trigger a rebuild we have to copy
350
- // the node_modules to a tmp location because
351
- // we don't want to change the source files
352
- };
378
+ });
353
379
 
354
- NwBuilder.prototype.preparePlatformSpecificManifests = function () {
355
- if (
356
- !(
357
- this._appPkg.platformOverrides &&
358
- Object.keys(this._appPkg.platformOverrides).length
359
- )
360
- ) {
361
- return Promise.resolve();
380
+ return Promise.all(promises);
362
381
  }
363
382
 
364
- var self = this;
365
- var promises = [];
366
-
367
- self._forEachPlatform(function (name, platform) {
368
- promises.push(
369
- new Promise(function (resolve, reject) {
370
- var overrides = self._appPkg.platformOverrides;
371
- if (overrides[name] || overrides[name.substr(0, name.length - 2)]) {
372
- platformOverrides(
373
- {
374
- options: self._appPkg,
375
- platform: name,
376
- },
377
- function (err, result) {
378
- if (err) {
379
- return reject(err);
380
- }
381
-
382
- platform.platformSpecificManifest = result;
383
- resolve();
384
- },
385
- );
386
- } else {
387
- resolve();
388
- }
389
- }),
390
- );
391
- });
392
-
393
- return Promise.all(promises);
394
- };
395
-
396
- NwBuilder.prototype.createReleaseFolder = function () {
397
- var self = this,
398
- releasePath,
399
- directoryCreationPromises = [];
383
+ createReleaseFolder() {
384
+ var self = this,
385
+ releasePath,
386
+ directoryCreationPromises = [];
400
387
 
401
- if (_.isFunction(self.options.buildType)) {
402
- releasePath = self.options.buildType.call(self.options);
403
- } else {
404
- // buildTypes
405
- switch (self.options.buildType) {
406
- case "timestamped":
407
- releasePath =
408
- self.options.appName +
409
- " - " +
410
- Math.round(Date.now() / 1000).toString();
411
- break;
412
-
413
- case "versioned":
414
- releasePath = self.options.appName + " - v" + self.options.appVersion;
415
- break;
416
-
417
- default:
418
- releasePath = self.options.appName;
388
+ if (_.isFunction(self.options.buildType)) {
389
+ releasePath = self.options.buildType.call(self.options);
390
+ } else {
391
+ // buildTypes
392
+ switch (self.options.buildType) {
393
+ case "timestamped":
394
+ releasePath =
395
+ self.options.appName +
396
+ " - " +
397
+ Math.round(Date.now() / 1000).toString();
398
+ break;
399
+
400
+ case "versioned":
401
+ releasePath = self.options.appName + " - v" + self.options.appVersion;
402
+ break;
403
+
404
+ default:
405
+ releasePath = self.options.appName;
406
+ }
419
407
  }
420
- }
421
408
 
422
- this._forEachPlatform(function (name, platform) {
423
- directoryCreationPromises.push(
424
- new Promise(function (resolve, reject) {
425
- platform.releasePath = path.resolve(
426
- self.options.buildDir,
427
- releasePath,
428
- name,
429
- );
430
-
431
- // Ensure that there is a release Folder, delete and create it.
432
- fs.remove(platform.releasePath, function (err) {
433
- if (err) return reject(err);
409
+ this._forEachPlatform(function (name, platform) {
410
+ directoryCreationPromises.push(
411
+ new Promise(function (resolve, reject) {
412
+ platform.releasePath = path.resolve(
413
+ self.options.buildDir,
414
+ releasePath,
415
+ name,
416
+ );
434
417
 
435
- fs.mkdirp(platform.releasePath, function (err) {
418
+ // Ensure that there is a release Folder, delete and create it.
419
+ fs.remove(platform.releasePath, function (err) {
436
420
  if (err) return reject(err);
437
421
 
438
- self.emit(
439
- "log",
440
- "Create release folder in " + platform.releasePath,
441
- );
442
- resolve();
422
+ fs.mkdirp(platform.releasePath, function (err) {
423
+ if (err) return reject(err);
424
+
425
+ log.debug("Create release folder in " + platform.releasePath);
426
+ resolve();
427
+ });
443
428
  });
444
- });
445
- }),
446
- );
447
- });
429
+ }),
430
+ );
431
+ });
448
432
 
449
- return Promise.all(directoryCreationPromises);
450
- };
433
+ return Promise.all(directoryCreationPromises);
434
+ }
451
435
 
452
- NwBuilder.prototype.copyNwjs = function () {
453
- var self = this,
454
- copiedFiles = [];
455
-
456
- this._forEachPlatform(function (name, platform) {
457
- // >= v0.12.3
458
- // Since we only have `*`, we're going to recursively get all the files, then copy them
459
- // Since a .app is treated like a directory, we need to ignore files inside them and just copy them entirely
460
- if (platform.files.length === 1 && platform.files[0] === "*") {
461
- // convert all paths inside a .app, etc. to just point to the .app
462
- // then remove duplicates
463
- var files = recursiveReaddirSync(platform.cache).map(function (file) {
464
- var matches = file.match(/^(.+?(\.app|\.framework))/);
465
- if (matches) {
466
- return matches[1];
467
- }
468
- return file;
436
+ async copyNwjs() {
437
+ for await (const os of this.options.platforms) {
438
+ const platform = os.slice(0, os.length - 2);
439
+ const arch = "x" + os.slice(os.length - 2);
440
+
441
+ await rm(resolve(this.options.buildDir, this.options.appName, os), {
442
+ recursive: true,
443
+ force: true,
469
444
  });
470
445
 
471
- var totalFiles = _.uniq(files);
472
- platform.files = totalFiles;
473
-
474
- totalFiles.forEach(function (file) {
475
- var destFile = path.relative(platform.cache, file);
476
- var options = {};
477
-
478
- if (["nw", "nwjs.app", "nw.exe"].indexOf(destFile) !== -1) {
479
- // ignore nwjs.app/Contents/Resources/*.lproj/InfoPlist.strings,
480
- // otherwise the app name will show as nwjs.app in Finder.
481
- // *.lproj directory itself needs to be kept to support multiple locales.
482
- if (destFile === "nwjs.app") {
483
- options.filter = function (filepath) {
484
- return !/nwjs\.app\/Contents\/Resources\/[^.]+\.lproj\/InfoPlist\.strings$/.test(
485
- filepath,
486
- );
487
- };
488
- }
489
- // rename executable to app name
490
- destFile = self.options.appName + path.extname(destFile);
491
- }
446
+ const nwDir = resolve(
447
+ this.options.cacheDir,
448
+ `nwjs${this.options.flavor === "sdk" ? "-sdk" : ""}-v${
449
+ this.options.version
450
+ }-${platform}-${arch}`,
451
+ );
492
452
 
493
- copiedFiles.push(
494
- Utils.copyFile(
453
+ await cp(
454
+ nwDir,
455
+ resolve(this.options.buildDir, this.options.appName, os),
456
+ { recursive: true },
457
+ );
458
+
459
+ for (const file of glob(this.options.files)) {
460
+ await cp(
461
+ file,
462
+ resolve(
463
+ this.options.buildDir,
464
+ this.options.appName,
465
+ os,
466
+ platform !== "osx"
467
+ ? "package.nw"
468
+ : "nwjs.app/Contents/Resources/app.nw",
495
469
  file,
496
- path.join(platform.releasePath, destFile),
497
- self,
498
- options,
499
470
  ),
471
+ { recursive: true, verbatimSymlinks: true },
500
472
  );
501
- platform.files.push(destFile);
502
- });
503
-
504
- return;
505
- }
506
-
507
- // legacy
508
- platform.files.forEach(function (file, i) {
509
- var destFile = file;
510
- if (i === 0) {
511
- // rename executable to app name
512
- destFile = self.options.appName + path.extname(file);
513
- // save new filename back to files list
514
- platform.files[0] = destFile;
515
473
  }
516
- copiedFiles.push(
517
- Utils.copyFile(
518
- path.resolve(platform.cache, file),
519
- path.resolve(platform.releasePath, destFile),
520
- self,
521
- ),
522
- );
523
- });
524
- });
474
+ }
475
+ }
525
476
 
526
- return Promise.all(copiedFiles);
527
- };
477
+ isPlatformNeedingZip(name, platform) {
478
+ var self = this,
479
+ needsZip = platform.needsZip;
528
480
 
529
- NwBuilder.prototype.isPlatformNeedingZip = function (name, platform) {
530
- var self = this,
531
- needsZip = platform.needsZip;
481
+ if (name.indexOf("osx") === 0 && self.options.macZip != null) {
482
+ log.warn("macZip is deprecated. Use the zip option instead.");
483
+ needsZip = self.options.macZip;
484
+ } else if (self.options.zip != null) {
485
+ needsZip = self.options.zip;
486
+ }
532
487
 
533
- if (name.indexOf("osx") === 0 && self.options.macZip != null) {
534
- deprecate("macZip is deprecated. Use the zip option instead.");
535
- needsZip = self.options.macZip;
536
- } else if (self.options.zip != null) {
537
- needsZip = self.options.zip;
488
+ return needsZip;
538
489
  }
539
490
 
540
- return needsZip;
541
- };
542
-
543
- NwBuilder.prototype.zipAppFiles = function () {
544
- var self = this;
491
+ zipAppFiles() {
492
+ var self = this;
545
493
 
546
- // Check if zip is needed
547
- var doAnyNeedZip = false,
548
- zipOptions = this.options.zipOptions,
549
- numberOfPlatformsWithoutOverrides = 0;
494
+ // Check if zip is needed
495
+ var doAnyNeedZip = false,
496
+ zipOptions = this.options.zipOptions,
497
+ numberOfPlatformsWithoutOverrides = 0;
550
498
 
551
- self._zips = {};
499
+ self._zips = {};
552
500
 
553
- this._forEachPlatform(function (name, platform) {
554
- var needsZip = self.isPlatformNeedingZip(name, platform);
555
-
556
- if (needsZip) {
557
- var platformSpecific = !!platform.platformSpecificManifest;
501
+ this._forEachPlatform(function (name, platform) {
502
+ var needsZip = self.isPlatformNeedingZip(name, platform);
558
503
 
559
- self._zips[name] = { platformSpecific: platformSpecific };
504
+ if (needsZip) {
505
+ var platformSpecific = !!platform.platformSpecificManifest;
560
506
 
561
- numberOfPlatformsWithoutOverrides += !platformSpecific;
562
- }
507
+ self._zips[name] = { platformSpecific: platformSpecific };
563
508
 
564
- doAnyNeedZip = doAnyNeedZip || needsZip;
565
- });
509
+ numberOfPlatformsWithoutOverrides += !platformSpecific;
510
+ }
566
511
 
567
- self._needsZip = doAnyNeedZip;
512
+ doAnyNeedZip = doAnyNeedZip || needsZip;
513
+ });
568
514
 
569
- return new Promise(function (resolve, reject) {
570
- if (!self._needsZip) {
571
- resolve();
572
- return;
573
- }
515
+ self._needsZip = doAnyNeedZip;
574
516
 
575
- // create (or don't create) a ZIP for multiple platforms
576
- new Promise(function (resolve, reject) {
577
- if (numberOfPlatformsWithoutOverrides > 1) {
578
- Utils.generateZipFile(self._files, self, null, zipOptions).then(
579
- function (zip) {
580
- resolve(zip);
581
- },
582
- reject,
583
- );
584
- } else {
517
+ return new Promise(function (resolve, reject) {
518
+ if (!self._needsZip) {
585
519
  resolve();
520
+ return;
586
521
  }
587
- }).then(function (platformAgnosticZip) {
588
- var zipPromises = [];
589
-
590
- _.forEach(self._zips, function (zip, platformName) {
591
- if (platformAgnosticZip && !zip.platformSpecific) {
592
- zip.file = platformAgnosticZip;
593
- return;
594
- }
595
522
 
596
- zipPromises.push(
597
- Utils.generateZipFile(
598
- self._files,
599
- self,
600
- JSON.stringify(
601
- self._platforms[platformName].platformSpecificManifest,
602
- ),
603
- zipOptions,
604
- ).then(function (file) {
605
- zip.file = file;
606
- }),
607
- );
608
- });
609
-
610
- Promise.all(zipPromises).then(resolve, reject);
611
- }, reject);
612
- });
613
- };
614
-
615
- NwBuilder.prototype.mergeAppFiles = function () {
616
- var self = this;
617
-
618
- var copyPromises = [];
619
-
620
- this._forEachPlatform(function (name, platform) {
621
- var zipping = self.isPlatformNeedingZip(name, platform);
622
- // We copy the app files if we are on mac and don't force zip
623
- if (!zipping) {
624
- // no zip, copy the files
625
- self._files.forEach(function (file) {
626
- var dest;
627
-
628
- if (name == "osx32" || name === "osx64") {
629
- dest = path.resolve(
630
- self.getResourcesDirectoryPath(platform),
631
- "app.nw",
632
- file.dest,
523
+ // create (or don't create) a ZIP for multiple platforms
524
+ new Promise(function (resolve, reject) {
525
+ if (numberOfPlatformsWithoutOverrides > 1) {
526
+ Utils.generateZipFile(self._files, self, null, zipOptions).then(
527
+ function (zip) {
528
+ resolve(zip);
529
+ },
530
+ reject,
633
531
  );
634
532
  } else {
635
- dest = path.resolve(platform.releasePath, file.dest);
636
- }
637
-
638
- if (file.dest === "package.json" && platform.platformSpecificManifest) {
639
- copyPromises.push(self.writePlatformSpecificManifest(platform, dest));
640
- } else {
641
- copyPromises.push(Utils.copyFile(file.src, dest, self));
533
+ resolve();
642
534
  }
643
- });
644
- } else if (!self.options.mergeZip) {
645
- // copy the zipped package.nw into the app directory
646
- copyPromises.push(
647
- Utils.copyFile(
648
- self.getZipFile(name),
649
- path.resolve(platform.releasePath, "package.nw"),
650
- self,
651
- ),
652
- );
653
- } else if (name == "osx32" || name == "osx64") {
654
- // zip just copy the app.nw
655
- copyPromises.push(
656
- Utils.copyFile(
657
- self.getZipFile(name),
658
- path.resolve(self.getResourcesDirectoryPath(platform), "app.nw"),
659
- self,
660
- ),
661
- );
662
- } else {
663
- var executableToMergeWith = self._version.isLegacy
664
- ? _.first(platform.files)
665
- : self.getExecutableName(name);
666
-
667
- // We cat the app.nw file into the .exe / nw
668
- copyPromises.push(
669
- Utils.mergeFiles(
670
- path.resolve(platform.releasePath, executableToMergeWith),
671
- self.getZipFile(name),
672
- platform.chmod,
673
- ),
674
- );
675
- }
676
- });
535
+ }).then(function (platformAgnosticZip) {
536
+ var zipPromises = [];
677
537
 
678
- return Promise.all(copyPromises);
679
- };
538
+ _.forEach(self._zips, function (zip, platformName) {
539
+ if (platformAgnosticZip && !zip.platformSpecific) {
540
+ zip.file = platformAgnosticZip;
541
+ return;
542
+ }
680
543
 
681
- NwBuilder.prototype.getZipFile = function (platformName) {
682
- return (this._zips[platformName] && this._zips[platformName].file) || null;
683
- };
544
+ zipPromises.push(
545
+ Utils.generateZipFile(
546
+ self._files,
547
+ self,
548
+ JSON.stringify(
549
+ self._platforms[platformName].platformSpecificManifest,
550
+ ),
551
+ zipOptions,
552
+ ).then(function (file) {
553
+ zip.file = file;
554
+ }),
555
+ );
556
+ });
684
557
 
685
- NwBuilder.prototype.writePlatformSpecificManifest = function (platform, dest) {
686
- return new Promise(function (resolve, reject) {
687
- var pkgParentDirectory = path.join(dest, "../");
688
- if (!fs.existsSync(pkgParentDirectory)) fs.mkdirpSync(pkgParentDirectory);
558
+ Promise.all(zipPromises).then(resolve, reject);
559
+ }, reject);
560
+ });
561
+ }
689
562
 
690
- fs.writeFile(
691
- dest,
692
- JSON.stringify(platform.platformSpecificManifest),
693
- function (err) {
694
- if (err) return reject(err);
695
- resolve();
696
- },
697
- );
698
- });
699
- };
563
+ mergeAppFiles() {
564
+ var self = this;
700
565
 
701
- NwBuilder.prototype.handleMacApp = function () {
702
- var self = this,
703
- allDone = [];
566
+ var copyPromises = [];
704
567
 
705
- this._forEachPlatform(function (name, platform) {
706
- if (["osx32", "osx64"].indexOf(name) < 0) return;
568
+ this._forEachPlatform(function (name, platform) {
569
+ var zipping = self.isPlatformNeedingZip(name, platform);
570
+ // We copy the app files if we are on mac and don't force zip
571
+ if (!zipping) {
572
+ // no zip, copy the files
573
+ self._files.forEach(function (file) {
574
+ var dest;
575
+
576
+ if (name == "osx32" || name === "osx64") {
577
+ dest = path.resolve(
578
+ self.getResourcesDirectoryPath(platform),
579
+ "app.nw",
580
+ file.dest,
581
+ );
582
+ } else {
583
+ dest = path.resolve(platform.releasePath, file.dest);
584
+ }
707
585
 
708
- // Let's first handle the mac icon
709
- if (self.options.macIcns) {
710
- if (semver.satisfies(self._version.version, "<=0.12.3")) {
711
- allDone.push(
586
+ if (
587
+ file.dest === "package.json" &&
588
+ platform.platformSpecificManifest
589
+ ) {
590
+ copyPromises.push(
591
+ self.writePlatformSpecificManifest(platform, dest),
592
+ );
593
+ } else {
594
+ copyPromises.push(Utils.copyFile(file.src, dest, self));
595
+ }
596
+ });
597
+ } else if (!self.options.mergeZip) {
598
+ // copy the zipped package.nw into the app directory
599
+ copyPromises.push(
712
600
  Utils.copyFile(
713
- self.options.macIcns,
714
- path.resolve(self.getResourcesDirectoryPath(platform), "nw.icns"),
601
+ self.getZipFile(name),
602
+ path.resolve(platform.releasePath, "package.nw"),
715
603
  self,
716
604
  ),
717
605
  );
718
- } else {
719
- allDone.push(
606
+ } else if (name == "osx32" || name == "osx64") {
607
+ // zip just copy the app.nw
608
+ copyPromises.push(
720
609
  Utils.copyFile(
721
- self.options.macIcns,
722
- path.resolve(self.getResourcesDirectoryPath(platform), "app.icns"),
610
+ self.getZipFile(name),
611
+ path.resolve(self.getResourcesDirectoryPath(platform), "app.nw"),
723
612
  self,
724
613
  ),
725
614
  );
726
- allDone.push(
727
- Utils.copyFile(
728
- self.options.macIcns,
729
- path.resolve(
730
- self.getResourcesDirectoryPath(platform),
731
- "document.icns",
732
- ),
733
- self,
615
+ } else {
616
+ var executableToMergeWith = self.getExecutableName(name);
617
+
618
+ // We cat the app.nw file into the .exe / nw
619
+ copyPromises.push(
620
+ Utils.mergeFiles(
621
+ path.resolve(platform.releasePath, executableToMergeWith),
622
+ self.getZipFile(name),
623
+ platform.chmod,
734
624
  ),
735
625
  );
736
626
  }
737
- }
627
+ });
738
628
 
739
- // Handle mac credits
740
- if (self.options.macCredits) {
741
- allDone.push(
742
- Utils.copyFile(
743
- self.options.macCredits,
744
- path.resolve(
745
- self.getResourcesDirectoryPath(platform),
746
- "Credits.html",
747
- ),
748
- self,
749
- ),
750
- );
751
- }
629
+ return Promise.all(copyPromises);
630
+ }
752
631
 
753
- // Let's handle the Plist
754
- var PlistPath = path.resolve(
755
- platform.releasePath,
756
- self.options.appName + ".app",
757
- "Contents",
758
- "Info.plist",
759
- );
632
+ getZipFile(platformName) {
633
+ return (this._zips[platformName] && this._zips[platformName].file) || null;
634
+ }
760
635
 
761
- // If the macPlist is a string we just copy the file
762
- if (typeof self.options.macPlist === "string") {
763
- allDone.push(Utils.copyFile(self.options.macPlist, PlistPath, self));
764
- } else {
765
- // Setup the Plist
766
- var plistOptions = Utils.getPlistOptions(
767
- {
768
- name: self.options.appName,
769
- version: self.options.appVersion,
770
- copyright: self._appPkg.copyright,
636
+ writePlatformSpecificManifest(platform, dest) {
637
+ return new Promise(function (resolve, reject) {
638
+ var pkgParentDirectory = path.join(dest, "../");
639
+ if (!fs.existsSync(pkgParentDirectory)) fs.mkdirpSync(pkgParentDirectory);
640
+
641
+ fs.writeFile(
642
+ dest,
643
+ JSON.stringify(platform.platformSpecificManifest),
644
+ function (err) {
645
+ if (err) return reject(err);
646
+ resolve();
771
647
  },
772
- self.options.macPlist,
773
648
  );
649
+ });
650
+ }
774
651
 
775
- allDone.push(Utils.editPlist(PlistPath, PlistPath, plistOptions));
776
- }
777
- });
652
+ handleLinuxApp() {
653
+ var self = this;
778
654
 
779
- return Promise.all(allDone);
780
- };
655
+ this._forEachPlatform(async function (name, platform) {
656
+ if (["linux64", "linux32"].indexOf(name) < 0) return;
781
657
 
782
- NwBuilder.prototype.handleWinApp = function () {
783
- var self = this,
784
- allDone = [];
658
+ var executableName = self.getExecutableName(name);
785
659
 
786
- this._forEachPlatform(function (name, platform) {
787
- if (
788
- (!self.options.winIco && !self.options.winVersionString) ||
789
- ["win32", "win64"].indexOf(name) < 0
790
- )
791
- return;
792
-
793
- var executableName = self._version.isLegacy
794
- ? _.first(platform.files)
795
- : self.getExecutableName(name);
796
- var executablePath = path.resolve(platform.releasePath, executableName);
797
-
798
- var rcConf = {};
799
- if (self.options.winVersionString) {
800
- rcConf["version-string"] = Object.assign(
801
- {},
802
- {
803
- // The process name used in the Task Manager
804
- FileDescription: self.options.appName,
805
- },
806
- self.options.winVersionString,
660
+ await rename(
661
+ resolve(platform.releasePath, "nw"),
662
+ resolve(platform.releasePath, executableName),
807
663
  );
808
- }
809
- if (self.options.winIco && self.options.useRcedit) {
810
- rcConf["icon"] = path.resolve(self.options.winIco);
811
- }
664
+ });
665
+ }
812
666
 
813
- var updateVersionStringPromise = rcedit(executablePath, rcConf);
667
+ handleMacApp() {
668
+ var self = this,
669
+ allDone = [];
814
670
 
815
- var updateIconsPromise = updateVersionStringPromise.then(function () {
816
- return new Promise(function (resolve, reject) {
817
- if (!self.options.winIco || self.options.useRcedit) {
818
- resolve();
671
+ this._forEachPlatform(async function (name, platform) {
672
+ if (["osx32", "osx64"].indexOf(name) < 0) return;
673
+
674
+ var executableName = self.getExecutableName(name);
675
+
676
+ await rename(
677
+ resolve(platform.releasePath, "nwjs.app"),
678
+ resolve(platform.releasePath, executableName),
679
+ );
680
+
681
+ // Let's first handle the mac icon
682
+ if (self.options.macIcns) {
683
+ if (semver.satisfies(self._version.version, "<=0.12.3")) {
684
+ allDone.push(
685
+ Utils.copyFile(
686
+ self.options.macIcns,
687
+ path.resolve(self.getResourcesDirectoryPath(platform), "nw.icns"),
688
+ self,
689
+ ),
690
+ );
819
691
  } else {
820
- self.emit("log", "Update " + name + " executable icon");
821
- // Set icon
822
- winresourcer(
823
- {
824
- operation: "Update",
825
- exeFile: executablePath,
826
- resourceType: "Icongroup",
827
- resourceName: "IDR_MAINFRAME",
828
- lang: 1033, // Required, except when updating or deleting
829
- resourceFile: path.resolve(self.options.winIco),
830
- },
831
- function (err) {
832
- if (!err) {
833
- resolve();
834
- } else {
835
- reject(
836
- "Error while updating the Windows icon." +
837
- (process.platform !== "win32"
838
- ? " Wine (winehq.org) must be installed to add custom icons from Mac and Linux."
839
- : ""),
840
- );
841
- }
842
- },
692
+ allDone.push(
693
+ Utils.copyFile(
694
+ self.options.macIcns,
695
+ path.resolve(
696
+ self.getResourcesDirectoryPath(platform),
697
+ "app.icns",
698
+ ),
699
+ self,
700
+ ),
701
+ );
702
+ allDone.push(
703
+ Utils.copyFile(
704
+ self.options.macIcns,
705
+ path.resolve(
706
+ self.getResourcesDirectoryPath(platform),
707
+ "document.icns",
708
+ ),
709
+ self,
710
+ ),
843
711
  );
844
712
  }
845
- });
713
+ }
714
+
715
+ // Handle mac credits
716
+ if (self.options.macCredits) {
717
+ allDone.push(
718
+ Utils.copyFile(
719
+ self.options.macCredits,
720
+ path.resolve(
721
+ self.getResourcesDirectoryPath(platform),
722
+ "Credits.html",
723
+ ),
724
+ self,
725
+ ),
726
+ );
727
+ }
728
+
729
+ // Let's handle the Plist
730
+ var PlistPath = path.resolve(
731
+ platform.releasePath,
732
+ self.options.appName + ".app",
733
+ "Contents",
734
+ "Info.plist",
735
+ );
736
+
737
+ // If the macPlist is a string we just copy the file
738
+ if (typeof self.options.macPlist === "string") {
739
+ allDone.push(Utils.copyFile(self.options.macPlist, PlistPath, self));
740
+ } else {
741
+ // Setup the Plist
742
+ var plistOptions = Utils.getPlistOptions(
743
+ {
744
+ name: self.options.appName,
745
+ version: self.options.appVersion,
746
+ copyright: self._appPkg.copyright,
747
+ },
748
+ self.options.macPlist,
749
+ );
750
+
751
+ allDone.push(Utils.editPlist(PlistPath, PlistPath, plistOptions));
752
+ }
846
753
  });
847
754
 
848
- // build a promise chain
849
- allDone.push(updateIconsPromise);
850
- });
755
+ return Promise.all(allDone);
756
+ }
851
757
 
852
- return Promise.all(allDone);
853
- };
758
+ handleWinApp() {
759
+ var self = this,
760
+ allDone = [];
761
+
762
+ this._forEachPlatform(async function (name, platform) {
763
+ if (
764
+ (!self.options.winIco && !self.options.winVersionString) ||
765
+ ["win32", "win64"].indexOf(name) < 0
766
+ )
767
+ return;
854
768
 
855
- NwBuilder.prototype.runApp = function () {
856
- var self = this;
769
+ var executableName = self.getExecutableName(name);
770
+ var executablePath = path.resolve(platform.releasePath, executableName);
857
771
 
858
- var currentPlatform = this.options.currentPlatform;
859
- var platform = this._platforms[currentPlatform];
860
- // if the user is on Windows/OS X 64-bit, but there is no 64-bit build, try the 32-bit build
861
- if (!platform) {
862
- if (["osx64", "win64"].indexOf(this.options.currentPlatform) !== -1) {
863
- currentPlatform = currentPlatform.split("64")[0] + "32";
864
- platform = this._platforms[currentPlatform];
772
+ await rename(
773
+ resolve(platform.releasePath, "nw.exe"),
774
+ resolve(platform.releasePath, executableName),
775
+ );
865
776
 
866
- if (!platform) {
867
- throw new Error(
868
- "currentPlatform selected (" +
869
- this.options.currentPlatform +
870
- ") doesn't exist in selected platforms (" +
871
- Object.keys(this._platforms).join(", ") +
872
- "). We also tried " +
873
- currentPlatform +
874
- " and that doesn't exist either",
777
+ var rcConf = {};
778
+ if (self.options.winVersionString) {
779
+ rcConf["version-string"] = Object.assign(
780
+ {},
781
+ {
782
+ // The process name used in the Task Manager
783
+ FileDescription: self.options.appName,
784
+ },
785
+ self.options.winVersionString,
875
786
  );
876
787
  }
877
- } else {
878
- throw new Error(
879
- "currentPlatform selected (" +
880
- currentPlatform +
881
- ") doesn't exist in selected platforms (" +
882
- Object.keys(this._platforms).join(", ") +
883
- ")",
884
- );
885
- }
886
- }
788
+ if (self.options.winIco && self.options.useRcedit) {
789
+ rcConf["icon"] = path.resolve(self.options.winIco);
790
+ }
887
791
 
888
- var runnable;
889
- if (this._version.isLegacy) {
890
- runnable = platform.getRunnable(this.options.version);
891
- } else {
892
- if (currentPlatform.indexOf("osx") === 0) {
893
- runnable = "nwjs.app/Contents/MacOS/nwjs";
894
- } else if (currentPlatform.indexOf("win") === 0) {
895
- runnable = "nw.exe";
896
- } else {
897
- runnable = "nw";
898
- }
899
- }
900
- var executable = path.resolve(platform.cache, runnable);
901
-
902
- self.emit("log", "Launching App");
903
- return new Promise(function (resolve, reject) {
904
- var parentDirectory = (
905
- _.isArray(self.options.files) ? self.options.files[0] : self.options.files
906
- ).replace(/\*[/*]*/, "");
907
- var nwProcess = (self._nwProcess = spawn(
908
- executable,
909
- [parentDirectory].concat(self.options.argv),
910
- {
911
- detached: true,
912
- windowsHide: true,
913
- },
914
- ));
915
-
916
- self.emit("appstart");
917
-
918
- nwProcess.stdout.on("data", function (data) {
919
- self.emit("stdout", data);
920
- });
792
+ var updateVersionStringPromise = rcedit(executablePath, rcConf);
921
793
 
922
- nwProcess.stderr.on("data", function (data) {
923
- self.emit("stderr", data);
924
- });
794
+ var updateIconsPromise = updateVersionStringPromise.then(function () {
795
+ return new Promise(function (resolve, reject) {
796
+ if (!self.options.winIco || self.options.useRcedit) {
797
+ resolve();
798
+ } else {
799
+ log.debug("Update " + name + " executable icon");
800
+ // Set icon
801
+ winresourcer(
802
+ {
803
+ operation: "Update",
804
+ exeFile: executablePath,
805
+ resourceType: "Icongroup",
806
+ resourceName: "IDR_MAINFRAME",
807
+ lang: 1033, // Required, except when updating or deleting
808
+ resourceFile: path.resolve(self.options.winIco),
809
+ },
810
+ function (err) {
811
+ if (!err) {
812
+ resolve();
813
+ } else {
814
+ reject(
815
+ "Error while updating the Windows icon." +
816
+ (process.platform !== "win32"
817
+ ? " Wine (winehq.org) must be installed to add custom icons from Mac and Linux."
818
+ : ""),
819
+ );
820
+ }
821
+ },
822
+ );
823
+ }
824
+ });
825
+ });
925
826
 
926
- nwProcess.on("error", function (err) {
927
- self.emit("log", "App launch error: " + err);
928
- reject(err);
827
+ // build a promise chain
828
+ allDone.push(updateIconsPromise);
929
829
  });
930
830
 
931
- nwProcess.on("close", function (code) {
932
- self._nwProcess = undefined;
933
- self.emit("log", "App exited with code " + code);
934
- resolve();
935
- });
936
- });
937
- };
831
+ return Promise.all(allDone);
832
+ }
938
833
 
939
- NwBuilder.prototype.isAppRunning = function () {
940
- return this._nwProcess !== undefined;
941
- };
834
+ async runApp() {
835
+ const options = this.options;
942
836
 
943
- NwBuilder.prototype.getAppProcess = function () {
944
- return this._nwProcess;
945
- };
837
+ let platform = options.currentPlatform.slice(
838
+ 0,
839
+ options.currentPlatform.length - 2,
840
+ );
841
+ let arch =
842
+ "x" + options.currentPlatform.slice(options.currentPlatform.length - 2);
843
+
844
+ await run({
845
+ version: options.version,
846
+ flavor: options.flavor,
847
+ platform: platform,
848
+ arch: arch,
849
+ srcDir: options.files,
850
+ cacheDir: options.cacheDir,
851
+ argv: options.argv,
852
+ });
853
+ }
946
854
 
947
- NwBuilder.prototype._forEachPlatform = function (fn) {
948
- _.forEach(this._platforms, function (platform, name) {
949
- return fn(name, platform);
950
- });
951
- };
855
+ isAppRunning() {
856
+ return this._nwProcess !== undefined;
857
+ }
952
858
 
953
- // Mac only
954
- NwBuilder.prototype.getResourcesDirectoryPath = function (platform) {
955
- return path.resolve(
956
- platform.releasePath,
957
- this.options.appName + ".app",
958
- "Contents",
959
- "Resources",
960
- );
961
- };
859
+ getAppProcess() {
860
+ return this._nwProcess;
861
+ }
962
862
 
963
- // Don't use if legacy version
964
- NwBuilder.prototype.getExecutableName = function (platform) {
965
- var executableExtension = "";
863
+ _forEachPlatform(fn) {
864
+ _.forEach(this._platforms, function (platform, name) {
865
+ return fn(name, platform);
866
+ });
867
+ }
966
868
 
967
- if (platform.indexOf("osx") === 0) {
968
- executableExtension = ".app";
969
- } else if (platform.indexOf("win") === 0) {
970
- executableExtension = ".exe";
869
+ // Mac only
870
+ getResourcesDirectoryPath(platform) {
871
+ return path.resolve(
872
+ platform.releasePath,
873
+ this.options.appName + ".app",
874
+ "Contents",
875
+ "Resources",
876
+ );
971
877
  }
972
878
 
973
- return this.options.appName + executableExtension;
974
- };
879
+ // Don't use if legacy version
880
+ getExecutableName(platform) {
881
+ var executableExtension = "";
975
882
 
976
- NwBuilder.prototype.setPlatformCacheDirectory = function (
977
- platformName,
978
- platform,
979
- version,
980
- flavor,
981
- ) {
982
- if (!platform.cache) {
983
- platform.cache = path.resolve(
984
- this.options.cacheDir,
985
- version + "-" + flavor,
986
- platformName,
987
- );
883
+ if (platform.indexOf("osx") === 0) {
884
+ executableExtension = ".app";
885
+ } else if (platform.indexOf("win") === 0) {
886
+ executableExtension = ".exe";
887
+ }
888
+
889
+ return this.options.appName + executableExtension;
988
890
  }
989
- };
990
891
 
991
- NwBuilder.prototype.isPlatformCached = function (
992
- platformName,
993
- platform,
994
- version,
995
- flavor,
996
- ) {
997
- this.setPlatformCacheDirectory(platformName, platform, version, flavor);
998
- if (this.options.forceDownload) {
999
- return false;
892
+ setPlatformCacheDirectory(platformName, platform, version, flavor) {
893
+ if (!platform.cache) {
894
+ platform.cache = path.resolve(
895
+ this.options.cacheDir,
896
+ version + "-" + flavor,
897
+ platformName,
898
+ );
899
+ }
1000
900
  }
1001
- this.preparePlatformFiles(platformName, platform, version);
1002
- return checkCache(platform.cache, platform.files);
1003
- };
1004
901
 
1005
- // returns a Boolean; true if the desired platform is supported
1006
- NwBuilder.prototype.preparePlatformFiles = function (
1007
- platformName,
1008
- platform,
1009
- version,
1010
- ) {
1011
- // return if platform.files is already prepared
1012
- if (
1013
- Object.keys(platform.files)[0] !==
1014
- Object.keys(Platforms[platformName].files)[0]
1015
- ) {
1016
- return true;
902
+ isPlatformCached(platformName, platform, version, flavor) {
903
+ this.setPlatformCacheDirectory(platformName, platform, version, flavor);
904
+ if (this.options.forceDownload) {
905
+ return false;
906
+ }
907
+ this.preparePlatformFiles(platformName, platform, version);
908
+ return checkCache(platform.cache, platform.files);
1017
909
  }
1018
910
 
1019
- if (semver.satisfies(version, "<0.12.3")) {
1020
- return !Object.keys(platform.files).every(function (range) {
1021
- if (semver.satisfies(version, range)) {
1022
- platform.files = platform.files[range];
1023
- if ("string" === typeof platform.files) {
1024
- platform.files = [platform.files];
1025
- }
1026
- return false;
1027
- }
911
+ // returns a Boolean; true if the desired platform is supported
912
+ preparePlatformFiles(platformName, platform, version) {
913
+ // return if platform.files is already prepared
914
+ if (
915
+ Object.keys(platform.files)[0] !==
916
+ Object.keys(Platforms[platformName].files)[0]
917
+ ) {
1028
918
  return true;
1029
- });
1030
- }
919
+ }
1031
920
 
1032
- platform.files = ["*"]; // otherwise bad stuff will happen like at attempt to download legacy version files
1033
- // all we can do here is assume it's oke because this._version might not exist yet, but callers of this function
1034
- // will check properly where necessary
1035
- return true;
1036
- };
921
+ if (semver.satisfies(version, "<0.12.3")) {
922
+ return !Object.keys(platform.files).every(function (range) {
923
+ if (semver.satisfies(version, range)) {
924
+ platform.files = platform.files[range];
925
+ if ("string" === typeof platform.files) {
926
+ platform.files = [platform.files];
927
+ }
928
+ return false;
929
+ }
930
+ return true;
931
+ });
932
+ }
933
+
934
+ platform.files = ["*"]; // otherwise bad stuff will happen like at attempt to download legacy version files
935
+ // all we can do here is assume it's oke because this._version might not exist yet, but callers of this function
936
+ // will check properly where necessary
937
+ return true;
938
+ }
939
+ }
1037
940
 
1038
941
  const nwbuild = (options) => {
1039
942
  let nw = new NwBuilder(options);
@@ -1041,15 +944,16 @@ const nwbuild = (options) => {
1041
944
  if (options.mode === "build") {
1042
945
  nw.build();
1043
946
  return 0;
1044
- } if (options.mode === "run") {
947
+ }
948
+ if (options.mode === "run") {
1045
949
  nw.run();
1046
950
  return 0;
1047
951
  } else {
1048
- console.error("[ WARN ] Invalid mode option.");
952
+ log.warn("[ WARN ] Invalid mode option.");
1049
953
  return 1;
1050
954
  }
1051
955
  };
1052
956
 
1053
957
  module.exports = NwBuilder;
1054
958
  exports = module.exports;
1055
- exports.nwbuild = nwbuild;
959
+ exports.nwbuild = nwbuild;