-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactor install script: * Convert from CJS to ESM * Improve code documentation * Adopt many ES6+ coding styles (let/const, promises, optional chaining, endsWith, etc.) * Manifest Maintenance: * Reduce dependencies from 10 to 5 by swapping most out for native Node modules, or newer alternatives. * Updated dependencies. * Remove "engines" and "packageManager" from manifest to avoid reported issues. * Bug fixes: * #26 & #74 - Freezing during or after post-install step. * #77 - Decompress API change bug. Swapped Decompress for Compressing. * #93 - Errors on install and deprecation warnings * #109 - Engines/packageManager mismatch
- Loading branch information
1 parent
8f6ac34
commit 86b52bc
Showing
4 changed files
with
357 additions
and
880 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
import { createWriteStream, existsSync } from 'node:fs'; | ||
import { rename, rm } from 'node:fs/promises'; | ||
import { get } from 'node:https'; | ||
import { dirname, resolve } from 'node:path'; | ||
import { arch, env, platform, exit } from 'node:process'; | ||
import { fileURLToPath, URL } from 'node:url'; | ||
|
||
import compressing from 'compressing'; | ||
import progress from 'cli-progress'; | ||
import semver from 'semver'; | ||
|
||
import nodeManifest from '../package.json' assert { type: 'json' }; | ||
|
||
/** | ||
* NW.js build flavor | ||
* | ||
* @type {'sdk' | 'normal'} | ||
*/ | ||
let buildType = env.npm_config_nwjs_build_type || env.NWJS_BUILD_TYPE || 'normal'; | ||
|
||
/** | ||
* Parsed string version to Semver version object | ||
*/ | ||
let parsedVersion = semver.parse(nodeManifest.version); | ||
|
||
/** | ||
* Version string of the format `X.Y.Z-pre`. | ||
* The prerelease segment `pre` is used to specify build flavor, or other tags. | ||
* | ||
* @type {string} | ||
*/ | ||
let versionString = [ | ||
parsedVersion.major, | ||
parsedVersion.minor, | ||
parsedVersion.patch | ||
].join('.'); | ||
|
||
// Check if version is a prelease. | ||
if (typeof parsedVersion?.prerelease?.[0] === 'string') { | ||
let prerelease = parsedVersion.prerelease[0].split('-'); | ||
if (prerelease.length > 1) { | ||
prerelease = prerelease.slice(0, -1); | ||
} | ||
versionString = [versionString, ...prerelease].join('-'); | ||
} | ||
|
||
// Check build flavor and slice that off the `versionString`. | ||
if (versionString.endsWith('-sdk')) { | ||
versionString = versionString.slice(0, -4); | ||
buildType = 'sdk'; | ||
} else if (versionString.endsWith('sdk')) { | ||
versionString = versionString.slice(0, -3); | ||
buildType = 'sdk'; | ||
} | ||
|
||
/** | ||
* URL to download or get binaries from. | ||
* | ||
* @type {string} | ||
*/ | ||
let url = ''; | ||
|
||
/** | ||
* Host operating system | ||
* | ||
* @type {NodeJS.Platform | 'osx' | 'win'} | ||
*/ | ||
let hostOs = env.npm_config_nwjs_platform || env.NWJS_PLATFORM || platform; | ||
|
||
/** | ||
* Host architecture | ||
* | ||
* @type {NodeJS.Architecture} | ||
*/ | ||
let hostArch = env.npm_config_nwjs_process_arch || arch; | ||
|
||
/** | ||
* URL base prepended to `url`. | ||
* | ||
* @type {string} | ||
*/ | ||
let urlBase = env.npm_config_nwjs_urlbase || env.NWJS_URLBASE || 'https://dl.nwjs.io/v'; | ||
|
||
const PLATFORM_KV = { | ||
darwin: 'osx', | ||
linux: 'linux', | ||
win32: 'win', | ||
}; | ||
|
||
const ARCH_KV = { | ||
x64: 'x64', | ||
ia32: 'ia32', | ||
arm64: 'arm64', | ||
}; | ||
|
||
url = [ | ||
urlBase, | ||
versionString, | ||
'/nwjs', | ||
buildType === 'normal' ? '' : `-${buildType}`, | ||
'-v', | ||
versionString, | ||
'-', | ||
PLATFORM_KV[hostOs], | ||
'-', | ||
ARCH_KV[hostArch], | ||
PLATFORM_KV[hostOs] === 'linux' ? '.tar.gz' : '.zip' | ||
].join(''); | ||
|
||
if (!PLATFORM_KV[hostOs] || !ARCH_KV[hostArch]) { | ||
console.error('[ ERROR ] Could not find a compatible version of nw.js to download for your platform.'); | ||
exit(1); | ||
} | ||
|
||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
|
||
/** | ||
* The folder where NW.js binaries are placed. | ||
* | ||
* @type {string} | ||
*/ | ||
let nwDir = resolve(__dirname, '..', 'nwjs'); | ||
|
||
if (existsSync(nwDir) === true) { | ||
exit(0); | ||
} | ||
|
||
let parsedUrl = new URL(url); | ||
|
||
/** | ||
* Path to the compressed binary. | ||
* | ||
* @type {string} | ||
*/ | ||
let filePath = ''; | ||
|
||
/** | ||
* Recursively delete the passed in directory. | ||
* Rename the downloaded file. | ||
* @param {string} dir - directory to remove | ||
*/ | ||
const rmAndRename = async (dir) => { | ||
await rm(dir, { recursive: true, force: true }); | ||
await rename(`nwjs-v${versionString}-${PLATFORM_KV[hostOs]}-${ARCH_KV[hostArch]}`, 'nwjs'); | ||
}; | ||
|
||
/** | ||
* @param {'zip' | 'tgz'} zipOrTgz | ||
* @param {string} filePath | ||
* @return {Promise<void>} | ||
*/ | ||
const decompress = function (zipOrTgz, filePath) { | ||
return compressing[zipOrTgz].uncompress(filePath, '.') | ||
.then(async () => await rmAndRename(filePath)); | ||
} | ||
|
||
// If the url is linking to the file system, | ||
// then it is assumed that a compressed binary exists in that location. | ||
if (parsedUrl.protocol === 'file:') { | ||
filePath = resolve(decodeURIComponent(url.slice('file://'.length))); | ||
|
||
if (existsSync(filePath) === false) { | ||
console.error('[ ERROR ] Could not find ' + filePath); | ||
} | ||
|
||
// If the compressed file is of ZIP format: | ||
if (filePath.endsWith('.zip')) { | ||
decompress('zip', filePath); | ||
// If the compressed file is of TGZ format: | ||
} else if (filePath.endsWith('.tar.gz')) { | ||
decompress('tgz', filePath); | ||
} else { | ||
console.error(`[ ERROR ] Expected .zip or .tar.gz file format. Got ${filePath}`); | ||
exit(1); | ||
} | ||
|
||
} else { | ||
|
||
const bar = new progress.SingleBar({}, progress.Presets.rect); | ||
|
||
const stream = createWriteStream(nwDir); | ||
|
||
get(url, (response) => { | ||
|
||
let chunks = 0; | ||
bar.start(Number(response.headers['content-length']), 0); | ||
response.on('data', async (chunk) => { | ||
chunks += chunk.length; | ||
bar.increment(); | ||
bar.update(chunks); | ||
}); | ||
|
||
response.on('error', async () => await rm(nwDir, { force: true })); | ||
|
||
response.on('end', () => { | ||
if (PLATFORM_KV[hostOs] === 'linux') { | ||
decompress('tgz', nwDir); | ||
} else { | ||
decompress('zip', nwDir); | ||
} | ||
}); | ||
response.pipe(stream); | ||
}); | ||
} |
Oops, something went wrong.