Added remote plugin reconciliation

This commit is contained in:
Wyatt Johnson
2017-03-31 15:54:39 -06:00
parent e5da8354d6
commit 0108673566
12 changed files with 343 additions and 248 deletions
+1
View File
@@ -13,6 +13,7 @@ program
.command('setup', 'setup the application')
.command('jobs', 'work with the job queues')
.command('users', 'work with the application auth')
.command('plugins', 'provides utilities for interacting with the plugin system')
.parse(process.argv);
/**
+193
View File
@@ -0,0 +1,193 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
const program = require('./commander');
// Make things colorful!
require('colors');
const fs = require('fs');
const path = require('path');
const spawn = require('cross-spawn');
const resolve = require('resolve');
const {plugins, isInternal} = require('../plugins');
function existsInNodeModules(name) {
try {
resolve.sync(name, {basedir: process.cwd()});
return true;
} catch (e) {
return false;
}
}
const EXTERNAL = /^\w[a-z\-0-9\.]+$/; // Match "react", "path", "fs", "lodash.random", etc.
async function reconcileRemotePlugins(dryRun) {
const linkable = [];
const fetchable = [];
console.log('\n[1/3] 🔍 Reconciling plugins...\n'.yellow);
console.log(' +local (l) packages in your project\n +external (e) referenced packages in node_modules but not in current project\n +missing (m) referenced packages but not found\n +symlinked (sl) symlinked external packages\n');
for (let i in plugins) {
let section = plugins[i];
for (let name in section) {
let version = section[name];
let namespaced = name.charAt(0) === '@';
let dep = name.split('/')
.slice(0, namespaced ? 2 : 1)
.join('/');
// Ignore relative modules, which aren't installed by NPM
if (!dep.match(EXTERNAL) && !namespaced) {
return;
}
if (isInternal(dep)) {
let stat = fs.lstatSync(path.join(process.cwd(), 'plugins', name));
if (stat.isSymbolicLink()) {
console.log(` sl ${name.cyan}`);
} else {
console.log(` l ${name.cyan}`);
}
continue;
}
if (!existsInNodeModules(dep)) {
console.warn(` m ${name.cyan}`);
fetchable.push({name, version});
} else {
console.log(` e ${name.cyan}`);
linkable.push({name, version});
}
}
}
console.log('\n[2/3] 🚚 Fetching plugins...\n'.yellow);
if (fetchable.length > 0) {
console.log(`$ yarn add ${fetchable.map(({name, version}) => `${name}@${version}`.cyan)}`);
if (!dryRun) {
let args = [
'add',
...fetchable.map(({name, version}) => `${name}@${version}`)
];
let output = spawn.sync('yarn', args, {
stdio: ['ignore', 'pipe', 'inherit']
});
if (output.status) {
throw new Error('Could not install external plugins, errors occured during install');
}
console.log(output.stdout.toString());
}
fetchable.forEach((plugin) => {
linkable.push(plugin);
});
}
// TODO fetch the plugins using yarn
console.log('\n[3/3] 🔗 Linking plugins...\n'.yellow);
for (let i in linkable) {
let {name} = linkable[i];
let src = path.join(process.cwd(), 'node_modules', name);
let dst = path.join(process.cwd(), 'plugins', name);
console.log(`$ link ${src.cyan} -> ${dst.cyan}`);
if (!dryRun) {
// Create the symlink for the plugin directory.
fs.symlinkSync(src, dst, 'dir');
}
}
return {linkable, fetchable};
}
// This traverses the local plugins and installs any dependencies listed there,
// this only is really needed for plugins that are installed via docker because
// core plugins will have their dependencies already included in core.
async function reconcilePluginDeps(options) {
let startTime = new Date();
// We don't need to do anything if we skip everything....
if (options.skipLocal && options.skipRemote) {
return;
}
// Traverse local plugins and install dependencies if enabled.
if (!options.skipLocal) {
}
// Locate any external plugins and install them.
if (!options.skipRemote) {
let results = [];
try {
results = await reconcileRemotePlugins(options.dryRun);
} catch (e) {
throw e;
}
let status;
if (options.dryRun) {
status = '[dry-run] success'.green;
} else {
status = 'success'.green;
}
let message;
if (results.linkable.length === 0 && results.fetchable.length === 0) {
message = 'Already up-to-date.';
} else if (results.linkable.length === 0) {
message = `Fetched ${results.fetchable.length} new plugins.`;
} else if (results.fetchable.length === 0) {
message = `Linked ${results.linkable.length} new plugins.`;
} else {
message = `Fetched ${results.fetchable.length} new plugins, linked ${results.linkable.length} plugins.`;
}
console.log(`\n${status} ${message}`);
}
let endTime = new Date();
let totalTime = ((endTime.getTime() - startTime.getTime()) / 1000).toFixed(2);
console.log(`✨ Done in ${totalTime}s.`);
}
//==============================================================================
// Setting up the program command line arguments.
//==============================================================================
program
.command('reconcile')
.description('reconciles local plugin dependencies and downloads external plugins')
.option('-d, --dry-run', 'does not actually change anything on the filesystem acts only as a simulation')
.option('--skip-local', 'skips the local dependancy reconciliation')
.option('--skip-remote', 'skips the remote plugin reconciliation')
.action(reconcilePluginDeps);
program.parse(process.argv);
// If there is no command listed, output help.
if (!process.argv.slice(2).length) {
program.outputHelp();
}
+1 -1
View File
@@ -1,7 +1,7 @@
const loaders = require('./loaders');
const mutators = require('./mutators');
const plugins = require('../plugins');
const plugins = require('../services/plugins');
const debug = require('debug')('talk:graph:context');
/**
+1 -1
View File
@@ -8,7 +8,7 @@ const Metrics = require('./metrics');
const Settings = require('./settings');
const Users = require('./users');
const plugins = require('../../plugins');
const plugins = require('../../services/plugins');
let loaders = [
+1 -1
View File
@@ -5,7 +5,7 @@ const Comment = require('./comment');
const Action = require('./action');
const User = require('./user');
const plugins = require('../../plugins');
const plugins = require('../../services/plugins');
let mutators = [
+1 -1
View File
@@ -20,7 +20,7 @@ const UserError = require('./user_error');
const User = require('./user');
const ValidationUserError = require('./validation_user_error');
const plugins = require('../../plugins');
const plugins = require('../../services/plugins');
// Provide the core resolvers.
let resolvers = {
+1 -1
View File
@@ -2,7 +2,7 @@ const {makeExecutableSchema} = require('graphql-tools');
const {maskErrors} = require('graphql-errors');
const {decorateWithHooks} = require('./hooks');
const plugins = require('../plugins');
const plugins = require('../services/plugins');
const resolvers = require('./resolvers');
const typeDefs = require('./typeDefs');
+1 -1
View File
@@ -6,7 +6,7 @@ const fs = require('fs');
const path = require('path');
const {mergeStrings} = require('gql-merge');
const debug = require('debug')('talk:graph:typeDefs');
const plugins = require('../plugins');
const plugins = require('../services/plugins');
/**
* Plugin support requires us to merge the type definitions from the loaded
+3
View File
@@ -52,8 +52,10 @@
"bcrypt": "^1.0.2",
"body-parser": "^1.17.1",
"cli-table": "^0.3.1",
"colors": "^1.1.2",
"commander": "^2.9.0",
"connect-redis": "^3.1.0",
"cross-spawn": "^5.1.0",
"csurf": "^1.9.0",
"dataloader": "^1.3.0",
"debug": "^2.6.3",
@@ -88,6 +90,7 @@
"react-apollo": "^0.10.0",
"react-recaptcha": "^2.2.6",
"redis": "^2.7.1",
"resolve": "^1.3.2",
"uuid": "^2.0.3"
},
"devDependencies": {
+63 -5
View File
@@ -1,5 +1,6 @@
const fs = require('fs');
const path = require('path');
const debug = require('debug')('talk:plugins');
let plugins = {};
@@ -16,13 +17,65 @@ try {
}
}
/**
* isInternal checks to see if a given plugin is internal, and returns true
* if it is.
*
* @param {String} name
* @returns {Boolean}
*/
function isInternal(name) {
const internalPluginPath = path.join(__dirname, 'plugins', name);
// Check to see if this plugin exists internally, because if it doesn't, it is
// external.
return fs.existsSync(internalPluginPath);
}
/**
* Returns the plugin path for the given plugin name.
*
* @param {any} name
* @returns
*/
function pluginPath(name) {
if (isInternal(name)) {
return path.join(__dirname, 'plugins', name);
}
// The plugin is not available.
return undefined;
}
/**
* Stores a reference to a section for a section of Plugins.
*/
class PluginSection {
constructor(plugin_names) {
this.plugins = plugin_names.map((plugin_name) => {
let plugin = require(`./plugins/${plugin_name}`);
this.plugins = Object.keys(plugin_names).map((plugin_name) => {
let plugin = {};
// Get the version/folder that was specified.
plugin.version = plugin_names[plugin_name];
// Get the path for the plugin.
plugin.path = pluginPath(plugin_name);
if (typeof plugin.path === 'undefined') {
throw new Error(`plugin '${plugin_name}' is not local or is not symlinked from your node_modules directory, plugin reconsiliation may be required`);
}
try {
plugin.module = require(plugin.path);
} catch (e) {
throw new Error(`plugin '${plugin_name}' could not be required from '${plugin.path}': ${e.message}`);
}
if (isInternal(plugin_name)) {
debug(`loading internal plugin '${plugin_name}' from '${plugin.path}'`);
} else {
debug(`loading external plugin '${plugin_name}' from '${plugin.path}'`);
}
// Ensure we have a default plugin name, but allow the name to be
// overrided by the plugin.
@@ -38,8 +91,8 @@ class PluginSection {
*/
hook(hook) {
return this.plugins
.filter((plugin) => hook in plugin)
.map((plugin) => ({plugin, [hook]: plugin[hook]}));
.filter(({module}) => hook in module)
.map((plugin) => ({plugin, [hook]: module[hook]}));
}
}
@@ -78,4 +131,9 @@ class PluginManager {
}
}
module.exports = new PluginManager(plugins);
module.exports = {
plugins,
PluginManager,
isInternal,
pluginPath
};
+3
View File
@@ -0,0 +1,3 @@
const {plugins, PluginManager} = require('../plugins');
module.exports = new PluginManager(plugins);
+74 -237
View File
@@ -397,19 +397,7 @@ babel-eslint@^7.2.1:
babel-types "^6.23.0"
babylon "^6.16.1"
babel-generator@^6.18.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.22.0.tgz#d642bf4961911a8adc7c692b0c9297f325cda805"
dependencies:
babel-messages "^6.22.0"
babel-runtime "^6.22.0"
babel-types "^6.22.0"
detect-indent "^4.0.0"
jsesc "^1.3.0"
lodash "^4.2.0"
source-map "^0.5.0"
babel-generator@^6.24.0:
babel-generator@^6.18.0, babel-generator@^6.24.0:
version "6.24.0"
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.0.tgz#eba270a8cc4ce6e09a61be43465d7c62c1f87c56"
dependencies:
@@ -482,17 +470,7 @@ babel-helper-explode-class@^6.22.0:
babel-traverse "^6.22.0"
babel-types "^6.22.0"
babel-helper-function-name@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.22.0.tgz#51f1bdc4bb89b15f57a9b249f33d742816dcbefc"
dependencies:
babel-helper-get-function-arity "^6.22.0"
babel-runtime "^6.22.0"
babel-template "^6.22.0"
babel-traverse "^6.22.0"
babel-types "^6.22.0"
babel-helper-function-name@^6.23.0:
babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz#25742d67175c8903dbe4b6cb9d9e1fcb8dcf23a6"
dependencies:
@@ -576,13 +554,7 @@ babel-loader@^6.4.1:
mkdirp "^0.5.1"
object-assign "^4.0.1"
babel-messages@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.22.0.tgz#36066a214f1217e4ed4164867669ecb39e3ea575"
dependencies:
babel-runtime "^6.22.0"
babel-messages@^6.23.0:
babel-messages@^6.22.0, babel-messages@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
dependencies:
@@ -686,16 +658,7 @@ babel-plugin-transform-class-constructor-call@^6.22.0:
babel-runtime "^6.22.0"
babel-template "^6.22.0"
babel-plugin-transform-class-properties@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.22.0.tgz#aa78f8134495c7de06c097118ba061844e1dc1d8"
dependencies:
babel-helper-function-name "^6.22.0"
babel-plugin-syntax-class-properties "^6.8.0"
babel-runtime "^6.22.0"
babel-template "^6.22.0"
babel-plugin-transform-class-properties@^6.23.0:
babel-plugin-transform-class-properties@^6.22.0, babel-plugin-transform-class-properties@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.23.0.tgz#187b747ee404399013563c993db038f34754ac3b"
dependencies:
@@ -925,14 +888,7 @@ babel-plugin-transform-object-assign@^6.8.0:
dependencies:
babel-runtime "^6.22.0"
babel-plugin-transform-object-rest-spread@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.22.0.tgz#1d419b55e68d2e4f64a5ff3373bd67d73c8e83bc"
dependencies:
babel-plugin-syntax-object-rest-spread "^6.8.0"
babel-runtime "^6.22.0"
babel-plugin-transform-object-rest-spread@^6.23.0:
babel-plugin-transform-object-rest-spread@^6.22.0, babel-plugin-transform-object-rest-spread@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921"
dependencies:
@@ -1057,17 +1013,7 @@ babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtim
core-js "^2.4.0"
regenerator-runtime "^0.10.0"
babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.3.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.22.0.tgz#403d110905a4626b317a2a1fcb8f3b73204b2edb"
dependencies:
babel-runtime "^6.22.0"
babel-traverse "^6.22.0"
babel-types "^6.22.0"
babylon "^6.11.0"
lodash "^4.2.0"
babel-template@^6.23.0:
babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0, babel-template@^6.3.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.23.0.tgz#04d4f270adbb3aa704a8143ae26faa529238e638"
dependencies:
@@ -1077,21 +1023,7 @@ babel-template@^6.23.0:
babylon "^6.11.0"
lodash "^4.2.0"
babel-traverse@^6.18.0, babel-traverse@^6.22.0:
version "6.22.1"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.22.1.tgz#3b95cd6b7427d6f1f757704908f2fc9748a5f59f"
dependencies:
babel-code-frame "^6.22.0"
babel-messages "^6.22.0"
babel-runtime "^6.22.0"
babel-types "^6.22.0"
babylon "^6.15.0"
debug "^2.2.0"
globals "^9.0.0"
invariant "^2.2.0"
lodash "^4.2.0"
babel-traverse@^6.23.0, babel-traverse@^6.23.1:
babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1:
version "6.23.1"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48"
dependencies:
@@ -1105,16 +1037,7 @@ babel-traverse@^6.23.0, babel-traverse@^6.23.1:
invariant "^2.2.0"
lodash "^4.2.0"
babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.22.0.tgz#2a447e8d0ea25d2512409e4175479fd78cc8b1db"
dependencies:
babel-runtime "^6.22.0"
esutils "^2.0.2"
lodash "^4.2.0"
to-fast-properties "^1.0.1"
babel-types@^6.23.0:
babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf"
dependencies:
@@ -1123,11 +1046,11 @@ babel-types@^6.23.0:
lodash "^4.2.0"
to-fast-properties "^1.0.1"
babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0:
babylon@^6.11.0:
version "6.15.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e"
babylon@^6.16.1:
babylon@^6.13.0, babylon@^6.15.0, babylon@^6.16.1:
version "6.16.1"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3"
@@ -1221,22 +1144,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
version "4.11.6"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215"
body-parser@^1.12.2:
version "1.16.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.16.0.tgz#924a5e472c6229fb9d69b85a20d5f2532dec788b"
dependencies:
bytes "2.4.0"
content-type "~1.0.2"
debug "2.6.0"
depd "~1.1.0"
http-errors "~1.5.1"
iconv-lite "0.4.15"
on-finished "~2.3.0"
qs "6.2.1"
raw-body "~2.2.0"
type-is "~1.6.14"
body-parser@^1.17.1:
body-parser@^1.12.2, body-parser@^1.17.1:
version "1.17.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.1.tgz#75b3bc98ddd6e7e0d8ffe750dfaca5c66993fa47"
dependencies:
@@ -1723,7 +1631,7 @@ colors@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
colors@1.1.2, colors@~1.1.2:
colors@1.1.2, colors@^1.1.2, colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@@ -1965,6 +1873,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2:
create-hash "^1.1.0"
inherits "^2.0.1"
cross-spawn@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
dependencies:
lru-cache "^4.0.1"
shebang-command "^1.2.0"
which "^1.2.9"
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
@@ -2186,9 +2102,9 @@ date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
debug@*, debug@2, debug@2.6.0, debug@^2.1.1, debug@^2.2.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b"
debug@*, debug@2, debug@2.6.3, debug@^2.1.1, debug@^2.2.0, debug@^2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d"
dependencies:
ms "0.7.2"
@@ -2210,12 +2126,6 @@ debug@2.6.1:
dependencies:
ms "0.7.2"
debug@2.6.3, debug@^2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d"
dependencies:
ms "0.7.2"
debug@^0.7.2, debug@~0.7.4:
version "0.7.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39"
@@ -2797,10 +2707,6 @@ esutils@^2.0.0, esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
etag@~1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8"
etag@~1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051"
@@ -2871,38 +2777,7 @@ express-session@^1.15.1:
uid-safe "~2.1.3"
utils-merge "1.0.0"
express@^4.12.2:
version "4.14.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.14.1.tgz#646c237f766f148c2120aff073817b9e4d7e0d33"
dependencies:
accepts "~1.3.3"
array-flatten "1.1.1"
content-disposition "0.5.2"
content-type "~1.0.2"
cookie "0.3.1"
cookie-signature "1.0.6"
debug "~2.2.0"
depd "~1.1.0"
encodeurl "~1.0.1"
escape-html "~1.0.3"
etag "~1.7.0"
finalhandler "0.5.1"
fresh "0.3.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "~2.3.0"
parseurl "~1.3.1"
path-to-regexp "0.1.7"
proxy-addr "~1.1.3"
qs "6.2.0"
range-parser "~1.2.0"
send "0.14.2"
serve-static "~1.11.2"
type-is "~1.6.14"
utils-merge "1.0.0"
vary "~1.1.0"
express@^4.15.2:
express@^4.12.2, express@^4.15.2:
version "4.15.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.15.2.tgz#af107fc148504457f2dca9a6f2571d7129b97b35"
dependencies:
@@ -3038,16 +2913,6 @@ fill-range@^2.1.0:
repeat-element "^1.1.2"
repeat-string "^1.5.2"
finalhandler@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.1.tgz#2c400d8d4530935bc232549c5fa385ec07de6fcd"
dependencies:
debug "~2.2.0"
escape-html "~1.0.3"
on-finished "~2.3.0"
statuses "~1.3.1"
unpipe "~1.0.0"
finalhandler@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.0.tgz#b5691c2c0912092f18ac23e9416bde5cd7dc6755"
@@ -3167,10 +3032,6 @@ frameguard@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/frameguard/-/frameguard-3.0.0.tgz#7bcad469ee7b96e91d12ceb3959c78235a9272e9"
fresh@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f"
fresh@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e"
@@ -3756,7 +3617,7 @@ htmlparser2@~3.8.1:
entities "1.0"
readable-stream "1.1"
http-errors@~1.5.0, http-errors@~1.5.1:
http-errors@~1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750"
dependencies:
@@ -4269,19 +4130,7 @@ istanbul-lib-hook@^1.0.0:
dependencies:
append-transform "^0.4.0"
istanbul-lib-instrument@^1.3.0:
version "1.4.2"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.4.2.tgz#0e2fdfac93c1dabf2e31578637dc78a19089f43e"
dependencies:
babel-generator "^6.18.0"
babel-template "^6.16.0"
babel-traverse "^6.18.0"
babel-types "^6.18.0"
babylon "^6.13.0"
istanbul-lib-coverage "^1.0.0"
semver "^5.3.0"
istanbul-lib-instrument@^1.6.2:
istanbul-lib-instrument@^1.3.0, istanbul-lib-instrument@^1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.6.2.tgz#dac644f358f51efd6113536d7070959a0111f73b"
dependencies:
@@ -4912,6 +4761,13 @@ lru-cache@2, lru-cache@^2.5.0:
version "2.7.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"
lru-cache@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e"
dependencies:
pseudomap "^1.0.1"
yallist "^2.0.0"
lru-cache@~2.6.5:
version "2.6.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5"
@@ -6280,18 +6136,18 @@ postcss@5.1.2:
source-map "^0.5.6"
supports-color "^3.1.2"
postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.19, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.1.2, postcss@^5.2.11, postcss@^5.2.4, postcss@^5.2.5:
version "5.2.11"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.11.tgz#ff29bcd6d2efb98bfe08a022055ec599bbe7b761"
postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.19, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.8, postcss@^5.1.2, postcss@^5.2.15, postcss@^5.2.4, postcss@^5.2.5:
version "5.2.16"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.16.tgz#732b3100000f9ff8379a48a53839ed097376ad57"
dependencies:
chalk "^1.1.3"
js-base64 "^2.1.9"
source-map "^0.5.6"
supports-color "^3.2.3"
postcss@^5.2.15:
version "5.2.16"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.16.tgz#732b3100000f9ff8379a48a53839ed097376ad57"
postcss@^5.0.6, postcss@^5.2.11:
version "5.2.11"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.11.tgz#ff29bcd6d2efb98bfe08a022055ec599bbe7b761"
dependencies:
chalk "^1.1.3"
js-base64 "^2.1.9"
@@ -6412,6 +6268,10 @@ ps-tree@^1.0.1:
dependencies:
event-stream "~3.3.0"
pseudomap@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
public-encrypt@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6"
@@ -6543,15 +6403,7 @@ q@^1.1.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
qs@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b"
qs@6.2.1, qs@^6.1.0, qs@^6.2.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625"
qs@6.4.0:
qs@6.4.0, qs@^6.1.0, qs@^6.2.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
@@ -6828,11 +6680,7 @@ redis-commands@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b"
redis-parser@^2.0.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.4.0.tgz#018ea743077aae944d0b798b2fd12587320bf3c9"
redis-parser@^2.5.0:
redis-parser@^2.0.0, redis-parser@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.5.0.tgz#79fc2b1d4a6e4d2870b35368433639271fca2617"
@@ -6840,15 +6688,7 @@ redis@^0.12.1:
version "0.12.1"
resolved "https://registry.yarnpkg.com/redis/-/redis-0.12.1.tgz#64df76ad0fc8acebaebd2a0645e8a48fac49185e"
redis@^2.1.0, redis@~2.6.0-2:
version "2.6.5"
resolved "https://registry.yarnpkg.com/redis/-/redis-2.6.5.tgz#87c1eff4a489f94b70871f3d08b6988f23a95687"
dependencies:
double-ended-queue "^2.1.0-0"
redis-commands "^1.2.0"
redis-parser "^2.0.0"
redis@^2.7.1:
redis@^2.1.0, redis@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/redis/-/redis-2.7.1.tgz#7d56f7875b98b20410b71539f1d878ed58ebf46a"
dependencies:
@@ -6856,6 +6696,14 @@ redis@^2.7.1:
redis-commands "^1.2.0"
redis-parser "^2.5.0"
redis@~2.6.0-2:
version "2.6.5"
resolved "https://registry.yarnpkg.com/redis/-/redis-2.6.5.tgz#87c1eff4a489f94b70871f3d08b6988f23a95687"
dependencies:
double-ended-queue "^2.1.0-0"
redis-commands "^1.2.0"
redis-parser "^2.0.0"
reds@^0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/reds/-/reds-0.2.5.tgz#38a767f7663cd749036848697d82c74fd29bc01f"
@@ -7056,9 +6904,11 @@ resolve-from@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
resolve@^1.1.6, resolve@^1.1.7:
version "1.2.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.2.0.tgz#9589c3f2f6149d1417a40becc1663db6ec6bc26c"
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235"
dependencies:
path-parse "^1.0.5"
restore-cursor@^1.0.1:
version "1.0.1"
@@ -7172,24 +7022,6 @@ semver@~5.0.1:
version "5.0.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a"
send@0.14.2:
version "0.14.2"
resolved "https://registry.yarnpkg.com/send/-/send-0.14.2.tgz#39b0438b3f510be5dc6f667a11f71689368cdeef"
dependencies:
debug "~2.2.0"
depd "~1.1.0"
destroy "~1.0.4"
encodeurl "~1.0.1"
escape-html "~1.0.3"
etag "~1.7.0"
fresh "0.3.0"
http-errors "~1.5.1"
mime "1.3.4"
ms "0.7.2"
on-finished "~2.3.0"
range-parser "~1.2.0"
statuses "~1.3.1"
send@0.15.1:
version "0.15.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.15.1.tgz#8a02354c26e6f5cca700065f5f0cdeba90ec7b5f"
@@ -7217,15 +7049,6 @@ serve-static@1.12.1:
parseurl "~1.3.1"
send "0.15.1"
serve-static@~1.11.2:
version "1.11.2"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.2.tgz#2cf9889bd4435a320cc36895c9aa57bd662e6ac7"
dependencies:
encodeurl "~1.0.1"
escape-html "~1.0.3"
parseurl "~1.3.1"
send "0.14.2"
set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
@@ -7252,6 +7075,16 @@ sha.js@^2.3.6:
dependencies:
inherits "^2.0.1"
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
dependencies:
shebang-regex "^1.0.0"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
shelljs@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.0.tgz#ce1ed837b4b0e55b5ec3dab84251ab9dbdc0c7ec"
@@ -8128,7 +7961,7 @@ which@1.1.1:
dependencies:
is-absolute "^0.1.7"
which@^1.1.1:
which@^1.1.1, which@^1.2.9:
version "1.2.12"
resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192"
dependencies:
@@ -8230,6 +8063,10 @@ y18n@^3.2.0, y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
yallist@^2.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
yargs-parser@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4"