nw-builder 3.6.0 → 3.7.0
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/.github/CHANGELOG.md +58 -35
- package/.github/CODE_OF_CONDUCT.md +55 -0
- package/.github/{ISSUE_REQUEST_TEMPLATE.md → ISSUE_TEMPLATE.md} +1 -0
- package/.github/workflows/cd.yml +3 -3
- package/.github/workflows/ci.yml +7 -4
- package/README.md +81 -23
- package/bin/nwbuild.cjs +97 -0
- package/dist/index.cjs +1 -0
- package/lib/Version.cjs +81 -0
- package/lib/downloader.cjs +177 -0
- package/lib/index.cjs +1078 -0
- package/lib/{platformOverrides.js → platformOverrides.cjs} +61 -36
- package/lib/platforms.cjs +141 -0
- package/lib/utils.cjs +293 -0
- package/lib/versions.cjs +206 -0
- package/package.json +56 -28
- package/src/index.js +2 -0
- package/src/schema/Platform.js +16 -0
- package/src/schema/index.js +3 -0
- package/src/utilities/checkCache.js +30 -0
- package/src/utilities/detectCurrentPlatform.js +24 -0
- package/src/utilities/index.js +4 -0
- package/{example/icons → test/demo}/icon.icns +0 -0
- package/{example/icons → test/demo}/icon.ico +0 -0
- package/test/demo/index.cjs +14 -0
- package/test/demo/index.html +10 -0
- package/{example/nwapp → test/demo}/package.json +7 -6
- package/test/downloader.cjs +131 -0
- package/test/expected/README.md +1 -1
- package/test/expected/oneOveriddenRestNot/README.md +1 -1
- package/test/expected/oneOveriddenRestNot/osx32.json +7 -7
- package/test/expected/oneOveriddenRestNot/osx64.json +7 -7
- package/test/expected/osx-plist/README.md +1 -1
- package/test/expected/platformOverrides/README.md +1 -1
- package/test/expected/platformOverrides/linux32.json +12 -12
- package/test/expected/platformOverrides/linux64.json +8 -8
- package/test/expected/platformOverrides/osx32.json +10 -10
- package/test/expected/platformOverrides/osx64.json +10 -10
- package/test/expected/platformOverrides/win32.json +10 -10
- package/test/expected/platformOverrides/win64.json +10 -10
- package/test/fixtures/README.md +1 -1
- package/test/fixtures/invalid.json +1 -1
- package/test/fixtures/manifest/README.md +1 -1
- package/test/fixtures/manifest/versions.json +9 -3
- package/test/fixtures/nwapp/README.md +1 -1
- package/test/fixtures/nwapp/index.html +5 -2
- package/test/fixtures/nwapp/javascript/bower_packages/simple/package.json +1 -1
- package/test/fixtures/nwapp/javascript/jsfile.js +1 -1
- package/test/fixtures/nwapp/package.json +1 -1
- package/test/fixtures/oneOveriddenRestNot/README.md +1 -1
- package/test/fixtures/oneOveriddenRestNot/package.json +13 -13
- package/test/fixtures/osx-plist/README.md +1 -1
- package/test/fixtures/platformOverrides/README.md +1 -1
- package/test/fixtures/platformOverrides/package.json +68 -48
- package/test/fixtures/testVersions.html +73 -16
- package/test/nwBuilder.cjs +339 -0
- package/test/unit/checkCache.test.js +19 -0
- package/test/unit/checkCacheDir/v0.64.1/linux64/nw1.app +0 -0
- package/test/unit/checkCacheDir/v0.64.1/linux64/nw2.app +0 -0
- package/test/unit/detectCurrentPlatform.test.js +58 -0
- package/test/utils.cjs +310 -0
- package/test/versions.cjs +486 -0
- package/bin/nwbuild +0 -98
- package/demo.js +0 -22
- package/example/icons/README.md +0 -7
- package/example/nwapp/Credits.html +0 -9
- package/example/nwapp/README.md +0 -7
- package/example/nwapp/images/README.md +0 -7
- package/example/nwapp/images/kitten.jpg +0 -0
- package/example/nwapp/index.html +0 -22
- package/example/package.json +0 -7
- package/index.js +0 -1
- package/lib/Version.js +0 -60
- package/lib/detectCurrentPlatform.js +0 -17
- package/lib/downloader.js +0 -192
- package/lib/index.js +0 -873
- package/lib/platforms.js +0 -76
- package/lib/utils.js +0 -249
- package/lib/versions.js +0 -198
- package/test/downloader.js +0 -87
- package/test/nwBuilder.js +0 -237
- package/test/utils.js +0 -232
- package/test/versions.js +0 -330
package/lib/platforms.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
var semver = require('semver');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
win32: {
|
|
5
|
-
needsZip: true,
|
|
6
|
-
getRunnable: function() { return 'nw.exe'; },
|
|
7
|
-
files: { // First file must be the executable
|
|
8
|
-
'<=0.9.2': ['nw.exe', 'ffmpegsumo.dll', 'icudt.dll', 'libEGL.dll', 'libGLESv2.dll', 'nw.pak'],
|
|
9
|
-
'>0.9.2 <0.12.0': ['nw.exe', 'ffmpegsumo.dll', 'icudtl.dat', 'libEGL.dll', 'libGLESv2.dll', 'nw.pak', 'locales'],
|
|
10
|
-
'>=0.12.0': ['nw.exe', 'ffmpegsumo.dll', 'icudtl.dat', 'libEGL.dll', 'libGLESv2.dll', 'nw.pak', 'locales', 'd3dcompiler_47.dll', 'pdf.dll']
|
|
11
|
-
},
|
|
12
|
-
versionNameTemplate: 'v${ version }/${ name }-v${ version }-win-ia32.zip'
|
|
13
|
-
},
|
|
14
|
-
win64: {
|
|
15
|
-
needsZip: true,
|
|
16
|
-
getRunnable: function() { return 'nw.exe'; },
|
|
17
|
-
files: { // First file must be the executable
|
|
18
|
-
'<=0.9.2': ['nw.exe', 'ffmpegsumo.dll', 'icudt.dll', 'libEGL.dll', 'libGLESv2.dll', 'nw.pak', 'locales'],
|
|
19
|
-
'>0.9.2 <0.12.0': ['nw.exe', 'ffmpegsumo.dll', 'icudtl.dat', 'libEGL.dll', 'libGLESv2.dll', 'nw.pak', 'locales'],
|
|
20
|
-
'>=0.12.0': ['nw.exe', 'ffmpegsumo.dll', 'icudtl.dat', 'libEGL.dll', 'libGLESv2.dll', 'nw.pak', 'locales', 'd3dcompiler_47.dll', 'pdf.dll']
|
|
21
|
-
},
|
|
22
|
-
versionNameTemplate: 'v${ version }/${ name }-v${ version }-win-x64.zip'
|
|
23
|
-
},
|
|
24
|
-
osx32: {
|
|
25
|
-
needsZip: false,
|
|
26
|
-
getRunnable: function(version) {
|
|
27
|
-
if(semver.satisfies(version, '>=0.12.0 || ~0.12.0-alpha')) {
|
|
28
|
-
return 'nwjs.app/Contents/MacOS/nwjs';
|
|
29
|
-
} else {
|
|
30
|
-
return 'node-webkit.app/Contents/MacOS/node-webkit';
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
files: {
|
|
34
|
-
'<0.12.0-alpha': ['node-webkit.app'],
|
|
35
|
-
'>=0.12.0 || ~0.12.0-alpha': ['nwjs.app']
|
|
36
|
-
},
|
|
37
|
-
versionNameTemplate: 'v${ version }/${ name }-v${ version }-osx-ia32.zip'
|
|
38
|
-
},
|
|
39
|
-
osx64: {
|
|
40
|
-
needsZip: false,
|
|
41
|
-
getRunnable: function(version) {
|
|
42
|
-
if(semver.satisfies(version, '>=0.12.0 || ~0.12.0-alpha')) {
|
|
43
|
-
return 'nwjs.app/Contents/MacOS/nwjs';
|
|
44
|
-
} else {
|
|
45
|
-
return 'node-webkit.app/Contents/MacOS/node-webkit';
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
files: {
|
|
49
|
-
'<0.12.0-alpha': ['node-webkit.app'],
|
|
50
|
-
'>=0.12.0 || ~0.12.0-alpha': ['nwjs.app']
|
|
51
|
-
},
|
|
52
|
-
versionNameTemplate: 'v${ version }/${ name }-v${ version }-osx-x64.zip'
|
|
53
|
-
},
|
|
54
|
-
linux32: {
|
|
55
|
-
needsZip: true,
|
|
56
|
-
chmod: '0755',
|
|
57
|
-
getRunnable: function() { return 'nw'; },
|
|
58
|
-
files: { // First file must be the executable
|
|
59
|
-
'<=0.9.2': ['nw', 'nw.pak', 'libffmpegsumo.so'],
|
|
60
|
-
'>0.9.2 <=0.10.1': ['nw', 'nw.pak', 'libffmpegsumo.so', 'icudtl.dat'],
|
|
61
|
-
'>0.10.1': ['nw', 'nw.pak', 'libffmpegsumo.so', 'icudtl.dat', 'locales']
|
|
62
|
-
},
|
|
63
|
-
versionNameTemplate: 'v${ version }/${ name }-v${ version }-linux-ia32.tar.gz'
|
|
64
|
-
},
|
|
65
|
-
linux64: {
|
|
66
|
-
needsZip: true,
|
|
67
|
-
chmod: '0755', // chmod file file to be executable
|
|
68
|
-
getRunnable: function() { return 'nw'; },
|
|
69
|
-
files: { // First file must be the executable
|
|
70
|
-
'<=0.9.2': ['nw', 'nw.pak', 'libffmpegsumo.so'],
|
|
71
|
-
'>0.9.2 <=0.10.1': ['nw', 'nw.pak', 'libffmpegsumo.so', 'icudtl.dat'],
|
|
72
|
-
'>0.10.1': ['nw', 'nw.pak', 'libffmpegsumo.so', 'icudtl.dat', 'locales']
|
|
73
|
-
},
|
|
74
|
-
versionNameTemplate: 'v${ version }/${ name }-v${ version }-linux-x64.tar.gz'
|
|
75
|
-
}
|
|
76
|
-
};
|
package/lib/utils.js
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
var fs = require('graceful-fs-extra');
|
|
2
|
-
var path = require('path');
|
|
3
|
-
var _ = require('lodash');
|
|
4
|
-
var plist = require('plist');
|
|
5
|
-
var Glob = require('simple-glob');
|
|
6
|
-
var temp = require('temp');
|
|
7
|
-
var archiver = require('archiver');
|
|
8
|
-
var thenify = require('thenify');
|
|
9
|
-
|
|
10
|
-
var readFile = thenify(fs.readFile);
|
|
11
|
-
var writeFile = thenify(fs.writeFile);
|
|
12
|
-
|
|
13
|
-
// Automatically track and cleanup files at exit
|
|
14
|
-
temp.track();
|
|
15
|
-
|
|
16
|
-
module.exports = {
|
|
17
|
-
getPackageInfo: function(path) {
|
|
18
|
-
return new Promise(function(resolve, reject) {
|
|
19
|
-
fs.readFile(path, function (err, data) {
|
|
20
|
-
if (err) return reject(err);
|
|
21
|
-
try {
|
|
22
|
-
var appPkg = JSON.parse(data);
|
|
23
|
-
} catch(e) {
|
|
24
|
-
reject("Invalid package.json: " + e + "\nMake sure the file is encoded as utf-8");
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (!appPkg.name || !appPkg.version) {
|
|
28
|
-
reject("Please make sure that your project's package.json includes a version and a name value");
|
|
29
|
-
} else {
|
|
30
|
-
resolve(appPkg);
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
},
|
|
35
|
-
getFileList: function(fileglob) {
|
|
36
|
-
var self = this,
|
|
37
|
-
jsonfile, destFiles = [],
|
|
38
|
-
srcFiles = [],
|
|
39
|
-
package_path,
|
|
40
|
-
matches = Glob(fileglob);
|
|
41
|
-
|
|
42
|
-
return new Promise(function(resolve, reject) {
|
|
43
|
-
if(!matches.length) return reject('No files matching');
|
|
44
|
-
|
|
45
|
-
matches.forEach(function(file) {
|
|
46
|
-
var internalFileName = path.normalize(file);
|
|
47
|
-
if (internalFileName.match('package.json')) {
|
|
48
|
-
jsonfile = self.closerPathDepth(internalFileName, jsonfile);
|
|
49
|
-
package_path = path.normalize(jsonfile.split('package.json')[0] || './');
|
|
50
|
-
}
|
|
51
|
-
if(!fs.lstatSync(internalFileName).isDirectory()) {
|
|
52
|
-
srcFiles.push(internalFileName);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
if (!jsonfile) {
|
|
57
|
-
return reject('Could not find a package.json in your src folder');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
srcFiles.forEach(function(file) {
|
|
61
|
-
destFiles.push({
|
|
62
|
-
src: file,
|
|
63
|
-
dest: file.replace(package_path, '')
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
resolve({
|
|
68
|
-
files: destFiles,
|
|
69
|
-
json: jsonfile
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
},
|
|
73
|
-
closerPathDepth: function(path1, path2) {
|
|
74
|
-
if (!path2) { return path1; }
|
|
75
|
-
|
|
76
|
-
var d1 = this.pathDepth(path1),
|
|
77
|
-
d2 = this.pathDepth(path2);
|
|
78
|
-
|
|
79
|
-
return d1 < d2 ? path1 : path2;
|
|
80
|
-
},
|
|
81
|
-
pathDepth: function(absolutePath) {
|
|
82
|
-
return absolutePath.split(path.sep).length;
|
|
83
|
-
},
|
|
84
|
-
copyFile: function (src, dest, _event, options) {
|
|
85
|
-
return new Promise(function(resolve, reject) {
|
|
86
|
-
options = options || {};
|
|
87
|
-
var stats = fs.lstatSync(src);
|
|
88
|
-
fs.copy(src, dest, options, function (err) {
|
|
89
|
-
if(err) return reject(err);
|
|
90
|
-
|
|
91
|
-
var retryCount = 0;
|
|
92
|
-
var existsCallback = function(exists){
|
|
93
|
-
if(exists){
|
|
94
|
-
fs.chmod(dest, stats.mode, function(err){
|
|
95
|
-
// ignore error
|
|
96
|
-
if (err) {
|
|
97
|
-
_event.emit('log', 'chmod ' + stats.mode + ' on ' + dest + ' failed after copying, ignoring');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
resolve();
|
|
101
|
-
});
|
|
102
|
-
} else if (retryCount++ < 2) {
|
|
103
|
-
// This is antipattern!!!
|
|
104
|
-
// Callback should be called when the copy is finished!!!!
|
|
105
|
-
setTimeout(function(){
|
|
106
|
-
fs.exists(dest, existsCallback);
|
|
107
|
-
}, 1000);
|
|
108
|
-
} else {
|
|
109
|
-
reject(new Error("Copied file (" + dest + ") doesn't exist in destination after copying"));
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
fs.exists(dest, existsCallback);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
mergeFiles: function (app, zipfile, chmod) {
|
|
118
|
-
// we need to pipe the app into the zipfile and chmod it
|
|
119
|
-
return new Promise(function(resolve, reject) {
|
|
120
|
-
var zipStream = fs.createReadStream(zipfile),
|
|
121
|
-
writeStream = fs.createWriteStream(app, {flags:'a'});
|
|
122
|
-
|
|
123
|
-
zipStream.on('error', reject);
|
|
124
|
-
writeStream.on('error', reject);
|
|
125
|
-
|
|
126
|
-
writeStream.on('finish', function () {
|
|
127
|
-
if(chmod) {
|
|
128
|
-
fs.chmodSync(app, chmod);
|
|
129
|
-
}
|
|
130
|
-
resolve();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
zipStream.pipe(writeStream);
|
|
134
|
-
});
|
|
135
|
-
},
|
|
136
|
-
generateZipFile: function (files, _event, platformSpecificManifest, zipOptions) {
|
|
137
|
-
var destStream = temp.createWriteStream(),
|
|
138
|
-
archive = archiver('zip', zipOptions || {});
|
|
139
|
-
|
|
140
|
-
return new Promise(function(resolve, reject) {
|
|
141
|
-
|
|
142
|
-
// Resolve on close
|
|
143
|
-
destStream.on('close', function () {
|
|
144
|
-
resolve(destStream.path);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Reject on Error
|
|
148
|
-
archive.on('error', reject);
|
|
149
|
-
|
|
150
|
-
// Add the files
|
|
151
|
-
var filesBulk = [];
|
|
152
|
-
files.forEach(function(file){
|
|
153
|
-
if(file.dest === 'package.json' && platformSpecificManifest){
|
|
154
|
-
archive.append(platformSpecificManifest, {name: 'package.json'});
|
|
155
|
-
}
|
|
156
|
-
else
|
|
157
|
-
{
|
|
158
|
-
archive.file(file.src, {name: file.dest});
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Some logs
|
|
163
|
-
archive.on('entry', function (file) {
|
|
164
|
-
_event.emit('log', 'Zipping ' + file.name);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// Pipe the stream
|
|
168
|
-
archive.pipe(destStream);
|
|
169
|
-
archive.finalize();
|
|
170
|
-
|
|
171
|
-
});
|
|
172
|
-
},
|
|
173
|
-
getPlistOptions: function(parsedParams, custom) {
|
|
174
|
-
var obj = {};
|
|
175
|
-
if(parsedParams.name) {
|
|
176
|
-
obj.CFBundleName = parsedParams.name;
|
|
177
|
-
obj.CFBundleDisplayName = parsedParams.name;
|
|
178
|
-
}
|
|
179
|
-
if(parsedParams.version) {
|
|
180
|
-
obj.CFBundleVersion = parsedParams.version;
|
|
181
|
-
obj.CFBundleShortVersionString = 'Version ' + parsedParams.version;
|
|
182
|
-
}
|
|
183
|
-
if(parsedParams.copyright) {
|
|
184
|
-
obj.NSHumanReadableCopyright = parsedParams.copyright;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return _.merge(obj, custom);
|
|
188
|
-
},
|
|
189
|
-
editPlist: function(plistInput, plistOutput, options) {
|
|
190
|
-
options = options || {};
|
|
191
|
-
|
|
192
|
-
// Make sure all required properties are set
|
|
193
|
-
[
|
|
194
|
-
'CFBundleName',
|
|
195
|
-
'CFBundleDisplayName',
|
|
196
|
-
'CFBundleVersion',
|
|
197
|
-
'CFBundleShortVersionString'
|
|
198
|
-
].forEach(function(prop) {
|
|
199
|
-
if(!options.hasOwnProperty(prop)) {
|
|
200
|
-
throw new Error('Missing macPlist property \'' + prop + '\'');
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
// Bundle identifier based on package name
|
|
205
|
-
if(options.CFBundleIdentifier === undefined) {
|
|
206
|
-
options.CFBundleIdentifier = 'com.nw-builder.' + options.CFBundleName.toLowerCase().replace(/[^a-z\-]/g,'');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Read the input file
|
|
210
|
-
return readFile(plistInput, 'utf8')
|
|
211
|
-
// Parse it
|
|
212
|
-
.then(plist.parse)
|
|
213
|
-
// Then overwrite the properties with custom values
|
|
214
|
-
.then(function(info) {
|
|
215
|
-
// Keep backwards compatibility and handle aliases
|
|
216
|
-
Object.keys(options).forEach(function(key) {
|
|
217
|
-
var value = options[key];
|
|
218
|
-
switch(key) {
|
|
219
|
-
case 'mac_bundle_id':
|
|
220
|
-
info.CFBundleIdentifier = value;
|
|
221
|
-
break;
|
|
222
|
-
case 'mac_document_types':
|
|
223
|
-
info.CFBundleDocumentTypes = value.map(function(type) {
|
|
224
|
-
return {
|
|
225
|
-
CFBundleTypeName: type.name,
|
|
226
|
-
CFBundleTypeExtensions: type.extensions,
|
|
227
|
-
CFBundleTypeRole: type.role,
|
|
228
|
-
LSIsAppleDefaultForType: type.isDefault
|
|
229
|
-
};
|
|
230
|
-
});
|
|
231
|
-
break;
|
|
232
|
-
default:
|
|
233
|
-
info[key] = value;
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
// Remove some unwanted properties
|
|
238
|
-
if(!(options.hasOwnProperty('mac_document_types') || options.hasOwnProperty('CFBundleDocumentTypes'))) {
|
|
239
|
-
info.CFBundleDocumentTypes = [];
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if(!options.hasOwnProperty('UTExportedTypeDeclarations'))
|
|
243
|
-
info.UTExportedTypeDeclarations = [];
|
|
244
|
-
|
|
245
|
-
// Write output file
|
|
246
|
-
return writeFile(plistOutput, plist.build(info));
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
};
|
package/lib/versions.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
var platforms = require('./platforms');
|
|
2
|
-
var semver = require('semver');
|
|
3
|
-
var request = require('request');
|
|
4
|
-
var _ = require('lodash');
|
|
5
|
-
var Version = require('./Version');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @param {string} url
|
|
9
|
-
* @param {object} options - Passed to request
|
|
10
|
-
* @returns {promise} which resolves to response body
|
|
11
|
-
*/
|
|
12
|
-
function get(url, options){
|
|
13
|
-
return new Promise(function(resolve, reject){
|
|
14
|
-
request(url, options, function (err, res, body) {
|
|
15
|
-
if (err) {
|
|
16
|
-
reject(err);
|
|
17
|
-
} else if (res.statusCode !== 200) {
|
|
18
|
-
reject('Received status code ' + res.statusCode + ': ' + url);
|
|
19
|
-
} else {
|
|
20
|
-
resolve(body);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @param {string} downloadUrl
|
|
28
|
-
* @returns {promise} which resolves to an array of {Version}s
|
|
29
|
-
*/
|
|
30
|
-
function getLegacyVersions(downloadUrl, flavor){
|
|
31
|
-
var scrapePtrn = /href="v?([0-9]+\.[0-9]+\.[0-9]+[^"]*)\/"/ig,
|
|
32
|
-
searchRes,
|
|
33
|
-
versions = [];
|
|
34
|
-
|
|
35
|
-
return get(downloadUrl).then(function(body){
|
|
36
|
-
// scrapes valid semver versions from apache directory listing
|
|
37
|
-
while ((searchRes = scrapePtrn.exec(body)) !== null) {
|
|
38
|
-
searchRes = searchRes[1];
|
|
39
|
-
if( semver.valid(searchRes) && !_.includes(versions, searchRes) ) {
|
|
40
|
-
versions.push(searchRes);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// order with newest version at front of array
|
|
44
|
-
versions = versions.sort(function(a,b){ return semver.compare(b,a); });
|
|
45
|
-
|
|
46
|
-
// filter out invalid / alpha versions
|
|
47
|
-
var validationPromises = [];
|
|
48
|
-
versions.forEach(function(version){
|
|
49
|
-
if(!isLegacyVersion(version)){
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
validationPromises.push(new Promise(function(resolve, reject){
|
|
53
|
-
// check if windows 64-bit ZIP exists
|
|
54
|
-
var win32Url = new Version({
|
|
55
|
-
version: version,
|
|
56
|
-
flavors: ['sdk'],
|
|
57
|
-
supportedPlatforms: ['win32'],
|
|
58
|
-
downloadUrl: downloadUrl
|
|
59
|
-
}).platforms['win32-sdk'];
|
|
60
|
-
request.head(win32Url, function(err, res){
|
|
61
|
-
// note: this takes a version string and replaces it with an object (will be converted back later)
|
|
62
|
-
resolve({
|
|
63
|
-
version: version,
|
|
64
|
-
flavors: ['sdk'],
|
|
65
|
-
valid: !err && res.statusCode === 200
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
}));
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
var allPlatforms = Object.keys(platforms);
|
|
73
|
-
|
|
74
|
-
return Promise.all(validationPromises)
|
|
75
|
-
.then(function(versions){
|
|
76
|
-
// convert back to array of version strings (filtered)
|
|
77
|
-
return versions.filter(function(versionObj){
|
|
78
|
-
return versionObj.valid;
|
|
79
|
-
})
|
|
80
|
-
.map(function(versionObj){
|
|
81
|
-
return new Version({
|
|
82
|
-
version: versionObj.version,
|
|
83
|
-
flavors: versionObj.flavors,
|
|
84
|
-
supportedPlatforms: allPlatforms,
|
|
85
|
-
downloadUrl: downloadUrl
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @param {string?} manifestUrl
|
|
94
|
-
* @returns {promise} which resolves to response body
|
|
95
|
-
*/
|
|
96
|
-
function getManifest(manifestUrl){
|
|
97
|
-
if (!manifestUrl){
|
|
98
|
-
manifestUrl='https://nwjs.io/versions.json';
|
|
99
|
-
}
|
|
100
|
-
return get(manifestUrl, { json: true }).then(function(body){
|
|
101
|
-
return body;
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @param {string} downloadUrl
|
|
107
|
-
* @param {string} manifestUrl
|
|
108
|
-
* @param {string} flavor
|
|
109
|
-
* @returns {promise} which resolves to an array of {Version}s
|
|
110
|
-
*/
|
|
111
|
-
function getVersionsFromManifest(downloadUrl, manifestUrl, flavor){
|
|
112
|
-
var mapFilesToPlatforms = function(files){
|
|
113
|
-
return files.map(function(file){
|
|
114
|
-
// convert win-x64 to win64, linux-ia32 to linux 32, etc.
|
|
115
|
-
return file.replace(/-(x|ia)/, '');
|
|
116
|
-
});
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
return getManifest(manifestUrl).then(function(manifest){
|
|
120
|
-
return manifest.versions
|
|
121
|
-
.filter(function(versionFromManifest){
|
|
122
|
-
// 0.12.3 is an exception that is in the manifest but is kind of a legacy version
|
|
123
|
-
return (versionFromManifest.flavors !== undefined) && ( versionFromManifest.flavors.indexOf('sdk') !== -1 || versionFromManifest.version === 'v0.12.3');
|
|
124
|
-
})
|
|
125
|
-
.map(function(versionFromManifest){
|
|
126
|
-
return new Version({
|
|
127
|
-
version: versionFromManifest.version.replace('v', ''),
|
|
128
|
-
flavors: versionFromManifest.flavors,
|
|
129
|
-
supportedPlatforms: mapFilesToPlatforms(versionFromManifest.files),
|
|
130
|
-
downloadUrl: downloadUrl
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* @param {string} version
|
|
138
|
-
* @returns {boolean}
|
|
139
|
-
*/
|
|
140
|
-
function isLegacyVersion(version){
|
|
141
|
-
return semver.lte(version, '0.12.3');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
module.exports = {
|
|
145
|
-
/**
|
|
146
|
-
* Gets the latest stable version
|
|
147
|
-
* @param {string} downloadUrl
|
|
148
|
-
* @param {string} manifestUrl
|
|
149
|
-
* @param {string} flavor
|
|
150
|
-
* @returns {promise} which resolves to a {Version}
|
|
151
|
-
*/
|
|
152
|
-
getLatestVersion: function(downloadUrl, manifestUrl, flavor) {
|
|
153
|
-
return getManifest(manifestUrl)
|
|
154
|
-
.then(function(manifest) {
|
|
155
|
-
return {
|
|
156
|
-
desiredVersion: manifest.stable.replace('v', ''),
|
|
157
|
-
downloadUrl: downloadUrl,
|
|
158
|
-
manifestUrl: manifestUrl,
|
|
159
|
-
flavor: flavor
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
.then(this.getVersion);
|
|
163
|
-
},
|
|
164
|
-
/**
|
|
165
|
-
* @param {string} args.desiredVersion
|
|
166
|
-
* @param {string} args.downloadUrl
|
|
167
|
-
* @param {string} args.manifestUrl
|
|
168
|
-
* @param {string} args.flavor
|
|
169
|
-
* @returns {promise} which resolves to a {Version}
|
|
170
|
-
*/
|
|
171
|
-
getVersion: function(args){
|
|
172
|
-
return (isLegacyVersion(args.desiredVersion) ? getLegacyVersions : getVersionsFromManifest)(args.downloadUrl, args.manifestUrl)
|
|
173
|
-
.then(function(versions) {
|
|
174
|
-
var version = versions.findIndex(function(version){
|
|
175
|
-
return version.version === args.desiredVersion;
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
return version >= 0
|
|
179
|
-
? Promise.resolve(versions[version])
|
|
180
|
-
: Promise.reject('Version ' + args.desiredVersion + ' not found.');
|
|
181
|
-
});
|
|
182
|
-
},
|
|
183
|
-
/**
|
|
184
|
-
* @param {string} downloadUrl
|
|
185
|
-
* @param {string} manifestUrl
|
|
186
|
-
* @param {string} flavor
|
|
187
|
-
* @returns {promise} which resolves to an array of {Version}s
|
|
188
|
-
*/
|
|
189
|
-
getVersions: function(downloadUrl, manifestUrl, flavor){
|
|
190
|
-
return Promise.all([
|
|
191
|
-
getVersionsFromManifest(downloadUrl, manifestUrl, flavor),
|
|
192
|
-
getLegacyVersions(downloadUrl, flavor)
|
|
193
|
-
])
|
|
194
|
-
.then(function(versionLists){
|
|
195
|
-
return versionLists[0].concat(versionLists[1]);
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
};
|
package/test/downloader.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
var test = require('tape'),
|
|
2
|
-
nock = require('nock'),
|
|
3
|
-
temp = require('temp'),
|
|
4
|
-
path = require('path'),
|
|
5
|
-
fs = require('fs');
|
|
6
|
-
|
|
7
|
-
temp.track();
|
|
8
|
-
|
|
9
|
-
var downloader = require('./../lib/downloader');
|
|
10
|
-
var fixturesCache = './test/fixtures/cache/v0.8.3';
|
|
11
|
-
var fixturesZip = './test/fixtures/test.zip';
|
|
12
|
-
var fixturesZipStrip = './test/fixtures/test-strip.zip';
|
|
13
|
-
var fixturesTar = './test/fixtures/test.tar.gz';
|
|
14
|
-
var isWindows = process.platform === 'win32';
|
|
15
|
-
|
|
16
|
-
test('checkCache', function (t) {
|
|
17
|
-
t.plan(2);
|
|
18
|
-
t.ok(downloader.checkCache(fixturesCache + '/osx', ['node-webkit.app']));
|
|
19
|
-
t.notOk(downloader.checkCache(fixturesCache + '/linux32', ['nwsnapshot', 'nwsnapshot2']));
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test('downloadAndUnpack: zip', function (t) {
|
|
23
|
-
t.plan(isWindows ? 3 : 6);
|
|
24
|
-
nock('https://amazon.s3.nw.com').get('/test.zip').replyWithFile(200, fixturesZip);
|
|
25
|
-
temp.mkdir('tmpcache', function(err, dirPath) {
|
|
26
|
-
downloader.downloadAndUnpack(dirPath, 'https://amazon.s3.nw.com/test.zip').then(function (files) {
|
|
27
|
-
files.forEach(function (file) {
|
|
28
|
-
t.ok(fs.existsSync(path.join(dirPath, file.path)), file.path + ' unpacked');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
if(!isWindows) {
|
|
32
|
-
t.ok(fs.statSync(path.join(dirPath, 'file1')).mode.toString(8) == 100444, '444 file permission');
|
|
33
|
-
t.ok(fs.statSync(path.join(dirPath, 'file2')).mode.toString(8) == 100666, '666 file permission');
|
|
34
|
-
t.ok(fs.statSync(path.join(dirPath, 'file3')).mode.toString(8) == 100644, '644 file permission'); // DOES NOT WORK ON WINDOWS
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('downloadAndUnpack: zip+strip', function (t) {
|
|
41
|
-
t.plan(isWindows ? 3 : 6);
|
|
42
|
-
nock('https://amazon.s3.nw.com').get('/test-strip.zip').replyWithFile(200, fixturesZipStrip);
|
|
43
|
-
temp.mkdir('tmpcache', function(err, dirPath) {
|
|
44
|
-
downloader.downloadAndUnpack(dirPath, 'https://amazon.s3.nw.com/test-strip.zip').then(function (files) {
|
|
45
|
-
files.forEach(function (file) {
|
|
46
|
-
t.ok(fs.existsSync(path.join(dirPath, file.path)), file.path + ' unpacked');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
if(!isWindows) {
|
|
50
|
-
t.ok(fs.statSync(path.join(dirPath, 'file1')).mode.toString(8) == 100444, '444 file permission');
|
|
51
|
-
t.ok(fs.statSync(path.join(dirPath, 'file2')).mode.toString(8) == 100666, '666 file permission');
|
|
52
|
-
t.ok(fs.statSync(path.join(dirPath, 'file3')).mode.toString(8) == 100644, '644 file permission'); // DOES NOT WORK ON WINDOWS
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
test('downloadAndUnpack: tar', function (t) {
|
|
59
|
-
t.plan(isWindows ? 3 : 6);
|
|
60
|
-
nock('https://amazon.s3.nw.com').get('/test.tar.gz').replyWithFile(200, fixturesTar);
|
|
61
|
-
temp.mkdir('tmpcache', function(err, dirPath) {
|
|
62
|
-
downloader.downloadAndUnpack(dirPath, 'https://amazon.s3.nw.com/test.tar.gz').then(function (files) {
|
|
63
|
-
files.forEach(function (file) {
|
|
64
|
-
t.ok(fs.existsSync(path.join(dirPath, file.path)), file.path + ' unpacked');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
if(!isWindows) {
|
|
68
|
-
t.ok(fs.statSync(path.join(dirPath, 'file1')).mode.toString(8) == 100444, '444 file permission'); // DOES NOT WORK ON WINDOWS
|
|
69
|
-
t.ok(fs.statSync(path.join(dirPath, 'file2')).mode.toString(8) == 100666, '666 file permission');
|
|
70
|
-
t.ok(fs.statSync(path.join(dirPath, 'file3')).mode.toString(8) == 100644, '644 file permission'); // DOES NOT WORK ON WINDOWS
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test('Should throw an error if you try to download a file that is not available', function (t) {
|
|
78
|
-
t.plan(2);
|
|
79
|
-
nock('https://doesnot.com').get('/exist.zip').reply(404);
|
|
80
|
-
downloader.downloadAndUnpack('/', 'https://doesnot.com/exist.zip').catch(function (err) {
|
|
81
|
-
t.equal(err.statusCode, 404, err.msg);
|
|
82
|
-
});
|
|
83
|
-
nock('https://doesnot.com').get('/exist.tar').reply(404);
|
|
84
|
-
downloader.downloadAndUnpack('/', 'https://doesnot.com/exist.tar').catch(function (err) {
|
|
85
|
-
t.equal(err.statusCode, 404, err.msg);
|
|
86
|
-
});
|
|
87
|
-
});
|