electron-updater
Advanced tools
Comparing version 0.0.1 to 0.0.2
136
lib/check.js
var download = require('./download.js'), | ||
semver = require('semver'), | ||
async = require('async'), | ||
path = require('path'), | ||
file = require('./file.js'), | ||
fs = require('fs'), | ||
directory = require('./directory.js'), | ||
AppDirectory = require('appdirectory') | ||
semver = require('semver'), | ||
async = require('async'), | ||
path = require('path'), | ||
file = require('./file.js'), | ||
fs = require('fs'), | ||
directory = require('./directory.js'), | ||
AppDirectory = require('appdirectory') | ||
function satisfy(registry, name, desired, current, exists, callback) { | ||
var url = registry + '/' + name + '/' + desired | ||
download.getJson(url, function (err, data) { | ||
if(err) return callback(err) | ||
var available = semver.clean(data.version) | ||
if(!exists || semver.gt(available, current)) { | ||
return callback(null, { | ||
name: name, | ||
desired: desired, | ||
current: current, | ||
available: available | ||
}) | ||
} | ||
var url = registry + '/' + name + '/' + desired | ||
download.getJson(url, function (err, data) { | ||
if(err) return callback(err) | ||
var available = semver.clean(data.version) | ||
if(!exists || semver.gt(available, current)) { | ||
return callback(null, { | ||
name: name, | ||
desired: desired, | ||
current: current, | ||
available: available | ||
}) | ||
} | ||
// We already have the most up-to-date version | ||
callback() | ||
}) | ||
// We already have the most up-to-date version | ||
callback() | ||
}) | ||
} | ||
function checkApp(context, callback) { | ||
var registry = context.registry | ||
var name = context.name | ||
var desired = context.channel | ||
var current = context.version | ||
satisfy(registry, name, desired, current, true, callback) | ||
var registry = context.registry | ||
var name = context.name | ||
var desired = context.channel | ||
var current = context.version | ||
satisfy(registry, name, desired, current, true, callback) | ||
} | ||
function checkDependency(name, callback) { | ||
var appName = this.name | ||
var registry = this.registry | ||
var desired = this.dependencies[name] | ||
var packagePath = path.join(this.appDir, 'node_modules', name, 'package.json') | ||
file.readJson(packagePath, function (err, pkg) { | ||
var exists = !err | ||
var current = (pkg && pkg.version) || '0.0.0' | ||
satisfy(registry, name, desired, current, exists, callback) | ||
}) | ||
var appName = this.name | ||
var registry = this.registry | ||
var desired = this.dependencies[name] | ||
var packagePath = path.join(this.appDir, 'node_modules', name, 'package.json') | ||
file.readJson(packagePath, function (err, pkg) { | ||
var exists = !err | ||
var current = (pkg && pkg.version) || '0.0.0' | ||
satisfy(registry, name, desired, current, exists, callback) | ||
}) | ||
} | ||
function checkPlugin(name, callback) { | ||
var appName = this.name | ||
var appVersion = this.version | ||
var registry = this.registry | ||
var desired = this.plugins[name] | ||
var dirs = new AppDirectory(appName) | ||
var appData = path.dirname(dirs.userData()) | ||
var currentPluginsPath = path.join(appData, '.current') | ||
file.readJson(currentPluginsPath, function (err, data) { | ||
var current = (data && data[name]) || '0.0.0' | ||
var pluginPackagePath = path.join(appData, 'plugins', name, current, 'package.json') | ||
fs.stat(pluginPackagePath, function (err, stat) { | ||
var exists = !err | ||
satisfy(registry, name, desired, current, exists, callback) | ||
}) | ||
}) | ||
var appName = this.name | ||
var appVersion = this.version | ||
var registry = this.registry | ||
var desired = this.plugins[name] | ||
var dirs = new AppDirectory(appName) | ||
var appData = path.dirname(dirs.userData()) | ||
var currentPluginsPath = path.join(appData, '.current') | ||
file.readJson(currentPluginsPath, function (err, data) { | ||
var current = (data && data[name]) || '0.0.0' | ||
var pluginPackagePath = path.join(appData, 'plugins', name, current, 'package.json') | ||
var pluginPackageLinkPath = path.join(appData, 'plugins', name, 'link', 'package.json') | ||
fs.stat(pluginPackageLinkPath, function (linkErr, stat) { | ||
fs.stat(pluginPackagePath, function (err, stat) { | ||
if (!linkErr) return callback(false) | ||
var exists = !err | ||
satisfy(registry, name, desired, current, exists, callback) | ||
}) | ||
}) | ||
}) | ||
} | ||
function check(item, callback) { | ||
switch(item.kind) { | ||
case 'app': | ||
checkApp(item.context, callback) | ||
break; | ||
case 'dependencies': | ||
async.map(Object.getOwnPropertyNames(item.context.dependencies), checkDependency.bind(item.context), callback) | ||
break; | ||
case 'plugins': | ||
async.map(Object.getOwnPropertyNames(item.context.plugins), checkPlugin.bind(item.context), callback) | ||
break; | ||
default: | ||
return callback(new Error('invalid dependency kind detected')) | ||
} | ||
switch(item.kind) { | ||
case 'app': | ||
checkApp(item.context, callback) | ||
break; | ||
case 'dependencies': | ||
async.map(Object.getOwnPropertyNames(item.context.dependencies), checkDependency.bind(item.context), callback) | ||
break; | ||
case 'plugins': | ||
async.map(Object.getOwnPropertyNames(item.context.plugins), checkPlugin.bind(item.context), callback) | ||
break; | ||
default: | ||
return callback(new Error('invalid dependency kind detected')) | ||
} | ||
} | ||
module.exports = { | ||
check: check | ||
check: check | ||
} |
@@ -10,2 +10,3 @@ var util = require('util'), | ||
copier = require('./copier.js'), | ||
file = require('./file.js'), | ||
AppDirectory = require('appdirectory'), | ||
@@ -18,7 +19,11 @@ EventEmitter = require('events').EventEmitter, | ||
function update(appDir, callback) { | ||
function update(appDir, callback) { | ||
if(typeof appDir === 'function') { | ||
callback = appDir | ||
appDir = path.dirname(process.mainModule.filename) | ||
} | ||
check(appDir, function (err, results) { | ||
if(err) return callback(err) | ||
if(!results) return callback() | ||
updater.update(results, callback); | ||
updater.update(results, callback) | ||
}) | ||
@@ -104,3 +109,3 @@ } | ||
copier.copy(process.execPath, appName, function (err, tmpExecPath) { | ||
// todo: log error | ||
if(err) return callback(err) | ||
var updateDir = path.resolve(path.join(__dirname, '..')) | ||
@@ -123,22 +128,22 @@ var appDir = path.dirname(process.mainModule.filename) | ||
function start(appDir) { | ||
function start(appDir, callback) { | ||
var that = this | ||
if(typeof appDir === 'function') { | ||
callback = appDir | ||
appDir = null | ||
} | ||
appDir = appDir || path.dirname(process.mainModule.filename) | ||
context.load(appDir, function (err, ctx) { | ||
// todo: handle error | ||
if(err) return callback(err) | ||
if(ctx.pendingUpdate) { | ||
// If there is a pending update, do a full update instead of starting the app. | ||
// This is set when a dependency update is available. | ||
console.log('pending update.') | ||
fullUpdate(ctx.name, function (err) { | ||
if(err) return callback(err) | ||
that.emit('updateRequired') | ||
callback() | ||
}) | ||
} else { | ||
isValid(appDir, function (err, valid) { | ||
if(err) { | ||
console.log('Error starting electron-updater') | ||
console.log(err) | ||
return; | ||
} | ||
if(err) return callback(err) | ||
if(valid) { | ||
@@ -151,4 +156,4 @@ // If the app is valid, then go ahead and startup what we have. | ||
check(appDir, function (err, result) { | ||
//todo: handle error | ||
if(result && (result.app || result.dependencies)) { | ||
if(err) return callback(err) | ||
if(result && (result.app || result.dependencies.length)) { | ||
// If a new version of the app is available or | ||
@@ -161,18 +166,23 @@ // a dependency update is available, we must | ||
file.touch(pendingUpdatePath, function (err) { | ||
if(err) return callback(err) | ||
that.emit('updateAvailable') | ||
callback() | ||
}) | ||
} else if (result && result.plugins) { | ||
} else if (result && result.plugins.length) { | ||
// If only plugin updates are available we can go ahead and update those | ||
// right now and then notify the user that they can restart to apply them. | ||
updater.update(results, function (err) { | ||
// todo: log errors | ||
this.emit('updateAvailable') | ||
updater.update(result, function (err) { | ||
if(err) return callback(err) | ||
that.emit('updateAvailable') | ||
callback() | ||
}) | ||
} else { | ||
callback() | ||
} | ||
}) | ||
} else { | ||
console.log('mandatory update.') | ||
fullUpdate(ctx.name, function (err) { | ||
if(err) return console.log(err) | ||
if(err) return callback(err) | ||
that.emit('updateRequired') | ||
callback() | ||
}) | ||
@@ -179,0 +189,0 @@ } |
var directory = require('./directory.js'), | ||
path = require('path'), | ||
fs = require('fs'), | ||
async = require('async'), | ||
file = require('./file.js'), | ||
AppDirectory = require('appdirectory') | ||
path = require('path'), | ||
fs = require('fs'), | ||
async = require('async'), | ||
file = require('./file.js'), | ||
AppDirectory = require('appdirectory') | ||
function isDevDirectory(appDir, callback) { | ||
var gitDir = path.join(appDir, '.git') | ||
var svnDir = path.join(appDir, '.svn') | ||
fs.readdir(gitDir, function (err) { | ||
if(!err) return callback(true) | ||
fs.readdir(svnDir, function (err) { | ||
if(!err) return callback(true) | ||
callback(false) | ||
}) | ||
}) | ||
var gitDir = path.join(appDir, '.git') | ||
var svnDir = path.join(appDir, '.svn') | ||
fs.readdir(gitDir, function (err) { | ||
if(!err) return callback(true) | ||
fs.readdir(svnDir, function (err) { | ||
if(!err) return callback(true) | ||
callback(false) | ||
}) | ||
}) | ||
} | ||
function load(appDir, callback) { | ||
if(!appDir || !callback) throw new Error('Failed to load app context: invalid argument') | ||
isDevDirectory(appDir, function (dev) { | ||
var packagePath = path.join(appDir, 'package.json') | ||
file.readJson(packagePath, function (err, package) { | ||
if (err) return callback(err) | ||
var name = package.name | ||
var version = package.version | ||
var dirs = new AppDirectory(name) | ||
var appData = path.dirname(dirs.userData()) | ||
var pendingUpdatePath = path.join(appData, '.update') | ||
var channelPath = path.join(appData, '.channel') | ||
fs.readFile(channelPath, function (err, channel) { | ||
channel = channel || 'latest' | ||
fs.stat(pendingUpdatePath, function (err, stat) { | ||
var pendingUpdate = !err && stat.isFile() | ||
callback(null, { | ||
name: name, | ||
version: version, | ||
channel: channel, | ||
dev: dev, | ||
pendingUpdate: pendingUpdate, | ||
registry: "https://registry.npmjs.org", // resolve from .npmrc's | ||
appDir: appDir, | ||
dependencies: package.dependencies || {}, | ||
plugins: package.plugins || {} | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
if(!appDir || !callback) throw new Error('Failed to load app context: invalid argument') | ||
isDevDirectory(appDir, function (dev) { | ||
var packagePath = path.join(appDir, 'package.json') | ||
file.readJson(packagePath, function (err, package) { | ||
if (err) return callback(err) | ||
var name = package.name | ||
var version = package.version | ||
var dirs = new AppDirectory(name) | ||
var appData = path.dirname(dirs.userData()) | ||
var pendingUpdatePath = path.join(appData, '.update') | ||
var channelPath = path.join(appData, '.channel') | ||
fs.readFile(channelPath, function (err, channel) { | ||
channel = channel || 'latest' | ||
fs.stat(pendingUpdatePath, function (err, stat) { | ||
var pendingUpdate = !err && stat.isFile() | ||
callback(null, { | ||
name: name, | ||
version: version, | ||
channel: channel, | ||
dev: dev, | ||
pendingUpdate: pendingUpdate, | ||
registry: "https://registry.npmjs.org", // resolve from .npmrc's | ||
appDir: appDir, | ||
dependencies: package.dependencies || {}, | ||
plugins: package.plugins || {} | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
} | ||
module.exports = { | ||
load: load | ||
load: load | ||
} |
var directory = require('./directory.js'), | ||
file = require('./file.js'), | ||
fs = process.versions.electron ? require('original-fs') : require('fs'), | ||
path = require('path'), | ||
util = require('util'), | ||
AppDirectory = require('appdirectory') | ||
file = require('./file.js'), | ||
fs = process.versions.electron ? require('original-fs') : require('fs'), | ||
path = require('path'), | ||
util = require('util'), | ||
AppDirectory = require('appdirectory') | ||
var whitelist = [ | ||
'resources', | ||
'default_app', | ||
'locales' | ||
'resources', | ||
'default_app', | ||
'locales' | ||
] | ||
function copyFile(sourceDir, destDir, name, callback) { | ||
var sourceFile = path.join(sourceDir, name) | ||
var destFile = path.join(destDir, name) | ||
fs.stat(sourceFile, function (err, sourceStat) { | ||
if(err) return callback(err); | ||
fs.stat(destFile, function (err, destStat) { | ||
if(sourceStat.isFile() && (err || !destStat || (sourceStat.mtime > destStat.mtime))) { | ||
file.copy(sourceFile, destFile, callback) | ||
} else if(sourceStat.isDirectory() && whitelist.indexOf(path.basename(sourceFile)) >= 0) { | ||
copyDir(sourceFile, destFile, callback) | ||
} else { | ||
callback() | ||
} | ||
}) | ||
}) | ||
var sourceFile = path.join(sourceDir, name) | ||
var destFile = path.join(destDir, name) | ||
fs.stat(sourceFile, function (err, sourceStat) { | ||
if(err) return callback(err); | ||
fs.stat(destFile, function (err, destStat) { | ||
if(sourceStat.isFile() && (err || !destStat || (sourceStat.mtime > destStat.mtime))) { | ||
file.copy(sourceFile, destFile, callback) | ||
} else if(sourceStat.isDirectory() && whitelist.indexOf(path.basename(sourceFile)) >= 0) { | ||
copyDir(sourceFile, destFile, callback) | ||
} else { | ||
callback() | ||
} | ||
}) | ||
}) | ||
} | ||
function copyDir(sourceDir, destDir, callback) { | ||
directory.create(destDir, function () { | ||
fs.readdir(sourceDir, function (err, files) { | ||
if(err) return callback(err); | ||
async.forEach( | ||
files, | ||
function (f, callback) { | ||
copyFile(sourceDir, destDir, f, callback) | ||
}, | ||
callback) | ||
}) | ||
}) | ||
directory.create(destDir, function () { | ||
fs.readdir(sourceDir, function (err, files) { | ||
if(err) return callback(err); | ||
async.forEach( | ||
files, | ||
function (f, callback) { | ||
copyFile(sourceDir, destDir, f, callback) | ||
}, | ||
callback) | ||
}) | ||
}) | ||
} | ||
function copy(execPath, appName, callback) { | ||
var execDir = path.dirname(execPath) | ||
var dirs = new AppDirectory(appName) | ||
var appData = path.dirname(dirs.userData()) | ||
var electronVersion = process.versions.electron | ||
var updateDir = path.join(appData, 'updater', electronVersion) | ||
console.log('copying...') | ||
copyDir(execDir, updateDir, function (err) { | ||
if(err) return callback(err); | ||
callback(null, path.join(updateDir, path.basename(execPath))) | ||
}) | ||
var execDir = path.join(path.dirname(execPath)) | ||
var dirs = new AppDirectory(appName) | ||
var appData = path.dirname(dirs.userData()) | ||
var electronVersion = process.versions.electron | ||
var updateDir = path.join(appData, 'updater', electronVersion) | ||
copyDir(execDir, updateDir, function (err) { | ||
if(err) return callback(err); | ||
callback(null, path.join(updateDir, path.basename(execPath))) | ||
}) | ||
} | ||
module.exports = { | ||
copy: copy | ||
copy: copy | ||
} |
@@ -8,38 +8,35 @@ | ||
function remove(directory, callback) { | ||
fs.lstat(directory, function (err, stat) { | ||
if(err) return callback(err) | ||
if(stat.isDirectory()) { | ||
fs.readdir(directory, function (err, files) { | ||
if(err) return callback(err) | ||
async.map( | ||
files, | ||
function (f, c) { | ||
remove(path.join(directory, f), c) | ||
}, | ||
function (err) { | ||
if(err) return callback(err) | ||
fs.rmdir(directory, callback) | ||
}) | ||
}) | ||
} else { | ||
fs.unlink(directory, callback) | ||
} | ||
}) | ||
fs.lstat(directory, function (err, stat) { | ||
if(err) return callback(err) | ||
if(stat.isDirectory()) { | ||
fs.readdir(directory, function (err, files) { | ||
if(err) return callback(err) | ||
async.map( | ||
files, | ||
function (f, c) { | ||
remove(path.join(directory, f), c) | ||
}, | ||
function (err) { | ||
if(err) return callback(err) | ||
fs.rmdir(directory, callback) | ||
}) | ||
}) | ||
} else { | ||
fs.unlink(directory, callback) | ||
} | ||
}) | ||
} | ||
function create(directory, callback) { | ||
var parent = path.dirname(directory) | ||
if (!parent || parent === directory) return callback() // root, skip | ||
create(parent, function (error) { // create parent dir | ||
if (error) return callback(error) // couldn't create parent, exit | ||
fs.access(directory, function (error) { // see if folder exists | ||
if (!error) return callback() // already exists, skip | ||
fs.mkdir(directory, callback) // create the directory | ||
}) | ||
}) | ||
var parent = path.dirname(directory) | ||
if (!parent || parent === directory) return callback() // root, skip | ||
create(parent, function (error) { // create parent dir | ||
if (error && error.code !== 'EEXIST') return callback(error) // failed unexpectedly, exit | ||
fs.mkdir(directory, callback) // create the directory | ||
}) | ||
} | ||
module.exports = { | ||
remove: remove, | ||
create: create | ||
create: create, | ||
remove: remove | ||
} |
@@ -17,3 +17,3 @@ var util = require('util') | ||
redirects++; | ||
_get(res.headers.location); | ||
_get(res.headers.location) | ||
} | ||
@@ -23,19 +23,7 @@ } else if(res.statusCode === 200) { | ||
} else { | ||
function errorHandler(err, data) { | ||
callback(new Error(util.inspect({ | ||
code: res.statusCode, | ||
data: data, | ||
url: url, | ||
headers: res.headers | ||
}))) | ||
} | ||
var message = '' | ||
res.setEncoding('utf8') | ||
res.on('data', function (data) { | ||
message += data | ||
}) | ||
res.on('end', function () { | ||
return errorHandler(null, message) | ||
}) | ||
res.on('error', errorHandler) | ||
var e = new Error('Download failed.') | ||
e.code = res.statusCode | ||
e.url = url | ||
e.headers = res.headers | ||
callback(e, res) | ||
} | ||
@@ -46,3 +34,3 @@ }) | ||
_get(url); | ||
_get(url) | ||
} | ||
@@ -52,3 +40,2 @@ | ||
get(url, function (err, res) { | ||
if(err) return callback(err) | ||
var json = '' | ||
@@ -61,3 +48,8 @@ res.setEncoding('utf8') | ||
var obj = JSON.parse(json) | ||
return callback(null, obj) | ||
if (err) { | ||
err.data = obj | ||
return callback(err) | ||
} else { | ||
return callback(null, obj) | ||
} | ||
}) | ||
@@ -64,0 +56,0 @@ res.on('error', callback) |
@@ -8,4 +8,8 @@ var fs = process.versions.electron ? require('original-fs') : require('fs'), | ||
if(err) return callback(err) | ||
var j = JSON.parse(data) | ||
callback(null, j) | ||
try { | ||
var j = JSON.parse(data) | ||
callback(null, j) | ||
} catch (e) { | ||
callback(e) | ||
} | ||
}) | ||
@@ -12,0 +16,0 @@ } |
@@ -9,3 +9,2 @@ var path = require('path'), | ||
function extract(dir, res, callback) { | ||
console.log('creating dir: ' + dir) | ||
directory.create(dir, function (err) { | ||
@@ -19,14 +18,13 @@ if(err) return callback(err) | ||
}) | ||
var name = header.name.split('/'); | ||
var name = header.name.split('/') | ||
if (name[0] === 'package') | ||
name.shift(); | ||
var joinedName = path.join.apply(path, name); | ||
var outPath = path.join(dir, joinedName); | ||
name.shift() | ||
var joinedName = path.join.apply(path, name) | ||
var outPath = path.join(dir, joinedName) | ||
if(header.type === 'file') { | ||
console.log('Extracting: ' + joinedName); | ||
var outdir = path.dirname(outPath); | ||
var outdir = path.dirname(outPath) | ||
directory.create(outdir, function (err) { | ||
if(err) return callback(err) | ||
var outFile = fs.createWriteStream(outPath); | ||
stream.pipe(outFile); | ||
var outFile = fs.createWriteStream(outPath) | ||
stream.pipe(outFile) | ||
}); | ||
@@ -36,13 +34,13 @@ } else if(header.type === 'directory') { | ||
if(err) return callback(err) | ||
stream.resume(); | ||
}); | ||
stream.resume() | ||
}) | ||
} else { | ||
console.log(' unexpected kind of file: ' + header.type); | ||
// else unsupported type | ||
stream.resume() | ||
} | ||
}); | ||
}) | ||
e.on('finish', function () { | ||
console.log('Extraction complete.') | ||
callback(); | ||
callback() | ||
}); | ||
res.pipe(z).pipe(e); | ||
res.pipe(z).pipe(e) | ||
}) | ||
@@ -49,0 +47,0 @@ } |
@@ -31,3 +31,2 @@ var util = require('util'), | ||
function updatePlugin(name, version, context, callback) { | ||
console.log('updating plugin: ' + name) | ||
var dirs = new AppDirectory(context.name) | ||
@@ -37,2 +36,4 @@ var appData = path.dirname(dirs.userData()) | ||
var dir = path.join(pluginsDir, name, version) | ||
var dir = path.join(pluginsDir, name, version) | ||
var url = context.registry + '/' + name + '/' + version | ||
@@ -82,14 +83,29 @@ download.getJson(url, function (err, data) { | ||
function updateApp(dir, name, version, context, callback) { | ||
var url = context.registry + '/' + name + '/' + version | ||
download.getJson(url, function (err, data) { | ||
if(err) return callback(err) | ||
var payloadUrl = data.dist.tarball | ||
download.get(payloadUrl, function (err, res) { | ||
if(err) return callback(err) | ||
unpacker.extract(dir, res, callback) | ||
}) | ||
}) | ||
} | ||
function updateEach(dep, callback) { | ||
var context = this | ||
switch(dep.kind) { | ||
case 'app': | ||
updateApp(context.appDir, dep.name, dep.version, context, callback) | ||
break | ||
case 'dependency': | ||
updateDependency(context.appDir, dep.name, dep.version, context, callback) | ||
break; | ||
break | ||
case 'plugin': | ||
updatePlugin(dep.name, dep.version, context, callback) | ||
break; | ||
break | ||
default: | ||
callback(new Error('Updating unexpected kind.')) | ||
break; | ||
break | ||
} | ||
@@ -99,5 +115,2 @@ } | ||
function update(deps, callback) { | ||
// todo: update primary package itself | ||
// todo: get prebuilt binaries for packages | ||
// todo: update dependencies/plugins recursively | ||
var updateContexts = [] | ||
@@ -104,0 +117,0 @@ if(deps.app && !deps.context.dev) { |
{ | ||
"name": "electron-updater", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Cross platform auto-updater for electron applications", | ||
@@ -37,6 +37,10 @@ "main": "index.js", | ||
"devDependencies": { | ||
"chai": "^2.3.0", | ||
"colors": "^1.1.0", | ||
"commander": "^2.8.1", | ||
"shelljs": "^0.4.0" | ||
"mocha": "^2.2.4", | ||
"proxyquire": "^1.4.0", | ||
"shelljs": "^0.4.0", | ||
"sinon": "^1.14.1" | ||
} | ||
} |
@@ -1,6 +0,12 @@ | ||
# electron-updater | ||
# electron-updater | ||
Cross platform auto-updater for electron apps | ||
> Work in progress... | ||
[![Build Status](https://travis-ci.org/EvolveLabs/electron-updater.svg?branch=master)](https://travis-ci.org/EvolveLabs/electron-updater) | ||
# Install | ||
There are two separate packages that make up the `electron-updater`. The updater itself runs in your app's main process while the plugins project loads the plugins downloaded by the updater into the render process. If you don't use plugins, then you don't need the second project. | ||
$ npm install electron-updater --save | ||
$ npm install electron-plugins --save | ||
## Features | ||
@@ -13,2 +19,84 @@ * Update notifications | ||
* Leverages npm for distribution | ||
* Fully based on javascript and node | ||
* Fully based on javascript and node | ||
* Designed for [`electron`](https://github.com/atom/electron) | ||
## Example main.js | ||
```JavaScript | ||
var app = require('app'), | ||
ipc = require('ipc'), | ||
util = require('util'), | ||
BrowserWindow = require('browser-window'), | ||
updater = require('electron-updater') | ||
require('crash-reporter').start() | ||
var mainWindow = null | ||
app.on('window-all-closed', function() { | ||
if (process.platform != 'darwin') | ||
app.quit() | ||
}) | ||
app.on('ready', function() { | ||
// Instead of launching your window right away, start the updater | ||
// to check to see if the app is valid or not. | ||
// An app is invalid if any of its dependencies or plugins are missing. | ||
// In this case the updater will begin a 'full' update. Once updated | ||
// your app will be re-launched. | ||
updater.on('ready', function () { | ||
// This event is called if your app is currently valid. | ||
// It may be out-of-date but it has all of the necessary | ||
// dependencies and plugins to launch right now. | ||
// Your app maybe also receive an update-available event following this | ||
mainWindow = new BrowserWindow({width: 800, height: 600}) | ||
mainWindow.loadUrl('file://' + __dirname + '/index.html') | ||
mainWindow.openDevTools({detach:true}) | ||
mainWindow.on('closed', function() { | ||
mainWindow = null; | ||
}); | ||
}) | ||
updater.on('updateRequired', function () { | ||
// This event is fired if your app is not currently valid at startup. | ||
// The app must be exited immediately and the auto-updater will be run instead. | ||
// After the auto-update runs the app will be re-run. | ||
app.quit(); | ||
}) | ||
updater.on('updateAvailable', function () { | ||
// This event is fired after new versions of plugins have been downloaded and | ||
// before the app and dependencies are downloaded. Plugins are installed side-by-side | ||
// so they can be downloaded while the app is running. | ||
// After the app is restarted it will watch for updates and fire the updated required | ||
// event when newer versions are available. | ||
if(mainWindow) { | ||
// Send a message to your view(s) | ||
mainWindow.webContents.send('update-available'); | ||
} | ||
}) | ||
updater.start() | ||
}) | ||
``` | ||
## Example index.js (running in render process) | ||
```JavaScript | ||
var plugins = require('electron-plugins'), | ||
util = require('util'), | ||
ipc = require('ipc') | ||
document.addEventListener('DOMContentLoaded', function () { | ||
var context = { document: document } | ||
plugins.load(context, function (err, loaded) { | ||
if(err) return console.error(err) | ||
console.log('Plugins loaded successfully.') | ||
}) | ||
}) | ||
ipc.on('update-available', function () { | ||
console.log('there is an update available for download') | ||
}) | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
92996
30
2504
102
7
5