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