├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── lib ├── config.js ├── get-path.js ├── install.js ├── list-remote.js ├── list.js ├── old-version.js ├── os.js ├── remove.js ├── run.js └── use.js ├── nw ├── package.json └── postinstall.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 四月橘林 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nwjs [![version](https://img.shields.io/npm/v/nwjs.svg)](https://www.npmjs.com/package/nwjs) [![npm](https://img.shields.io/npm/dm/nwjs.svg)](https://www.npmjs.com/package/nwjs) 2 | 3 | Inspired by [electron-prebuilt](https://github.com/mafintosh/electron-prebuilt) 4 | 5 | You can use `nwjs` as an nw.js version manager, and do things like `nw /your/app/path` 6 | 7 | ![preview](http://ooo.0o0.ooo/2016/02/01/56af0ee357dab.gif) 8 | 9 | # Install 10 | 11 | ```bash 12 | npm i -g nwjs 13 | ``` 14 | # Usage 15 | 16 | ```bash 17 | # Install a version 18 | $ nw install 0.12.3 19 | 20 | # Install a SDK version 21 | $ nw install 0.13.0-rc3-sdk 22 | 23 | # Run nw in cwd or specific any directory 24 | $ nw . 25 | 26 | # Use another cached version 27 | $ nw use 0.13.0-beta3 28 | 29 | # Use SDK version 30 | $ nw use 0.13.0-rc3-sdk 31 | 32 | # List all local cached versions 33 | $ nw ls 34 | 35 | # Use a proxy 36 | $ http_proxy=http://127.0.0.1:8787 nw install 0.13.0-beta5 37 | 38 | # For fish shell users 39 | $ env http_proxy=http://127.0.0.1:8787 nw install 0.13.0-beta5 40 | ``` 41 | 42 | For all available versions to install please use `nw ls-remote` 43 | 44 | _Tested on Windows 7(32), Windows 10(32), Ubuntu 14.04(32), OSX El Capitan (64)._ 45 | 46 | ## Help 47 | 48 | ```bash 49 | $ nw -h 50 | 51 | Usage: nw [options] [command] 52 | 53 | 54 | Commands: 55 | 56 | * Run nwjs in a directory 57 | install|i Install an nwjs version 58 | use|u Set an active nwjs version 59 | list|ls List local cached nwjs versions 60 | list-remote|ls-remote List all available nwjs versions from remote 61 | remove|r Remove a specific version of nwjs 62 | 63 | Options: 64 | 65 | -h, --help output usage information 66 | -V, --version output the version number 67 | ``` 68 | 69 | ## Programmatic usage 70 | 71 | ```js 72 | const spawn = require('child_process').spawn 73 | // this returns the path to nwjs excutable 74 | const nw = require('nwjs') 75 | 76 | const child = spawn(nw) 77 | ``` 78 | 79 | ## License 80 | 81 | MIT © [EGOIST](https://github.com/egoist) 82 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = require('./lib/get-path')() -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const Config = require('configstore') 7 | const pkg = require('../package') 8 | 9 | module.exports = new Config(pkg.name) 10 | -------------------------------------------------------------------------------- /lib/get-path.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const home = require('user-home') 4 | const platform = require('./os').platform 5 | const config = require('./config') 6 | const oldVesrion = require('./old-version') 7 | 8 | module.exports = function () { 9 | const version = config.get('current') 10 | const isNodeWebkit = oldVesrion(version) 11 | if (version) { 12 | let nw 13 | if (platform === 'osx') { 14 | nw = isNodeWebkit?'node-webkit.app/Contents/MacOS/node-webkit':'nwjs.app/Contents/MacOS/nwjs' 15 | } else if (platform === 'win') { 16 | nw = 'nw.exe' 17 | } else { 18 | nw = 'nw' 19 | } 20 | nw = path.join(home, '.nwjs', version, nw) 21 | 22 | return nw 23 | } 24 | 25 | return null 26 | } -------------------------------------------------------------------------------- /lib/install.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const path = require('path') 7 | const co = require('co') 8 | const os = require('./os') 9 | const pget = require('pget') 10 | const home = require('user-home') 11 | const extract = require('extract-zip') 12 | const pify = require('pify') 13 | const exists = require('path-exists') 14 | const figures = require('figures') 15 | const config = require('./config') 16 | const oldVersion = require('./old-version') 17 | require('shelljs/global') 18 | 19 | module.exports = co.wrap(function* (version) { 20 | try { 21 | // Create cache dir 22 | const cacheDir = path.join(home, '.nwjs') 23 | mkdir('-p', cacheDir) 24 | // check if has cached nwjs in this version 25 | if (exists.sync(`${cacheDir}/${version}`)) { 26 | return console.log(`A cached nwjs already located in ${cacheDir}/${version}`.red) 27 | } 28 | // Download the nwjs 29 | const realVersion = version.split('-sdk').shift() 30 | const isNodeWebkit = oldVersion(version) 31 | const prefix = isNodeWebkit ? 'node-webkit' : 'nwjs' 32 | const fileName = version == realVersion ? `${prefix}-v${realVersion}-${os.platform}-${os.arch}` : `${prefix}-sdk-v${realVersion}-${os.platform}-${os.arch}` 33 | const ext = os.platform === 'linux' ? 'tar.gz' : 'zip' 34 | const url = `http://dl.nwjs.io/v${realVersion}/${fileName}.${ext}` 35 | yield pget(url, {dir: cacheDir, target: `${version}.${ext}`, verbose: true, proxy: process.env.HTTP_PROXY}) 36 | // extract both zip and tarball 37 | const from = `${cacheDir}/${version}.${ext}` 38 | if (os.platform === 'linux') { 39 | exec(`tar -xzvf ${from} -C ${cacheDir}`, {silent: true}) 40 | } else { 41 | yield pify(extract)(from, {dir: cacheDir}) 42 | } 43 | mv(`${cacheDir}/${fileName}`, `${cacheDir}/${version}`) 44 | // remove zip 45 | rm(from) 46 | // update the current using version 47 | config.set('current', version) 48 | // print success info 49 | console.log(`${figures.tick} Version ${version} is installed and activated`.green) 50 | } catch (e) { 51 | console.log(`Failed to install ${figures.cross} Version ${version}`.red) 52 | console.log(e.stack) 53 | } 54 | }) 55 | -------------------------------------------------------------------------------- /lib/list-remote.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const co = require('co') 7 | const getVersions = require('nwjs-versions') 8 | const Spin = require('io-spin') 9 | const config = require('./config') 10 | 11 | const spin = new Spin() 12 | 13 | module.exports = co.wrap(function* () { 14 | try { 15 | spin.start() 16 | const current = config.get('current') 17 | let versions = yield getVersions() 18 | versions = versions 19 | .map(v => v === current ? `* ${v}`.green : ` ${v}`) 20 | .join('\n') 21 | spin.stop() 22 | console.log(versions) 23 | } catch (e) { 24 | spin.stop() 25 | console.log(e.stack) 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /lib/list.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const fs = require('fs') 7 | const pify = require('pify') 8 | const co = require('co') 9 | const home = require('user-home') 10 | const isSemver = require('is-semver') 11 | const config = require('./config') 12 | 13 | module.exports = co.wrap(function* () { 14 | try { 15 | const current = config.get('current') 16 | let versions = yield pify(fs).readdir(`${home}/.nwjs`) 17 | versions = versions 18 | .filter(v => isSemver(v)) 19 | .map(v => v === current ? `* ${v}`.green : ` ${v}`) 20 | .join('\n') 21 | console.log(versions) 22 | } catch (e) { 23 | console.log(e.stack) 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /lib/old-version.js: -------------------------------------------------------------------------------- 1 | module.exports = function(version){ 2 | return version.split('.')[1] < 12 3 | } -------------------------------------------------------------------------------- /lib/os.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const os = require('os') 7 | 8 | let arch = os.arch() 9 | let platform = os.platform() 10 | 11 | // there are no official arm64 builds so 12 | // use x64 ones on Apple Silicon macs 13 | if (arch === 'arm64' && platform === 'darwin') { 14 | arch = 'x64' 15 | } 16 | 17 | if (platform === 'darwin') { 18 | platform = 'osx' 19 | } else if (platform === 'win32') { 20 | platform = 'win' 21 | } 22 | 23 | module.exports = {arch, platform} 24 | -------------------------------------------------------------------------------- /lib/remove.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const home = require('user-home') 7 | const config = require('./config') 8 | require('shelljs/global') 9 | 10 | module.exports = function (version) { 11 | try { 12 | const current = config.get('current') 13 | 14 | if (current === version) { 15 | config.set('current', null) 16 | } 17 | 18 | const dir = `${home}/.nwjs/${version}` 19 | rm('-r', dir) 20 | } catch (e) { 21 | console.log(e.stack) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/run.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const path = require('path') 7 | const home = require('user-home') 8 | const exists = require('path-exists') 9 | const spawn = require('child_process').spawn 10 | const config = require('./config') 11 | const getPath = require('./get-path') 12 | 13 | module.exports = function (dir, opts) { 14 | try { 15 | const version = config.get('current') 16 | const nw = getPath() 17 | 18 | if (!exists.sync(nw)) { 19 | return console.log(`Cached nwjs excutable v${version} not found, run ${`nw install ${version}`.cyan} first`) 20 | } 21 | 22 | const cliArgs = opts.parent.rawArgs.slice(3) 23 | 24 | console.log(`Using nw.js v${version}`) 25 | 26 | const run = spawn(nw, [dir].concat(cliArgs)) 27 | run.stdout.on('data', data => console.log(data.toString())) 28 | run.stderr.on('data', data => console.log(data.toString())) 29 | run.on('close', code => { 30 | process.exitCode = code 31 | console.log('===================='.green) 32 | console.log('bye!'.green) 33 | }) 34 | } catch (e) { 35 | console.log(e.stack) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/use.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | const path = require('path') 7 | const home = require('user-home') 8 | const exists = require('path-exists') 9 | const config = require('./config') 10 | 11 | module.exports = function (version) { 12 | config.set('current', version) 13 | const cached = path.join(home, '.nwjs', version) 14 | if (!exists.sync(cached)) { 15 | return console.log(`Run ${`nw install ${version}`.red} first`) 16 | } 17 | console.log(`You're using v${version} now!`.green) 18 | } 19 | -------------------------------------------------------------------------------- /nw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict' 3 | 4 | /** 5 | * Module dependencies 6 | */ 7 | const cli = require('commander') 8 | const update = require('update-notifier') 9 | const pkg = require('./package') 10 | require('colorful').toxic() 11 | 12 | /** 13 | * Commands 14 | */ 15 | const install = require('./lib/install') 16 | const run = require('./lib/run') 17 | const use = require('./lib/use') 18 | const list = require('./lib/list') 19 | const listRemote = require('./lib/list-remote') 20 | const remove = require('./lib/remove') 21 | 22 | /** 23 | * Update notify 24 | */ 25 | update({pkg}).notify() 26 | 27 | cli.version(pkg.version) 28 | 29 | cli 30 | .command('*') 31 | .description('Run nwjs in a directory') 32 | .action(run) 33 | 34 | cli 35 | .command('install ') 36 | .description('Install an nwjs version') 37 | .alias('i') 38 | .action(install) 39 | 40 | cli 41 | .command('use ') 42 | .description('Set an active nwjs version') 43 | .alias('u') 44 | .action(use) 45 | 46 | cli 47 | .command('list') 48 | .description('List local cached nwjs versions') 49 | .alias('ls') 50 | .action(list) 51 | 52 | cli 53 | .command('list-remote') 54 | .description('List all available nwjs versions from remote') 55 | .alias('ls-remote') 56 | .action(listRemote) 57 | 58 | cli 59 | .command('remove ') 60 | .description('Remove a specific version of nwjs') 61 | .alias('r') 62 | .action(remove) 63 | 64 | const inst = cli.parse(process.argv) 65 | 66 | if(!inst.args.length) { 67 | cli.outputHelp() 68 | } 69 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nwjs", 3 | "version": "1.4.4", 4 | "description": "Install nw.js prebuilts using npm", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"lol\"", 8 | "postinstall": "node postinstall.js" 9 | }, 10 | "preferGlobal": true, 11 | "bin": { 12 | "nw": "nw" 13 | }, 14 | "files": [ 15 | "nw", 16 | "index.js", 17 | "postinstall.js", 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/egoist/nwjs.git" 23 | }, 24 | "author": "EGOIST <0x142857@gmail.com>", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/egoist/nwjs/issues" 28 | }, 29 | "homepage": "https://github.com/egoist/nwjs#readme", 30 | "dependencies": { 31 | "co": "^4.6.0", 32 | "colorful": "^2.1.0", 33 | "commander": "^2.9.0", 34 | "configstore": "^1.4.0", 35 | "extract-zip": "^1.4.1", 36 | "figures": "^1.4.0", 37 | "io-spin": "^0.3.0", 38 | "is-semver": "^1.0.0", 39 | "nwjs-versions": "0.0.3", 40 | "path-exists": "^1.0.0", 41 | "pget": "0.0.0", 42 | "pify": "^2.3.0", 43 | "shelljs": "^0.7.5", 44 | "update-notifier": "^0.6.0", 45 | "user-home": "^2.0.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /postinstall.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const home = require('user-home') 3 | require('shelljs/global') 4 | 5 | const cacheDir = path.join(home, '.nwjs') 6 | mkdir('-p', cacheDir) 7 | --------------------------------------------------------------------------------