live-server
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -11,6 +11,10 @@ Contributing Guidelines | ||
* Does my code adhere to the project's coding style (observable from surrounding code)? | ||
* Can backwards compatibility be preserved? | ||
A few guiding principles: keep the app simple and small, focusing on what it's meant to provide: live reloading development web server. Avoid extra dependencies and the need to do configuration when possible and it makes sense. Minimize bloat. | ||
If you are adding a feature, think about if it could be an extenral middleware instead, possible bundled with `live-server` in its `middleware` folder. | ||
**New features should come with test cases!** | ||
**Run `npm test` to check that you are not introducing new bugs or style issues!** | ||
177
index.js
@@ -13,3 +13,4 @@ #!/usr/bin/env node | ||
es = require("event-stream"), | ||
watchr = require('watchr'); | ||
os = require('os'), | ||
chokidar = require('chokidar'); | ||
require('colors'); | ||
@@ -21,3 +22,3 @@ | ||
server: null, | ||
watchers: [], | ||
watcher: null, | ||
logLevel: 2 | ||
@@ -35,3 +36,3 @@ }; | ||
// Based on connect.static(), but streamlined and with added code injecter | ||
function staticServer(root, spa) { | ||
function staticServer(root) { | ||
var isFile = false; | ||
@@ -47,13 +48,5 @@ try { // For supporting mounting files instead of just directories | ||
var hasNoOrigin = !req.headers.origin; | ||
var injectCandidates = [ new RegExp("</body>", "i"), new RegExp("</svg>") ]; | ||
var injectCandidates = [ new RegExp("</body>", "i"), new RegExp("</svg>"), new RegExp("</head>", "i")]; | ||
var injectTag = null; | ||
// Single Page App - redirect handler | ||
if (spa && req.url !== '/') { | ||
var route = req.url; | ||
req.url = '/'; | ||
res.statusCode = 302; | ||
res.setHeader('Location', req.url + '#' + route); | ||
} | ||
function directory() { | ||
@@ -97,4 +90,4 @@ var pathname = url.parse(req.originalUrl).pathname; | ||
var originalPipe = stream.pipe; | ||
stream.pipe = function(res) { | ||
originalPipe.call(stream, es.replace(new RegExp(injectTag, "i"), INJECTED_CODE + injectTag)).pipe(res); | ||
stream.pipe = function(resp) { | ||
originalPipe.call(stream, es.replace(new RegExp(injectTag, "i"), INJECTED_CODE + injectTag)).pipe(resp); | ||
}; | ||
@@ -135,3 +128,3 @@ } | ||
* @param ignorePattern {regexp} Ignore files by RegExp | ||
* @param open {string} Subpath to open in browser, use false to suppress launch (default: server root) | ||
* @param open {(string|string[])} Subpath(s) to open in browser, use false to suppress launch (default: server root) | ||
* @param mount {array} Mount directories onto a route, e.g. [['/components', './node_modules']]. | ||
@@ -154,7 +147,6 @@ * @param logLevel {number} 0 = errors only, 1 = some, 2 = lots | ||
"" : ((options.open === null || options.open === false) ? null : options.open); | ||
var spa = options.spa || false; | ||
if (options.noBrowser) openPath = null; // Backwards compatibility with 0.7.0 | ||
var file = options.file; | ||
var staticServerHandler = staticServer(root, spa); | ||
var wait = options.wait || 0; | ||
var staticServerHandler = staticServer(root); | ||
var wait = options.wait === undefined ? 100 : options.wait; | ||
var browser = options.browser || null; | ||
@@ -170,4 +162,26 @@ var htpasswd = options.htpasswd || null; | ||
// Add logger. Level 2 logs only errors | ||
if (LiveServer.logLevel === 2) { | ||
app.use(logger('dev', { | ||
skip: function (req, res) { return res.statusCode < 400; } | ||
})); | ||
// Level 2 or above logs all requests | ||
} else if (LiveServer.logLevel > 2) { | ||
app.use(logger('dev')); | ||
} | ||
if (options.spa) { | ||
middleware.push("spa"); | ||
} | ||
// Add middleware | ||
middleware.map(app.use.bind(app)); | ||
middleware.map(function(mw) { | ||
if (typeof mw === "string") { | ||
var ext = path.extname(mw).toLocaleLowerCase(); | ||
if (ext !== ".js") { | ||
mw = require(path.join(__dirname, "middleware", mw + ".js")); | ||
} else { | ||
mw = require(mw); | ||
} | ||
} | ||
app.use(mw); | ||
}); | ||
@@ -208,8 +222,9 @@ // Use http-auth if configured | ||
.use(serveIndex(root, { icons: true })); | ||
if (LiveServer.logLevel >= 2) | ||
app.use(logger('dev')); | ||
var server, protocol; | ||
if (https !== null) { | ||
var httpsConfig = require(path.resolve(process.cwd(), https)); | ||
var httpsConfig = https; | ||
if (typeof https === "string") { | ||
httpsConfig = require(path.resolve(process.cwd(), https)); | ||
} | ||
server = require("https").createServer(httpsConfig, app); | ||
@@ -247,6 +262,31 @@ protocol = "https"; | ||
var serveURLs = [ serveURL ]; | ||
if (LiveServer.logLevel > 2 && address.address === "0.0.0.0") { | ||
var ifaces = os.networkInterfaces(); | ||
serveURLs = Object.keys(ifaces) | ||
.map(function(iface) { | ||
return ifaces[iface]; | ||
}) | ||
// flatten address data, use only IPv4 | ||
.reduce(function(data, addresses) { | ||
addresses.filter(function(addr) { | ||
return addr.family === "IPv4"; | ||
}).forEach(function(addr) { | ||
data.push(addr); | ||
}); | ||
return data; | ||
}, []) | ||
.map(function(addr) { | ||
return protocol + "://" + addr.address + ":" + address.port; | ||
}); | ||
} | ||
// Output | ||
if (LiveServer.logLevel >= 1) { | ||
if (serveURL === openURL) | ||
console.log(("Serving \"%s\" at %s").green, root, serveURL); | ||
if (serveURLs.length === 1) { | ||
console.log(("Serving \"%s\" at %s").green, root, serveURLs[0]); | ||
} else { | ||
console.log(("Serving \"%s\" at\n\t%s").green, root, serveURLs.join("\n\t")); | ||
} | ||
else | ||
@@ -258,3 +298,9 @@ console.log(("Serving \"%s\" at %s (%s)").green, root, openURL, serveURL); | ||
if (openPath !== null) | ||
open(openURL + openPath, {app: browser}); | ||
if (typeof openPath === "object") { | ||
openPath.forEach(function(p) { | ||
open(openURL + p, {app: browser}); | ||
}); | ||
} else { | ||
open(openURL + openPath, {app: browser}); | ||
} | ||
}); | ||
@@ -272,6 +318,5 @@ | ||
if (wait > 0) { | ||
(function(ws) { | ||
(function() { | ||
var wssend = ws.send; | ||
var waitTimeout; | ||
ws.send = function() { | ||
@@ -284,3 +329,3 @@ var args = arguments; | ||
}; | ||
})(ws); | ||
})(); | ||
} | ||
@@ -297,36 +342,43 @@ | ||
var ignored = [ | ||
function(testPath) { // Always ignore dotfiles (important e.g. because editor hidden temp files) | ||
return testPath !== "." && /(^[.#]|(?:__|~)$)/.test(path.basename(testPath)); | ||
} | ||
]; | ||
if (options.ignore) { | ||
ignored = ignored.concat(options.ignore); | ||
} | ||
if (options.ignorePattern) { | ||
ignored.push(options.ignorePattern); | ||
} | ||
// Setup file watcher | ||
watchr.watch({ | ||
paths: watchPaths, | ||
ignorePaths: options.ignore || false, | ||
ignoreCommonPatterns: true, | ||
ignoreHiddenFiles: true, | ||
ignoreCustomPatterns: options.ignorePattern || null, | ||
preferredMethods: [ 'watchFile', 'watch' ], | ||
interval: 1407, | ||
listeners: { | ||
error: function(err) { | ||
console.log("ERROR:".red, err); | ||
}, | ||
change: function(eventName, filePath /*, fileCurrentStat, filePreviousStat*/) { | ||
clients.forEach(function(ws) { | ||
if (!ws) return; | ||
if (path.extname(filePath) === ".css") { | ||
ws.send('refreshcss'); | ||
if (LiveServer.logLevel >= 1) | ||
console.log("CSS change detected".magenta, filePath); | ||
} else { | ||
ws.send('reload'); | ||
if (LiveServer.logLevel >= 1) | ||
console.log("File change detected".cyan, filePath); | ||
} | ||
}); | ||
} | ||
}, | ||
next: function(err, watchers) { | ||
if (err) | ||
console.error("Error watching files:".red, err); | ||
LiveServer.watchers = watchers; | ||
LiveServer.watcher = chokidar.watch(watchPaths, { | ||
ignored: ignored, | ||
ignoreInitial: true | ||
}); | ||
function handleChange(changePath) { | ||
var cssChange = path.extname(changePath) === ".css"; | ||
if (LiveServer.logLevel >= 1) { | ||
if (cssChange) | ||
console.log("CSS change detected".magenta, changePath); | ||
else console.log("Change detected".cyan, changePath); | ||
} | ||
}); | ||
clients.forEach(function(ws) { | ||
if (ws) | ||
ws.send(cssChange ? 'refreshcss' : 'reload'); | ||
}); | ||
} | ||
LiveServer.watcher | ||
.on("change", handleChange) | ||
.on("add", handleChange) | ||
.on("unlink", handleChange) | ||
.on("addDir", handleChange) | ||
.on("unlinkDir", handleChange) | ||
.on("ready", function () { | ||
if (LiveServer.logLevel >= 1) | ||
console.log("Ready for changes".cyan); | ||
}) | ||
.on("error", function (err) { | ||
console.log("ERROR:".red, err); | ||
}); | ||
@@ -337,6 +389,5 @@ return server; | ||
LiveServer.shutdown = function() { | ||
var watchers = LiveServer.watchers; | ||
if (watchers) { | ||
for (var i = 0; i < watchers.length; ++i) | ||
watchers[i].close(); | ||
var watcher = LiveServer.watcher; | ||
if (watcher) { | ||
watcher.close(); | ||
} | ||
@@ -343,0 +394,0 @@ var server = LiveServer.server; |
@@ -13,3 +13,4 @@ #!/usr/bin/env node | ||
proxy: [], | ||
logLevel: 2 | ||
middleware: [], | ||
logLevel: 2, | ||
}; | ||
@@ -44,3 +45,13 @@ | ||
} | ||
opts.open = open; | ||
switch (typeof opts.open) { | ||
case "boolean": | ||
opts.open = open; | ||
break; | ||
case "string": | ||
opts.open = [opts.open, open]; | ||
break; | ||
case "object": | ||
opts.open.push(open); | ||
break; | ||
} | ||
process.argv.splice(i, 1); | ||
@@ -78,3 +89,3 @@ } | ||
else if (arg === "--spa") { | ||
opts.spa = true; | ||
opts.middleware.push("spa"); | ||
process.argv.splice(i, 1); | ||
@@ -86,7 +97,12 @@ } | ||
} | ||
else if (arg === "--verbose" || arg === "-V") { | ||
opts.logLevel = 3; | ||
process.argv.splice(i, 1); | ||
} | ||
else if (arg.indexOf("--mount=") > -1) { | ||
// e.g. "--mount=/components:./node_modules" will be ['/components', '<process.cwd()>/node_modules'] | ||
var mountRule = arg.substring(8).split(":"); | ||
mountRule[1] = path.resolve(process.cwd(), mountRule[1]); | ||
opts.mount.push(mountRule); | ||
// split only on the first ":", as the path may contain ":" as well (e.g. C:\file.txt) | ||
var match = arg.substring(8).match(/([^:]+):(.+)$/); | ||
match[2] = path.resolve(process.cwd(), match[2]); | ||
opts.mount.push([ match[1], match[2] ]); | ||
process.argv.splice(i, 1); | ||
@@ -125,2 +141,6 @@ } | ||
} | ||
else if (arg.indexOf("--middleware=") > -1) { | ||
opts.middleware.push(arg.substring(13)); | ||
process.argv.splice(i, 1); | ||
} | ||
else if (arg === "--help" || arg === "-h") { | ||
@@ -127,0 +147,0 @@ console.log('Usage: live-server [-v|--version] [-h|--help] [-q|--quiet] [--port=PORT] [--host=HOST] [--open=PATH] [--no-browser] [--browser=BROWSER] [--ignore=PATH] [--ignorePattern=RGXP] [--entry-file=PATH] [--spa] [--mount=ROUTE:PATH] [--wait=MILLISECONDS] [--htpasswd=PATH] [--cors] [--https=PATH] [--proxy=PATH] [PATH]'); |
{ | ||
"name": "live-server", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "simple development http server with live reload capability", | ||
@@ -15,8 +15,9 @@ "keywords": [ | ||
"dependencies": { | ||
"chokidar": "^1.6.0", | ||
"colors": "latest", | ||
"connect": "3.4.x", | ||
"connect": "3.5.x", | ||
"cors": "latest", | ||
"event-stream": "latest", | ||
"faye-websocket": "0.11.x", | ||
"http-auth": "2.4.x", | ||
"http-auth": "3.1.x", | ||
"morgan": "^1.6.1", | ||
@@ -27,9 +28,8 @@ "object-assign": "latest", | ||
"send": "latest", | ||
"serve-index": "^1.7.2", | ||
"watchr": "2.6.x" | ||
"serve-index": "^1.7.2" | ||
}, | ||
"devDependencies": { | ||
"mocha": "^2.3.3", | ||
"supertest": "^1.0.1", | ||
"eslint": "^2.8.0", | ||
"mocha": "^3.2.0", | ||
"supertest": "^2.0.1", | ||
"eslint": "^3.13.0", | ||
"jshint": "^2.9.2" | ||
@@ -36,0 +36,0 @@ }, |
@@ -50,11 +50,13 @@ [![view on npm](http://img.shields.io/npm/v/live-server.svg)](https://www.npmjs.org/package/live-server) | ||
* `--browser=BROWSER` - specify browser to use instead of system default | ||
* `--quiet` - suppress logging | ||
* `--quiet | -q` - suppress logging | ||
* `--verbose | -V` - more logging (logs all requests, shows all listening IPv4 interfaces, etc.) | ||
* `--open=PATH` - launch browser to PATH instead of server root | ||
* `--watch=PATH` - comma-separated string of paths to exclusively watch for changes (default: watch everything) | ||
* `--ignore=PATH` - comma-separated string of paths to ignore | ||
* `--ignorePattern=RGXP` - Regular expression of files to ignore (ie `.*\.jade`) | ||
* `--entry-file=PATH` - serve this file in place of missing files (useful for single page apps) | ||
* `--ignore=PATH` - comma-separated string of paths to ignore ([anymatch](https://github.com/es128/anymatch)-compatible definition) | ||
* `--ignorePattern=RGXP` - Regular expression of files to ignore (ie `.*\.jade`) (**DEPRECATED** in favor of `--ignore`) | ||
* `--middleware=PATH` - path to .js file exporting a middleware function to add; can be a name without path nor extension to reference bundled middlewares in `middleware` folder | ||
* `--entry-file=PATH` - serve this file (server root relative) in place of missing files (useful for single page apps) | ||
* `--mount=ROUTE:PATH` - serve the paths contents under the defined route (multiple definitions possible) | ||
* `--spa` - translate requests from /abc to /#/abc (handy for Single Page Apps) | ||
* `--wait=MILLISECONDS` - wait for all changes, before reloading | ||
* `--wait=MILLISECONDS` - (default 100ms) wait for all changes, before reloading | ||
* `--htpasswd=PATH` - Enables http-auth expecting htpasswd file located at PATH | ||
@@ -81,3 +83,3 @@ * `--cors` - Enables CORS for any origin (reflects request origin, requests with credentials are supported) | ||
host: "0.0.0.0", // Set the address to bind to. Defaults to 0.0.0.0 or process.env.IP. | ||
root: "/public", // Set root directory that's being server. Defaults to cwd. | ||
root: "/public", // Set root directory that's being served. Defaults to cwd. | ||
open: false, // When false, it won't load your browser by default. | ||
@@ -112,8 +114,15 @@ ignore: 'scss,my/templates', // comma-separated string for paths to ignore | ||
If using the node API, you can also directly pass a configuration object instead of a path to the module. | ||
Troubleshooting | ||
--------------- | ||
Open your browser's console: there should be a message at the top stating that live reload is enabled. Note that you will need a browser that supports WebSockets. If there are errors, deal with them. If it's still not working, [file an issue](https://github.com/tapio/live-server/issues). | ||
* No reload on changes | ||
* Open your browser's console: there should be a message at the top stating that live reload is enabled. Note that you will need a browser that supports WebSockets. If there are errors, deal with them. If it's still not working, [file an issue](https://github.com/tapio/live-server/issues). | ||
* Error: watch <PATH> ENOSPC | ||
* See [this suggested solution](http://stackoverflow.com/questions/22475849/node-js-error-enospc/32600959#32600959). | ||
* Reload works but changes are missing or outdated | ||
* Try using `--wait=MS` option. Where `MS` is time in milliseconds to wait before issuing a reload. | ||
How it works | ||
@@ -134,2 +143,15 @@ ------------ | ||
* v1.2.0 | ||
- Add `--middleware` parameter to use external middlewares | ||
- `middleware` API parameter now also accepts strings similar to `--middleware` | ||
- Changed file watcher to improve speed (@pavel) | ||
- `--ignore` now accepts regexps and globs, `--ignorePattern` deprecated (@pavel) | ||
- Added `--verbose` cli option (logLevel 3) (@pavel) | ||
- Logs all requests, displays warning when can't inject html file, displays all listening IPv4 interfaces... | ||
- HTTPS configuration now also accepts a plain object (@pavel) | ||
- Move `--spa` to a bundled middleware file | ||
- New bundled `spa-no-assets` middleware that works like `spa` but ignores requests with extension | ||
- Allow multiple `--open` arguments (@PirtleShell) | ||
- Inject to `head` if `body` not found (@pmd1991) | ||
- Update dependencies | ||
* v1.1.0 | ||
@@ -136,0 +158,0 @@ - Proxy support (@pavel) |
@@ -31,2 +31,9 @@ var request = require('supertest'); | ||
}); | ||
it('should inject to <head> when no <body>', function(done){ | ||
request(liveServer) | ||
.get('/index-head.html') | ||
.expect('Content-Type', 'text/html; charset=UTF-8') | ||
.expect(/<script [^]+?live reload enabled[^]+?<\/script>/i) | ||
.expect(200, done); | ||
}); | ||
it('should inject also svg files', function(done){ | ||
@@ -42,2 +49,12 @@ request(liveServer) | ||
}); | ||
it('should not inject html fragments', function(done){ | ||
request(liveServer) | ||
.get('/fragment.html') | ||
.expect('Content-Type', 'text/html; charset=UTF-8') | ||
.expect(function(res) { | ||
if (res.text.toString().indexOf("Live reload enabled") > -1) | ||
throw new Error("injected code should not be found"); | ||
}) | ||
.expect(200, done); | ||
}); | ||
xit('should have WebSocket connection', function(done){ | ||
@@ -44,0 +61,0 @@ done(); // todo |
var request = require('supertest'); | ||
var path = require('path'); | ||
var liveServer = require('..').start({ | ||
root: path.join(__dirname, 'data'), | ||
port: 0, | ||
open: false, | ||
https: path.join(__dirname, 'conf/https.conf.js') | ||
}); | ||
// accept self-signed certificates | ||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; | ||
describe('https tests', function() { | ||
function tests(liveServer) { | ||
it('should reply with a correct index file', function(done) { | ||
@@ -26,4 +20,30 @@ request(liveServer) | ||
}); | ||
} | ||
describe('https tests with external module', function() { | ||
var opts = { | ||
root: path.join(__dirname, 'data'), | ||
port: 0, | ||
open: false, | ||
https: path.join(__dirname, 'conf/https.conf.js') | ||
}; | ||
var liveServer = require("..").start(opts); | ||
tests(liveServer); | ||
after(function () { | ||
liveServer.close() | ||
}); | ||
}); | ||
describe('https tests with object', function() { | ||
var opts = { | ||
root: path.join(__dirname, 'data'), | ||
port: 0, | ||
open: false, | ||
https: require(path.join(__dirname, 'conf/https.conf.js')) | ||
}; | ||
var liveServer = require("..").start(opts); | ||
tests(liveServer); | ||
after(function () { | ||
liveServer.close() | ||
}); | ||
}); |
var request = require('supertest'); | ||
var path = require('path'); | ||
var liveServer = require('..').start({ | ||
var liveServer1 = require('..').start({ | ||
root: path.join(__dirname, 'data'), | ||
@@ -14,9 +14,31 @@ port: 0, | ||
}); | ||
var liveServer2 = require('..').start({ | ||
root: path.join(__dirname, 'data'), | ||
port: 0, | ||
open: false, | ||
middleware: [ "example" ] | ||
}); | ||
var liveServer3 = require('..').start({ | ||
root: path.join(__dirname, 'data'), | ||
port: 0, | ||
open: false, | ||
middleware: [ path.join(__dirname, 'data', 'middleware.js') ] | ||
}); | ||
describe('middleware tests', function() { | ||
it("should respond with middleware's status code", function(done) { | ||
request(liveServer) | ||
it("should respond with middleware function's status code", function(done) { | ||
request(liveServer1) | ||
.get('/') | ||
.expect(201, done); | ||
}); | ||
it("should respond with built-in middleware's status code", function(done) { | ||
request(liveServer2) | ||
.get('/') | ||
.expect(202, done); | ||
}); | ||
it("should respond with external middleware's status code", function(done) { | ||
request(liveServer3) | ||
.get('/') | ||
.expect(203, done); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
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
50103
33
929
255
11
+ Addedchokidar@^1.6.0
+ Addedanymatch@1.3.2(transitive)
+ Addedapache-crypt@1.2.6(transitive)
+ Addedapache-md5@1.1.8(transitive)
+ Addedarr-diff@2.0.04.0.0(transitive)
+ Addedarr-flatten@1.1.0(transitive)
+ Addedarr-union@3.1.0(transitive)
+ Addedarray-unique@0.2.10.3.2(transitive)
+ Addedassign-symbols@1.0.0(transitive)
+ Addedasync-each@1.0.6(transitive)
+ Addedatob@2.1.2(transitive)
+ Addedbase@0.11.2(transitive)
+ Addedbcryptjs@2.4.3(transitive)
+ Addedbinary-extensions@1.13.1(transitive)
+ Addedbindings@1.5.0(transitive)
+ Addedbraces@1.8.52.3.2(transitive)
+ Addedcache-base@1.0.1(transitive)
+ Addedchokidar@1.7.0(transitive)
+ Addedclass-utils@0.3.6(transitive)
+ Addedcollection-visit@1.0.0(transitive)
+ Addedcomponent-emitter@1.3.1(transitive)
+ Addedconnect@3.5.1(transitive)
+ Addedcopy-descriptor@0.1.1(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addeddecode-uri-component@0.2.2(transitive)
+ Addeddefine-property@0.2.51.0.02.0.2(transitive)
+ Addedexpand-brackets@0.1.52.1.4(transitive)
+ Addedexpand-range@1.8.2(transitive)
+ Addedextend-shallow@2.0.13.0.2(transitive)
+ Addedextglob@0.3.22.0.4(transitive)
+ Addedfile-uri-to-path@1.0.0(transitive)
+ Addedfilename-regex@2.0.1(transitive)
+ Addedfill-range@2.2.44.0.0(transitive)
+ Addedfinalhandler@0.5.1(transitive)
+ Addedfor-in@1.0.2(transitive)
+ Addedfor-own@0.1.5(transitive)
+ Addedfragment-cache@0.2.1(transitive)
+ Addedfsevents@1.2.13(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-value@2.0.6(transitive)
+ Addedglob-base@0.3.0(transitive)
+ Addedglob-parent@2.0.0(transitive)
+ Addedhas-value@0.3.11.0.0(transitive)
+ Addedhas-values@0.1.41.0.0(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedhttp-auth@3.1.3(transitive)
+ Addedis-accessor-descriptor@1.0.1(transitive)
+ Addedis-binary-path@1.0.1(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-data-descriptor@1.0.1(transitive)
+ Addedis-descriptor@0.1.71.0.3(transitive)
+ Addedis-dotfile@1.0.3(transitive)
+ Addedis-equal-shallow@0.1.3(transitive)
+ Addedis-extendable@0.1.11.0.1(transitive)
+ Addedis-extglob@1.0.0(transitive)
+ Addedis-glob@2.0.1(transitive)
+ Addedis-number@2.1.03.0.04.0.0(transitive)
+ Addedis-plain-object@2.0.4(transitive)
+ Addedis-posix-bracket@0.1.1(transitive)
+ Addedis-primitive@2.0.0(transitive)
+ Addedis-windows@1.0.2(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisobject@2.1.03.0.1(transitive)
+ Addedkind-of@3.2.24.0.06.0.3(transitive)
+ Addedmap-cache@0.2.2(transitive)
+ Addedmap-visit@1.0.0(transitive)
+ Addedmath-random@1.0.4(transitive)
+ Addedmicromatch@2.3.113.1.10(transitive)
+ Addedmixin-deep@1.3.2(transitive)
+ Addednan@2.20.0(transitive)
+ Addednanomatch@1.2.13(transitive)
+ Addednormalize-path@2.1.1(transitive)
+ Addedobject-copy@0.1.0(transitive)
+ Addedobject-visit@1.0.1(transitive)
+ Addedobject.omit@2.0.1(transitive)
+ Addedobject.pick@1.3.0(transitive)
+ Addedparse-glob@3.0.4(transitive)
+ Addedpascalcase@0.1.1(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedposix-character-classes@0.1.1(transitive)
+ Addedpreserve@0.2.0(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedrandomatic@3.1.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedreaddirp@2.2.1(transitive)
+ Addedregex-cache@0.4.4(transitive)
+ Addedregex-not@1.0.2(transitive)
+ Addedremove-trailing-separator@1.1.0(transitive)
+ Addedrepeat-element@1.1.4(transitive)
+ Addedrepeat-string@1.6.1(transitive)
+ Addedresolve-url@0.2.1(transitive)
+ Addedret@0.1.15(transitive)
+ Addedsafe-regex@1.1.0(transitive)
+ Addedset-value@2.0.1(transitive)
+ Addedsnapdragon@0.8.2(transitive)
+ Addedsnapdragon-node@2.1.1(transitive)
+ Addedsnapdragon-util@3.0.1(transitive)
+ Addedsource-map@0.5.7(transitive)
+ Addedsource-map-resolve@0.5.3(transitive)
+ Addedsource-map-url@0.4.1(transitive)
+ Addedsplit-string@3.1.0(transitive)
+ Addedstatic-extend@0.1.2(transitive)
+ Addedstatuses@1.3.1(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedto-object-path@0.3.0(transitive)
+ Addedto-regex@3.0.2(transitive)
+ Addedto-regex-range@2.1.1(transitive)
+ Addedunion-value@1.0.1(transitive)
+ Addedunset-value@1.0.0(transitive)
+ Addedurix@0.1.0(transitive)
+ Addeduse@3.1.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addeduuid@3.4.0(transitive)
- Removedwatchr@2.6.x
- Removedambi@2.5.03.2.0(transitive)
- Removedapache-crypt@1.1.2(transitive)
- Removedapache-md5@1.0.6(transitive)
- Removedconnect@3.4.1(transitive)
- Removedcsextends@1.2.0(transitive)
- Removedeachr@3.3.0(transitive)
- Removededitions@1.3.42.3.1(transitive)
- Removederrlop@2.2.0(transitive)
- Removedextendr@3.5.0(transitive)
- Removedextract-opts@3.4.0(transitive)
- Removedfinalhandler@0.4.1(transitive)
- Removedhttp-auth@2.4.11(transitive)
- Removedignorefs@1.4.1(transitive)
- Removedignorepatterns@1.4.0(transitive)
- Removednode-uuid@1.4.8(transitive)
- Removedsafefs@3.2.24.2.0(transitive)
- Removedsafeps@7.0.1(transitive)
- Removedscandirectory@2.5.0(transitive)
- Removedsemver@6.3.1(transitive)
- Removedtaskgroup@4.3.15.5.0(transitive)
- Removedtypechecker@4.11.0(transitive)
- Removedunbounded@1.3.0(transitive)
- Removedwatchr@2.6.0(transitive)
Updatedconnect@3.5.x
Updatedhttp-auth@3.1.x