| 
									
										
										
										
											2014-12-26 18:54:20 -05:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | const winston = require('winston'); | 
					
						
							|  |  |  | const path = require('path'); | 
					
						
							|  |  |  | const fs = require('fs'); | 
					
						
							|  |  |  | const nconf = require('nconf'); | 
					
						
							|  |  |  | const os = require('os'); | 
					
						
							|  |  |  | const cproc = require('child_process'); | 
					
						
							|  |  |  | const util = require('util'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const db = require('../database'); | 
					
						
							|  |  |  | const meta = require('../meta'); | 
					
						
							|  |  |  | const pubsub = require('../pubsub'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const statAsync = util.promisify(fs.stat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const packageManager = nconf.get('package_manager') === 'yarn' ? 'yarn' : 'npm'; | 
					
						
							|  |  |  | let packageManagerExecutable = packageManager; | 
					
						
							|  |  |  | const packageManagerCommands = { | 
					
						
							| 
									
										
										
										
											2017-12-20 13:56:14 -07:00
										 |  |  | 	yarn: { | 
					
						
							|  |  |  | 		install: 'add', | 
					
						
							|  |  |  | 		uninstall: 'remove', | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	npm: { | 
					
						
							|  |  |  | 		install: 'install', | 
					
						
							|  |  |  | 		uninstall: 'uninstall', | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (process.platform === 'win32') { | 
					
						
							|  |  |  | 	packageManagerExecutable += '.cmd'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | module.exports = function (Plugins) { | 
					
						
							| 
									
										
										
										
											2014-12-26 20:18:05 -05:00
										 |  |  | 	if (nconf.get('isPrimary') === 'true') { | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		pubsub.on('plugins:toggleInstall', function (data) { | 
					
						
							| 
									
										
										
										
											2014-12-26 20:18:05 -05:00
										 |  |  | 			if (data.hostname !== os.hostname()) { | 
					
						
							|  |  |  | 				toggleInstall(data.id, data.version); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		pubsub.on('plugins:upgrade', function (data) { | 
					
						
							| 
									
										
										
										
											2014-12-26 20:18:05 -05:00
										 |  |  | 			if (data.hostname !== os.hostname()) { | 
					
						
							|  |  |  | 				upgrade(data.id, data.version); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 	Plugins.toggleActive = async function (id) { | 
					
						
							|  |  |  | 		const isActive = await Plugins.isActive(id); | 
					
						
							|  |  |  | 		if (isActive) { | 
					
						
							|  |  |  | 			await db.sortedSetRemove('plugins:active', id); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			const count = await db.sortedSetCard('plugins:active'); | 
					
						
							|  |  |  | 			await db.sortedSetAdd('plugins:active', count, id); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		meta.reloadRequired = true; | 
					
						
							|  |  |  | 		Plugins.fireHook(isActive ? 'action:plugin.deactivate' : 'action:plugin.activate', { id: id }); | 
					
						
							|  |  |  | 		return { id: id, active: !isActive }; | 
					
						
							| 
									
										
										
										
											2014-12-26 18:54:20 -05:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 	Plugins.toggleInstall = async function (id, version) { | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 		pubsub.publish('plugins:toggleInstall', { hostname: os.hostname(), id: id, version: version }); | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 		return await toggleInstall(id, version); | 
					
						
							| 
									
										
										
										
											2014-12-26 20:18:05 -05:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 	const runPackageManagerCommandAsync = util.promisify(runPackageManagerCommand); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	async function toggleInstall(id, version) { | 
					
						
							|  |  |  | 		const [installed, active] = await Promise.all([ | 
					
						
							|  |  |  | 			Plugins.isInstalled(id), | 
					
						
							|  |  |  | 			Plugins.isActive(id), | 
					
						
							|  |  |  | 		]); | 
					
						
							|  |  |  | 		const type = installed ? 'uninstall' : 'install'; | 
					
						
							|  |  |  | 		if (active) { | 
					
						
							|  |  |  | 			await Plugins.toggleActive(id); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		await runPackageManagerCommandAsync(type, id, version || 'latest'); | 
					
						
							|  |  |  | 		const pluginData = await Plugins.get(id); | 
					
						
							|  |  |  | 		Plugins.fireHook('action:plugin.' + type, { id: id, version: version }); | 
					
						
							|  |  |  | 		return pluginData; | 
					
						
							| 
									
										
										
										
											2014-12-26 20:18:05 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-26 18:54:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 13:56:14 -07:00
										 |  |  | 	function runPackageManagerCommand(command, pkgName, version, callback) { | 
					
						
							|  |  |  | 		cproc.execFile(packageManagerExecutable, [ | 
					
						
							|  |  |  | 			packageManagerCommands[packageManager][command], | 
					
						
							|  |  |  | 			pkgName + (command === 'install' ? '@' + version : ''), | 
					
						
							|  |  |  | 			'--save', | 
					
						
							|  |  |  | 		], function (err, stdout) { | 
					
						
							| 
									
										
										
										
											2016-01-12 13:53:26 +02:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-12-14 09:28:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			winston.verbose('[plugins/' + command + '] ' + stdout); | 
					
						
							| 
									
										
										
										
											2016-11-18 14:03:06 +03:00
										 |  |  | 			callback(); | 
					
						
							| 
									
										
										
										
											2016-12-15 16:08:32 +03:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2016-01-12 13:53:26 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Plugins.upgrade = async function (id, version) { | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 		pubsub.publish('plugins:upgrade', { hostname: os.hostname(), id: id, version: version }); | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 		return await upgrade(id, version); | 
					
						
							| 
									
										
										
										
											2014-12-26 20:18:05 -05:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 	async function upgrade(id, version) { | 
					
						
							|  |  |  | 		await runPackageManagerCommandAsync('install', id, version || 'latest'); | 
					
						
							|  |  |  | 		const isActive = await Plugins.isActive(id); | 
					
						
							|  |  |  | 		meta.reloadRequired = isActive; | 
					
						
							|  |  |  | 		return isActive; | 
					
						
							| 
									
										
										
										
											2014-12-26 20:18:05 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-26 18:54:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 	Plugins.isInstalled = async function (id) { | 
					
						
							|  |  |  | 		const pluginDir = path.join(__dirname, '../../node_modules', id); | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			const stats = await statAsync(pluginDir); | 
					
						
							|  |  |  | 			return stats.isDirectory(); | 
					
						
							|  |  |  | 		} catch (err) { | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-12-26 18:54:20 -05:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 	Plugins.isActive = async function (id) { | 
					
						
							|  |  |  | 		return await db.isSortedSetMember('plugins:active', id); | 
					
						
							| 
									
										
										
										
											2014-12-26 18:54:20 -05:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2015-02-23 15:55:35 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-22 00:30:47 -04:00
										 |  |  | 	Plugins.getActive = async function () { | 
					
						
							|  |  |  | 		return await db.getSortedSetRange('plugins:active', 0, -1); | 
					
						
							| 
									
										
										
										
											2015-02-23 15:55:35 -05:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-02-18 02:30:48 -07:00
										 |  |  | }; |