express
Advanced tools
Comparing version 4.12.4 to 4.13.0
@@ -0,2 +1,11 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
module.exports = require('./lib/express'); |
@@ -9,9 +9,10 @@ /*! | ||
'use strict'; | ||
/** | ||
* Module dependencies. | ||
* @api private | ||
* @private | ||
*/ | ||
var finalhandler = require('finalhandler'); | ||
var flatten = require('./utils').flatten; | ||
var Router = require('./router'); | ||
@@ -28,2 +29,3 @@ var methods = require('methods'); | ||
var deprecate = require('depd')('express'); | ||
var flatten = require('array-flatten'); | ||
var merge = require('utils-merge'); | ||
@@ -41,3 +43,3 @@ var resolve = require('path').resolve; | ||
* Variable for trust proxy inheritance back-compat | ||
* @api private | ||
* @private | ||
*/ | ||
@@ -54,9 +56,10 @@ | ||
* | ||
* @api private | ||
* @private | ||
*/ | ||
app.init = function(){ | ||
app.init = function init() { | ||
this.cache = {}; | ||
this.engines = {}; | ||
this.settings = {}; | ||
this.engines = {}; | ||
this.defaultConfiguration(); | ||
@@ -67,11 +70,11 @@ }; | ||
* Initialize application configuration. | ||
* | ||
* @api private | ||
* @private | ||
*/ | ||
app.defaultConfiguration = function(){ | ||
app.defaultConfiguration = function defaultConfiguration() { | ||
var env = process.env.NODE_ENV || 'development'; | ||
// default settings | ||
this.enable('x-powered-by'); | ||
this.set('etag', 'weak'); | ||
var env = process.env.NODE_ENV || 'development'; | ||
this.set('env', env); | ||
@@ -136,5 +139,5 @@ this.set('query parser', 'extended'); | ||
* | ||
* @api private | ||
* @private | ||
*/ | ||
app.lazyrouter = function() { | ||
app.lazyrouter = function lazyrouter() { | ||
if (!this._router) { | ||
@@ -154,13 +157,13 @@ this._router = new Router({ | ||
* | ||
* If no _done_ callback is provided, then default error handlers will respond | ||
* If no callback is provided, then default error handlers will respond | ||
* in the event of an error bubbling through the stack. | ||
* | ||
* @api private | ||
* @private | ||
*/ | ||
app.handle = function(req, res, done) { | ||
app.handle = function handle(req, res, callback) { | ||
var router = this._router; | ||
// final handler | ||
done = done || finalhandler(req, res, { | ||
var done = callback || finalhandler(req, res, { | ||
env: this.get('env'), | ||
@@ -187,3 +190,3 @@ onerror: logerror.bind(this) | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -255,6 +258,6 @@ | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
app.route = function(path){ | ||
app.route = function route(path) { | ||
this.lazyrouter(); | ||
@@ -295,9 +298,18 @@ return this._router.route(path); | ||
* @return {app} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
app.engine = function(ext, fn){ | ||
if ('function' != typeof fn) throw new Error('callback function required'); | ||
if ('.' != ext[0]) ext = '.' + ext; | ||
this.engines[ext] = fn; | ||
app.engine = function engine(ext, fn) { | ||
if (typeof fn !== 'function') { | ||
throw new Error('callback function required'); | ||
} | ||
// get file extension | ||
var extension = ext[0] !== '.' | ||
? '.' + ext | ||
: ext; | ||
// store engine | ||
this.engines[extension] = fn; | ||
return this; | ||
@@ -315,12 +327,13 @@ }; | ||
* @return {app} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
app.param = function(name, fn){ | ||
app.param = function param(name, fn) { | ||
this.lazyrouter(); | ||
if (Array.isArray(name)) { | ||
name.forEach(function(key) { | ||
this.param(key, fn); | ||
}, this); | ||
for (var i = 0; i < name.length; i++) { | ||
this.param(name[i], fn); | ||
} | ||
return this; | ||
@@ -330,2 +343,3 @@ } | ||
this._router.param(name, fn); | ||
return this; | ||
@@ -346,6 +360,6 @@ }; | ||
* @return {Server} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
app.set = function(setting, val){ | ||
app.set = function set(setting, val) { | ||
if (arguments.length === 1) { | ||
@@ -356,2 +370,4 @@ // app.get(setting) | ||
debug('set "%s" to %o', setting, val); | ||
// set value | ||
@@ -363,11 +379,8 @@ this.settings[setting] = val; | ||
case 'etag': | ||
debug('compile etag %s', val); | ||
this.set('etag fn', compileETag(val)); | ||
break; | ||
case 'query parser': | ||
debug('compile query parser %s', val); | ||
this.set('query parser fn', compileQueryParser(val)); | ||
break; | ||
case 'trust proxy': | ||
debug('compile trust proxy %s', val); | ||
this.set('trust proxy fn', compileTrust(val)); | ||
@@ -398,6 +411,6 @@ | ||
* @return {String} | ||
* @api private | ||
* @private | ||
*/ | ||
app.path = function(){ | ||
app.path = function path() { | ||
return this.parent | ||
@@ -420,7 +433,7 @@ ? this.parent.path() + this.mountpath | ||
* @return {Boolean} | ||
* @api public | ||
* @public | ||
*/ | ||
app.enabled = function(setting){ | ||
return !!this.set(setting); | ||
app.enabled = function enabled(setting) { | ||
return Boolean(this.set(setting)); | ||
}; | ||
@@ -440,6 +453,6 @@ | ||
* @return {Boolean} | ||
* @api public | ||
* @public | ||
*/ | ||
app.disabled = function(setting){ | ||
app.disabled = function disabled(setting) { | ||
return !this.set(setting); | ||
@@ -453,6 +466,6 @@ }; | ||
* @return {app} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
app.enable = function(setting){ | ||
app.enable = function enable(setting) { | ||
return this.set(setting, true); | ||
@@ -466,6 +479,6 @@ }; | ||
* @return {app} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
app.disable = function(setting){ | ||
app.disable = function disable(setting) { | ||
return this.set(setting, false); | ||
@@ -480,3 +493,6 @@ }; | ||
app[method] = function(path){ | ||
if ('get' == method && 1 == arguments.length) return this.set(path); | ||
if (method === 'get' && arguments.length === 1) { | ||
// app.get(setting) | ||
return this.set(path); | ||
} | ||
@@ -498,6 +514,6 @@ this.lazyrouter(); | ||
* @return {app} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
app.all = function(path){ | ||
app.all = function all(path) { | ||
this.lazyrouter(); | ||
@@ -507,6 +523,7 @@ | ||
var args = slice.call(arguments, 1); | ||
methods.forEach(function(method){ | ||
route[method].apply(route, args); | ||
}); | ||
for (var i = 0; i < methods.length; i++) { | ||
route[methods[i]].apply(route, args); | ||
} | ||
return this; | ||
@@ -532,39 +549,46 @@ }; | ||
* @param {String|Function} options or fn | ||
* @param {Function} fn | ||
* @api public | ||
* @param {Function} callback | ||
* @public | ||
*/ | ||
app.render = function(name, options, fn){ | ||
var opts = {}; | ||
app.render = function render(name, options, callback) { | ||
var cache = this.cache; | ||
var done = callback; | ||
var engines = this.engines; | ||
var opts = options; | ||
var renderOptions = {}; | ||
var view; | ||
// support callback function as second arg | ||
if ('function' == typeof options) { | ||
fn = options, options = {}; | ||
if (typeof options === 'function') { | ||
done = options; | ||
opts = {}; | ||
} | ||
// merge app.locals | ||
merge(opts, this.locals); | ||
merge(renderOptions, this.locals); | ||
// merge options._locals | ||
if (options._locals) { | ||
merge(opts, options._locals); | ||
if (opts._locals) { | ||
merge(renderOptions, opts._locals); | ||
} | ||
// merge options | ||
merge(opts, options); | ||
merge(renderOptions, opts); | ||
// set .cache unless explicitly provided | ||
opts.cache = null == opts.cache | ||
? this.enabled('view cache') | ||
: opts.cache; | ||
if (renderOptions.cache == null) { | ||
renderOptions.cache = this.enabled('view cache'); | ||
} | ||
// primed cache | ||
if (opts.cache) view = cache[name]; | ||
if (renderOptions.cache) { | ||
view = cache[name]; | ||
} | ||
// view | ||
if (!view) { | ||
view = new (this.get('view'))(name, { | ||
var View = this.get('view'); | ||
view = new View(name, { | ||
defaultEngine: this.get('view engine'), | ||
@@ -581,15 +605,13 @@ root: this.get('views'), | ||
err.view = view; | ||
return fn(err); | ||
return done(err); | ||
} | ||
// prime the cache | ||
if (opts.cache) cache[name] = view; | ||
if (renderOptions.cache) { | ||
cache[name] = view; | ||
} | ||
} | ||
// render | ||
try { | ||
view.render(opts, fn); | ||
} catch (err) { | ||
fn(err); | ||
} | ||
tryRender(view, renderOptions, done); | ||
}; | ||
@@ -615,6 +637,6 @@ | ||
* @return {http.Server} | ||
* @api public | ||
* @public | ||
*/ | ||
app.listen = function(){ | ||
app.listen = function listen() { | ||
var server = http.createServer(this); | ||
@@ -625,10 +647,24 @@ return server.listen.apply(server, arguments); | ||
/** | ||
* Log error using console.error. | ||
* | ||
* @param {Error} err | ||
* @api private | ||
*/ | ||
* Log error using console.error. | ||
* | ||
* @param {Error} err | ||
* @private | ||
*/ | ||
function logerror(err){ | ||
function logerror(err) { | ||
/* istanbul ignore next */ | ||
if (this.get('env') !== 'test') console.error(err.stack || err.toString()); | ||
} | ||
/** | ||
* Try rendering a view. | ||
* @private | ||
*/ | ||
function tryRender(view, options, callback) { | ||
try { | ||
view.render(options, callback); | ||
} catch (err) { | ||
callback(err); | ||
} | ||
} |
@@ -0,1 +1,11 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
@@ -2,0 +12,0 @@ * Module dependencies. |
@@ -0,1 +1,11 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
@@ -2,0 +12,0 @@ * Initialization middleware, exposing the |
@@ -0,1 +1,11 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
@@ -2,0 +12,0 @@ * Module dependencies. |
@@ -0,3 +1,14 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
* Module dependencies. | ||
* @private | ||
*/ | ||
@@ -44,8 +55,10 @@ | ||
* @return {String} | ||
* @api public | ||
* @public | ||
*/ | ||
req.get = | ||
req.header = function(name){ | ||
switch (name = name.toLowerCase()) { | ||
req.header = function header(name) { | ||
var lc = name.toLowerCase(); | ||
switch (lc) { | ||
case 'referer': | ||
@@ -56,3 +69,3 @@ case 'referrer': | ||
default: | ||
return this.headers[name]; | ||
return this.headers[lc]; | ||
} | ||
@@ -103,4 +116,4 @@ }; | ||
* @param {String|Array} type(s) | ||
* @return {String} | ||
* @api public | ||
* @return {String|Array|Boolean} | ||
* @public | ||
*/ | ||
@@ -117,4 +130,4 @@ | ||
* @param {String} ...encoding | ||
* @return {Boolean} | ||
* @api public | ||
* @return {String|Array} | ||
* @public | ||
*/ | ||
@@ -135,4 +148,4 @@ | ||
* @param {String} ...charset | ||
* @return {Boolean} | ||
* @api public | ||
* @return {String|Array} | ||
* @public | ||
*/ | ||
@@ -153,4 +166,4 @@ | ||
* @param {String} ...lang | ||
* @return {Boolean} | ||
* @api public | ||
* @return {String|Array} | ||
* @public | ||
*/ | ||
@@ -183,3 +196,3 @@ | ||
* @return {Array} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -207,3 +220,3 @@ | ||
* @return {String} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -249,10 +262,19 @@ | ||
* | ||
* @param {String} type | ||
* @return {Boolean} | ||
* @api public | ||
* @param {String|Array} types... | ||
* @return {String|false|null} | ||
* @public | ||
*/ | ||
req.is = function(types){ | ||
if (!Array.isArray(types)) types = [].slice.call(arguments); | ||
return typeis(this, types); | ||
req.is = function is(types) { | ||
var arr = types; | ||
// support flattened arguments | ||
if (!Array.isArray(types)) { | ||
arr = new Array(arguments.length); | ||
for (var i = 0; i < arr.length; i++) { | ||
arr[i] = arguments[i]; | ||
} | ||
} | ||
return typeis(this, arr); | ||
}; | ||
@@ -271,3 +293,3 @@ | ||
* @return {String} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -297,7 +319,7 @@ | ||
* @return {Boolean} | ||
* @api public | ||
* @public | ||
*/ | ||
defineGetter(req, 'secure', function secure(){ | ||
return 'https' == this.protocol; | ||
return this.protocol === 'https'; | ||
}); | ||
@@ -312,3 +334,3 @@ | ||
* @return {String} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -330,3 +352,3 @@ | ||
* @return {Array} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -352,3 +374,3 @@ | ||
* @return {Array} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -373,3 +395,3 @@ | ||
* @return {String} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -389,3 +411,3 @@ | ||
* @return {String} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -409,3 +431,3 @@ | ||
return ~index | ||
return index !== -1 | ||
? host.substring(0, index) | ||
@@ -427,3 +449,3 @@ : host; | ||
* @return {Boolean} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -452,3 +474,3 @@ | ||
* @return {Boolean} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -464,3 +486,3 @@ | ||
* @return {Boolean} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -470,3 +492,3 @@ | ||
var val = this.get('X-Requested-With') || ''; | ||
return 'xmlhttprequest' == val.toLowerCase(); | ||
return val.toLowerCase() === 'xmlhttprequest'; | ||
}); | ||
@@ -480,3 +502,3 @@ | ||
* @param {Function} getter | ||
* @api private | ||
* @private | ||
*/ | ||
@@ -483,0 +505,0 @@ function defineGetter(obj, name, getter) { |
@@ -8,5 +8,7 @@ /*! | ||
'use strict'; | ||
/** | ||
* Module dependencies. | ||
* @api private | ||
* @private | ||
*/ | ||
@@ -43,2 +45,9 @@ | ||
/** | ||
* Module variables. | ||
* @private | ||
*/ | ||
var charsetRegExp = /;\s*charset\s*=/; | ||
/** | ||
* Set status `code`. | ||
@@ -48,6 +57,6 @@ * | ||
* @return {ServerResponse} | ||
* @api public | ||
* @public | ||
*/ | ||
res.status = function(code){ | ||
res.status = function status(code) { | ||
this.statusCode = code; | ||
@@ -69,3 +78,3 @@ return this; | ||
* @return {ServerResponse} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -91,3 +100,3 @@ | ||
* @param {string|number|boolean|object|Buffer} body | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -127,3 +136,3 @@ | ||
this.statusCode = chunk; | ||
chunk = http.STATUS_CODES[chunk]; | ||
chunk = statusCodes[chunk]; | ||
} | ||
@@ -216,3 +225,3 @@ | ||
* @param {string|number|boolean|object} obj | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -259,3 +268,3 @@ | ||
* @param {string|number|boolean|object} obj | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -331,7 +340,7 @@ | ||
* @param {number} statusCode | ||
* @api public | ||
* @public | ||
*/ | ||
res.sendStatus = function sendStatus(statusCode) { | ||
var body = http.STATUS_CODES[statusCode] || String(statusCode); | ||
var body = statusCodes[statusCode] || String(statusCode); | ||
@@ -348,3 +357,3 @@ this.statusCode = statusCode; | ||
* Automatically sets the _Content-Type_ response header field. | ||
* The callback `fn(err)` is invoked when the transfer is complete | ||
* The callback `callback(err)` is invoked when the transfer is complete | ||
* or when an error occurs. Be sure to check `res.sentHeader` | ||
@@ -383,9 +392,11 @@ * if you wish to attempt responding, as the header and some data | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
res.sendFile = function sendFile(path, options, fn) { | ||
res.sendFile = function sendFile(path, options, callback) { | ||
var done = callback; | ||
var req = this.req; | ||
var res = this; | ||
var next = req.next; | ||
var opts = options || {}; | ||
@@ -398,9 +409,7 @@ if (!path) { | ||
if (typeof options === 'function') { | ||
fn = options; | ||
options = {}; | ||
done = options; | ||
opts = {}; | ||
} | ||
options = options || {}; | ||
if (!options.root && !isAbsolute(path)) { | ||
if (!opts.root && !isAbsolute(path)) { | ||
throw new TypeError('path must be absolute or specify root to res.sendFile'); | ||
@@ -411,7 +420,7 @@ } | ||
var pathname = encodeURI(path); | ||
var file = send(req, pathname, options); | ||
var file = send(req, pathname, opts); | ||
// transfer | ||
sendfile(res, file, options, function (err) { | ||
if (fn) return fn(err); | ||
sendfile(res, file, opts, function (err) { | ||
if (done) return done(err); | ||
if (err && err.code === 'EISDIR') return next(); | ||
@@ -430,3 +439,3 @@ | ||
* Automatically sets the _Content-Type_ response header field. | ||
* The callback `fn(err)` is invoked when the transfer is complete | ||
* The callback `callback(err)` is invoked when the transfer is complete | ||
* or when an error occurs. Be sure to check `res.sentHeader` | ||
@@ -465,24 +474,24 @@ * if you wish to attempt responding, as the header and some data | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
res.sendfile = function(path, options, fn){ | ||
res.sendfile = function (path, options, callback) { | ||
var done = callback; | ||
var req = this.req; | ||
var res = this; | ||
var next = req.next; | ||
var opts = options || {}; | ||
// support function as second arg | ||
if (typeof options === 'function') { | ||
fn = options; | ||
options = {}; | ||
done = options; | ||
opts = {}; | ||
} | ||
options = options || {}; | ||
// create file stream | ||
var file = send(req, path, options); | ||
var file = send(req, path, opts); | ||
// transfer | ||
sendfile(res, file, options, function (err) { | ||
if (fn) return fn(err); | ||
sendfile(res, file, opts, function (err) { | ||
if (done) return done(err); | ||
if (err && err.code === 'EISDIR') return next(); | ||
@@ -504,3 +513,3 @@ | ||
* Optionally providing an alternate attachment `filename`, | ||
* and optional callback `fn(err)`. The callback is invoked | ||
* and optional callback `callback(err)`. The callback is invoked | ||
* when the data transfer is complete, or when an error has | ||
@@ -511,17 +520,18 @@ * ocurred. Be sure to check `res.headersSent` if you plan to respond. | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
res.download = function download(path, filename, fn) { | ||
res.download = function download(path, filename, callback) { | ||
var done = callback; | ||
var name = filename; | ||
// support function as second arg | ||
if (typeof filename === 'function') { | ||
fn = filename; | ||
filename = null; | ||
done = filename; | ||
name = null; | ||
} | ||
filename = filename || path; | ||
// set Content-Disposition when file is sent | ||
var headers = { | ||
'Content-Disposition': contentDisposition(filename) | ||
'Content-Disposition': contentDisposition(name || path) | ||
}; | ||
@@ -532,3 +542,3 @@ | ||
return this.sendFile(fullPath, { headers: headers }, fn); | ||
return this.sendFile(fullPath, { headers: headers }, done); | ||
}; | ||
@@ -550,10 +560,12 @@ | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
res.contentType = | ||
res.type = function(type){ | ||
return this.set('Content-Type', ~type.indexOf('/') | ||
? type | ||
: mime.lookup(type)); | ||
res.type = function contentType(type) { | ||
var ct = type.indexOf('/') === -1 | ||
? mime.lookup(type) | ||
: type; | ||
return this.set('Content-Type', ct); | ||
}; | ||
@@ -615,3 +627,3 @@ | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -627,3 +639,5 @@ | ||
var key = req.accepts(keys); | ||
var key = keys.length > 0 | ||
? req.accepts(keys) | ||
: false; | ||
@@ -639,3 +653,3 @@ this.vary("Accept"); | ||
var err = new Error('Not Acceptable'); | ||
err.status = 406; | ||
err.status = err.statusCode = 406; | ||
err.types = normalizeTypes(keys).map(function(o){ return o.value }); | ||
@@ -653,3 +667,3 @@ next(err); | ||
* @return {ServerResponse} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -679,3 +693,3 @@ | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -709,6 +723,6 @@ | ||
* | ||
* @param {String|Object|Array} field | ||
* @param {String} val | ||
* @param {String|Object} field | ||
* @param {String|Array} val | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -719,9 +733,13 @@ | ||
if (arguments.length === 2) { | ||
if (Array.isArray(val)) val = val.map(String); | ||
else val = String(val); | ||
if ('content-type' == field.toLowerCase() && !/;\s*charset\s*=/.test(val)) { | ||
var charset = mime.charsets.lookup(val.split(';')[0]); | ||
if (charset) val += '; charset=' + charset.toLowerCase(); | ||
var value = Array.isArray(val) | ||
? val.map(String) | ||
: String(val); | ||
// add charset to content-type | ||
if (field.toLowerCase() === 'content-type' && !charsetRegExp.test(value)) { | ||
var charset = mime.charsets.lookup(value.split(';')[0]); | ||
if (charset) value += '; charset=' + charset.toLowerCase(); | ||
} | ||
this.setHeader(field, val); | ||
this.setHeader(field, value); | ||
} else { | ||
@@ -740,3 +758,3 @@ for (var key in field) { | ||
* @return {String} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -754,14 +772,13 @@ | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
res.clearCookie = function(name, options){ | ||
var opts = { expires: new Date(1), path: '/' }; | ||
return this.cookie(name, '', options | ||
? merge(opts, options) | ||
: opts); | ||
res.clearCookie = function clearCookie(name, options) { | ||
var opts = merge({ expires: new Date(1), path: '/' }, options); | ||
return this.cookie(name, '', opts); | ||
}; | ||
/** | ||
* Set cookie `name` to `val`, with the given `options`. | ||
* Set cookie `name` to `value`, with the given `options`. | ||
* | ||
@@ -783,37 +800,39 @@ * Options: | ||
* @param {String} name | ||
* @param {String|Object} val | ||
* @param {String|Object} value | ||
* @param {Options} options | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
res.cookie = function(name, val, options){ | ||
options = merge({}, options); | ||
res.cookie = function (name, value, options) { | ||
var opts = merge({}, options); | ||
var secret = this.req.secret; | ||
var signed = options.signed; | ||
if (signed && !secret) throw new Error('cookieParser("secret") required for signed cookies'); | ||
if ('number' == typeof val) val = val.toString(); | ||
if ('object' == typeof val) val = 'j:' + JSON.stringify(val); | ||
if (signed) val = 's:' + sign(val, secret); | ||
if ('maxAge' in options) { | ||
options.expires = new Date(Date.now() + options.maxAge); | ||
options.maxAge /= 1000; | ||
var signed = opts.signed; | ||
if (signed && !secret) { | ||
throw new Error('cookieParser("secret") required for signed cookies'); | ||
} | ||
if (null == options.path) options.path = '/'; | ||
var headerVal = cookie.serialize(name, String(val), options); | ||
// supports multiple 'res.cookie' calls by getting previous value | ||
var prev = this.get('Set-Cookie'); | ||
if (prev) { | ||
if (Array.isArray(prev)) { | ||
headerVal = prev.concat(headerVal); | ||
} else { | ||
headerVal = [prev, headerVal]; | ||
} | ||
var val = typeof value === 'object' | ||
? 'j:' + JSON.stringify(value) | ||
: String(value); | ||
if (signed) { | ||
val = 's:' + sign(val, secret); | ||
} | ||
this.set('Set-Cookie', headerVal); | ||
if ('maxAge' in opts) { | ||
opts.expires = new Date(Date.now() + opts.maxAge); | ||
opts.maxAge /= 1000; | ||
} | ||
if (opts.path == null) { | ||
opts.path = '/'; | ||
} | ||
this.append('Set-Cookie', cookie.serialize(name, String(val), opts)); | ||
return this; | ||
}; | ||
/** | ||
@@ -833,13 +852,15 @@ * Set the location header to `url`. | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
res.location = function(url){ | ||
var req = this.req; | ||
res.location = function location(url) { | ||
var loc = url; | ||
// "back" is an alias for the referrer | ||
if ('back' == url) url = req.get('Referrer') || '/'; | ||
if (url === 'back') { | ||
loc = this.req.get('Referrer') || '/'; | ||
} | ||
// Respond | ||
this.set('Location', url); | ||
// set location | ||
this.set('Location', loc); | ||
return this; | ||
@@ -863,3 +884,3 @@ }; | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -920,3 +941,3 @@ | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -946,21 +967,23 @@ | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
res.render = function(view, options, fn){ | ||
options = options || {}; | ||
res.render = function render(view, options, callback) { | ||
var app = this.req.app; | ||
var done = callback; | ||
var opts = options || {}; | ||
var req = this.req; | ||
var self = this; | ||
var req = this.req; | ||
var app = req.app; | ||
// support callback function as second arg | ||
if ('function' == typeof options) { | ||
fn = options, options = {}; | ||
if (typeof options === 'function') { | ||
done = options; | ||
opts = {}; | ||
} | ||
// merge res.locals | ||
options._locals = self.locals; | ||
opts._locals = self.locals; | ||
// default callback to respond | ||
fn = fn || function(err, str){ | ||
done = done || function (err, str) { | ||
if (err) return req.next(err); | ||
@@ -971,3 +994,3 @@ self.send(str); | ||
// render | ||
app.render(view, options, fn); | ||
app.render(view, opts, done); | ||
}; | ||
@@ -974,0 +997,0 @@ |
@@ -0,4 +1,14 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
* Module dependencies. | ||
* @private | ||
*/ | ||
@@ -12,7 +22,8 @@ | ||
var deprecate = require('depd')('express'); | ||
var flatten = require('array-flatten'); | ||
var parseUrl = require('parseurl'); | ||
var utils = require('../utils'); | ||
/** | ||
* Module variables. | ||
* @private | ||
*/ | ||
@@ -29,7 +40,7 @@ | ||
* @return {Router} which is an callable function | ||
* @api public | ||
* @public | ||
*/ | ||
var proto = module.exports = function(options) { | ||
options = options || {}; | ||
var opts = options || {}; | ||
@@ -45,5 +56,5 @@ function router(req, res, next) { | ||
router._params = []; | ||
router.caseSensitive = options.caseSensitive; | ||
router.mergeParams = options.mergeParams; | ||
router.strict = options.strict; | ||
router.caseSensitive = opts.caseSensitive; | ||
router.mergeParams = opts.mergeParams; | ||
router.strict = opts.strict; | ||
router.stack = []; | ||
@@ -85,3 +96,3 @@ | ||
* @return {app} for chaining | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -125,7 +136,6 @@ | ||
* Dispatch a req, res into the router. | ||
* | ||
* @api private | ||
* @private | ||
*/ | ||
proto.handle = function(req, res, done) { | ||
proto.handle = function handle(req, res, out) { | ||
var self = this; | ||
@@ -154,3 +164,3 @@ | ||
var parentUrl = req.baseUrl || ''; | ||
done = restore(done, req, 'baseUrl', 'next', 'params'); | ||
var done = restore(out, req, 'baseUrl', 'next', 'params'); | ||
@@ -315,7 +325,6 @@ // setup next layer | ||
* Process any parameters for the layer. | ||
* | ||
* @api private | ||
* @private | ||
*/ | ||
proto.process_params = function(layer, called, req, res, done) { | ||
proto.process_params = function process_params(layer, called, req, res, done) { | ||
var params = this.params; | ||
@@ -367,3 +376,4 @@ | ||
// param previously called with same value or error occurred | ||
if (paramCalled && (paramCalled.error || paramCalled.match === paramVal)) { | ||
if (paramCalled && (paramCalled.match === paramVal | ||
|| (paramCalled.error && paramCalled.error !== 'route'))) { | ||
// restore value | ||
@@ -423,3 +433,3 @@ req.params[name] = paramCalled.value; | ||
* | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -447,3 +457,3 @@ | ||
var callbacks = utils.flatten(slice.call(arguments, offset)); | ||
var callbacks = flatten(slice.call(arguments, offset)); | ||
@@ -454,3 +464,5 @@ if (callbacks.length === 0) { | ||
callbacks.forEach(function (fn) { | ||
for (var i = 0; i < callbacks.length; i++) { | ||
var fn = callbacks[i]; | ||
if (typeof fn !== 'function') { | ||
@@ -472,3 +484,3 @@ throw new TypeError('Router.use() requires middleware function but got a ' + gettype(fn)); | ||
this.stack.push(layer); | ||
}, this); | ||
} | ||
@@ -488,6 +500,6 @@ return this; | ||
* @return {Route} | ||
* @api public | ||
* @public | ||
*/ | ||
proto.route = function(path){ | ||
proto.route = function route(path) { | ||
var route = new Route(path); | ||
@@ -494,0 +506,0 @@ |
@@ -0,3 +1,14 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
* Module dependencies. | ||
* @private | ||
*/ | ||
@@ -10,2 +21,3 @@ | ||
* Module variables. | ||
* @private | ||
*/ | ||
@@ -16,3 +28,4 @@ | ||
/** | ||
* Expose `Layer`. | ||
* Module exports. | ||
* @public | ||
*/ | ||
@@ -28,3 +41,3 @@ | ||
debug('new %s', path); | ||
options = options || {}; | ||
var opts = options || {}; | ||
@@ -35,5 +48,5 @@ this.handle = fn; | ||
this.path = undefined; | ||
this.regexp = pathRegexp(path, this.keys = [], options); | ||
this.regexp = pathRegexp(path, this.keys = [], opts); | ||
if (path === '/' && options.end === false) { | ||
if (path === '/' && opts.end === false) { | ||
this.regexp.fast_slash = true; | ||
@@ -130,13 +143,7 @@ } | ||
var params = this.params; | ||
var prop; | ||
var n = 0; | ||
var key; | ||
var val; | ||
for (var i = 1, len = m.length; i < len; ++i) { | ||
key = keys[i - 1]; | ||
prop = key | ||
? key.name | ||
: n++; | ||
val = decode_param(m[i]); | ||
for (var i = 1; i < m.length; i++) { | ||
var key = keys[i - 1]; | ||
var prop = key.name; | ||
var val = decode_param(m[i]); | ||
@@ -156,7 +163,7 @@ if (val !== undefined || !(hasOwnProperty.call(params, prop))) { | ||
* @return {string} | ||
* @api private | ||
* @private | ||
*/ | ||
function decode_param(val){ | ||
if (typeof val !== 'string') { | ||
function decode_param(val) { | ||
if (typeof val !== 'string' || val.length === 0) { | ||
return val; | ||
@@ -167,7 +174,10 @@ } | ||
return decodeURIComponent(val); | ||
} catch (e) { | ||
var err = new TypeError("Failed to decode param '" + val + "'"); | ||
err.status = 400; | ||
} catch (err) { | ||
if (err instanceof URIError) { | ||
err.message = 'Failed to decode param \'' + val + '\''; | ||
err.status = err.statusCode = 400; | ||
} | ||
throw err; | ||
} | ||
} |
@@ -0,14 +1,34 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
* Module dependencies. | ||
* @private | ||
*/ | ||
var debug = require('debug')('express:router:route'); | ||
var flatten = require('array-flatten'); | ||
var Layer = require('./layer'); | ||
var methods = require('methods'); | ||
var utils = require('../utils'); | ||
/** | ||
* Expose `Route`. | ||
* Module variables. | ||
* @private | ||
*/ | ||
var slice = Array.prototype.slice; | ||
var toString = Object.prototype.toString; | ||
/** | ||
* Module exports. | ||
* @public | ||
*/ | ||
module.exports = Route; | ||
@@ -20,10 +40,11 @@ | ||
* @param {String} path | ||
* @api private | ||
* @public | ||
*/ | ||
function Route(path) { | ||
debug('new %s', path); | ||
this.path = path; | ||
this.stack = []; | ||
debug('new %s', path); | ||
// route handlers for various http methods | ||
@@ -34,3 +55,4 @@ this.methods = {}; | ||
/** | ||
* @api private | ||
* Determine if the route handles a given method. | ||
* @private | ||
*/ | ||
@@ -43,9 +65,9 @@ | ||
method = method.toLowerCase(); | ||
var name = method.toLowerCase(); | ||
if (method === 'head' && !this.methods['head']) { | ||
method = 'get'; | ||
if (name === 'head' && !this.methods['head']) { | ||
name = 'get'; | ||
} | ||
return Boolean(this.methods[method]); | ||
return Boolean(this.methods[name]); | ||
}; | ||
@@ -55,3 +77,3 @@ | ||
* @return {Array} supported HTTP methods | ||
* @api private | ||
* @private | ||
*/ | ||
@@ -77,7 +99,6 @@ | ||
* dispatch req, res into this route | ||
* | ||
* @api private | ||
* @private | ||
*/ | ||
Route.prototype.dispatch = function(req, res, done){ | ||
Route.prototype.dispatch = function dispatch(req, res, done) { | ||
var idx = 0; | ||
@@ -148,12 +169,15 @@ var stack = this.stack; | ||
Route.prototype.all = function(){ | ||
var callbacks = utils.flatten([].slice.call(arguments)); | ||
callbacks.forEach(function(fn) { | ||
if (typeof fn !== 'function') { | ||
var type = {}.toString.call(fn); | ||
Route.prototype.all = function all() { | ||
var handles = flatten(slice.call(arguments)); | ||
for (var i = 0; i < handles.length; i++) { | ||
var handle = handles[i]; | ||
if (typeof handle !== 'function') { | ||
var type = toString.call(handle); | ||
var msg = 'Route.all() requires callback functions but got a ' + type; | ||
throw new Error(msg); | ||
throw new TypeError(msg); | ||
} | ||
var layer = Layer('/', {}, fn); | ||
var layer = Layer('/', {}, handle); | ||
layer.method = undefined; | ||
@@ -163,3 +187,3 @@ | ||
this.stack.push(layer); | ||
}, this); | ||
} | ||
@@ -171,7 +195,9 @@ return this; | ||
Route.prototype[method] = function(){ | ||
var callbacks = utils.flatten([].slice.call(arguments)); | ||
var handles = flatten(slice.call(arguments)); | ||
callbacks.forEach(function(fn) { | ||
if (typeof fn !== 'function') { | ||
var type = {}.toString.call(fn); | ||
for (var i = 0; i < handles.length; i++) { | ||
var handle = handles[i]; | ||
if (typeof handle !== 'function') { | ||
var type = toString.call(handle); | ||
var msg = 'Route.' + method + '() requires callback functions but got a ' + type; | ||
@@ -183,3 +209,3 @@ throw new Error(msg); | ||
var layer = Layer('/', {}, fn); | ||
var layer = Layer('/', {}, handle); | ||
layer.method = method; | ||
@@ -189,5 +215,6 @@ | ||
this.stack.push(layer); | ||
}, this); | ||
} | ||
return this; | ||
}; | ||
}); |
@@ -8,2 +8,4 @@ /*! | ||
'use strict'; | ||
/** | ||
@@ -17,2 +19,3 @@ * Module dependencies. | ||
var deprecate = require('depd')('express'); | ||
var flatten = require('array-flatten'); | ||
var mime = require('send').mime; | ||
@@ -81,14 +84,4 @@ var basename = require('path').basename; | ||
exports.flatten = function(arr, ret){ | ||
ret = ret || []; | ||
var len = arr.length; | ||
for (var i = 0; i < len; ++i) { | ||
if (Array.isArray(arr[i])) { | ||
exports.flatten(arr[i], ret); | ||
} else { | ||
ret.push(arr[i]); | ||
} | ||
} | ||
return ret; | ||
}; | ||
exports.flatten = deprecate.function(flatten, | ||
'utils.flatten: use array-flatten npm module instead'); | ||
@@ -95,0 +88,0 @@ /** |
@@ -0,3 +1,14 @@ | ||
/*! | ||
* express | ||
* Copyright(c) 2009-2013 TJ Holowaychuk | ||
* Copyright(c) 2013 Roman Shtylman | ||
* Copyright(c) 2014-2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
'use strict'; | ||
/** | ||
* Module dependencies. | ||
* @private | ||
*/ | ||
@@ -22,3 +33,4 @@ | ||
/** | ||
* Expose `View`. | ||
* Module exports. | ||
* @public | ||
*/ | ||
@@ -37,18 +49,40 @@ | ||
* | ||
* @param {String} name | ||
* @param {Object} options | ||
* @api private | ||
* @param {string} name | ||
* @param {object} options | ||
* @public | ||
*/ | ||
function View(name, options) { | ||
options = options || {}; | ||
var opts = options || {}; | ||
this.defaultEngine = opts.defaultEngine; | ||
this.ext = extname(name); | ||
this.name = name; | ||
this.root = options.root; | ||
var engines = options.engines; | ||
this.defaultEngine = options.defaultEngine; | ||
var ext = this.ext = extname(name); | ||
if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.'); | ||
if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine); | ||
this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express); | ||
this.path = this.lookup(name); | ||
this.root = opts.root; | ||
if (!this.ext && !this.defaultEngine) { | ||
throw new Error('No default engine was specified and no extension was provided.'); | ||
} | ||
var fileName = name; | ||
if (!this.ext) { | ||
// get extension from default engine name | ||
this.ext = this.defaultEngine[0] !== '.' | ||
? '.' + this.defaultEngine | ||
: this.defaultEngine; | ||
fileName += this.ext; | ||
} | ||
if (!opts.engines[this.ext]) { | ||
// load engine | ||
opts.engines[this.ext] = require(this.ext.substr(1)).__express; | ||
} | ||
// store loaded engine | ||
this.engine = opts.engines[this.ext]; | ||
// lookup path | ||
this.path = this.lookup(fileName); | ||
} | ||
@@ -59,5 +93,4 @@ | ||
* | ||
* @param {String} name | ||
* @return {String} | ||
* @api private | ||
* @param {string} name | ||
* @private | ||
*/ | ||
@@ -87,12 +120,12 @@ | ||
/** | ||
* Render with the given `options` and callback `fn(err, str)`. | ||
* Render with the given options. | ||
* | ||
* @param {Object} options | ||
* @param {Function} fn | ||
* @api private | ||
* @param {object} options | ||
* @param {function} callback | ||
* @private | ||
*/ | ||
View.prototype.render = function render(options, fn) { | ||
View.prototype.render = function render(options, callback) { | ||
debug('render "%s"', this.path); | ||
this.engine(this.path, options, fn); | ||
this.engine(this.path, options, callback); | ||
}; | ||
@@ -110,8 +143,6 @@ | ||
var ext = this.ext; | ||
var path; | ||
var stat; | ||
// <path>.<ext> | ||
path = join(dir, file); | ||
stat = tryStat(path); | ||
var path = join(dir, file); | ||
var stat = tryStat(path); | ||
@@ -118,0 +149,0 @@ if (stat && stat.isFile()) { |
{ | ||
"name": "express", | ||
"description": "Fast, unopinionated, minimalist web framework", | ||
"version": "4.12.4", | ||
"version": "4.13.0", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
@@ -30,24 +30,25 @@ "contributors": [ | ||
"dependencies": { | ||
"accepts": "~1.2.7", | ||
"accepts": "~1.2.9", | ||
"array-flatten": "1.1.0", | ||
"content-disposition": "0.5.0", | ||
"content-type": "~1.0.1", | ||
"cookie": "0.1.2", | ||
"cookie": "0.1.3", | ||
"cookie-signature": "1.0.6", | ||
"debug": "~2.2.0", | ||
"depd": "~1.0.1", | ||
"escape-html": "1.0.1", | ||
"etag": "~1.6.0", | ||
"finalhandler": "0.3.6", | ||
"fresh": "0.2.4", | ||
"escape-html": "1.0.2", | ||
"etag": "~1.7.0", | ||
"finalhandler": "0.4.0", | ||
"fresh": "0.3.0", | ||
"merge-descriptors": "1.0.0", | ||
"methods": "~1.1.1", | ||
"on-finished": "~2.2.1", | ||
"on-finished": "~2.3.0", | ||
"parseurl": "~1.3.0", | ||
"path-to-regexp": "0.1.3", | ||
"path-to-regexp": "0.1.6", | ||
"proxy-addr": "~1.0.8", | ||
"qs": "2.4.2", | ||
"range-parser": "~1.0.2", | ||
"send": "0.12.3", | ||
"serve-static": "~1.9.3", | ||
"type-is": "~1.6.2", | ||
"send": "0.13.0", | ||
"serve-static": "~1.10.0", | ||
"type-is": "~1.6.3", | ||
"vary": "~1.0.0", | ||
@@ -62,12 +63,12 @@ "utils-merge": "1.0.0" | ||
"mocha": "2.2.5", | ||
"should": "6.0.1", | ||
"should": "7.0.1", | ||
"supertest": "1.0.1", | ||
"body-parser": "~1.12.4", | ||
"body-parser": "~1.13.1", | ||
"connect-redis": "~2.3.0", | ||
"cookie-parser": "~1.3.4", | ||
"cookie-parser": "~1.3.5", | ||
"cookie-session": "~1.1.0", | ||
"express-session": "~1.11.2", | ||
"jade": "~1.9.2", | ||
"express-session": "~1.11.3", | ||
"jade": "~1.11.0", | ||
"method-override": "~2.3.3", | ||
"morgan": "~1.5.3", | ||
"morgan": "~1.6.0", | ||
"multiparty": "~4.1.2", | ||
@@ -74,0 +75,0 @@ "vhost": "~3.0.0" |
Sorry, the diff of this file is too big to display
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
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
185012
3235
25
+ Addedarray-flatten@1.1.0
+ Addedarray-flatten@1.1.0(transitive)
+ Addedcookie@0.1.3(transitive)
+ Addeddepd@1.1.2(transitive)
+ Addeddestroy@1.0.4(transitive)
+ Addedee-first@1.1.1(transitive)
+ Addedescape-html@1.0.21.0.3(transitive)
+ Addedetag@1.7.0(transitive)
+ Addedfinalhandler@0.4.0(transitive)
+ Addedfresh@0.3.0(transitive)
+ Addedhttp-errors@1.3.1(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedon-finished@2.3.0(transitive)
+ Addedpath-to-regexp@0.1.6(transitive)
+ Addedsend@0.13.00.13.2(transitive)
+ Addedserve-static@1.10.3(transitive)
+ Addedstatuses@1.2.1(transitive)
+ Addedunpipe@1.0.0(transitive)
- Removedcookie@0.1.2(transitive)
- Removedcrc@3.2.1(transitive)
- Removedee-first@1.1.0(transitive)
- Removedescape-html@1.0.1(transitive)
- Removedetag@1.6.0(transitive)
- Removedfinalhandler@0.3.6(transitive)
- Removedfresh@0.2.4(transitive)
- Removedon-finished@2.2.1(transitive)
- Removedpath-to-regexp@0.1.3(transitive)
- Removedsend@0.12.3(transitive)
- Removedserve-static@1.9.3(transitive)
Updatedaccepts@~1.2.9
Updatedcookie@0.1.3
Updatedescape-html@1.0.2
Updatedetag@~1.7.0
Updatedfinalhandler@0.4.0
Updatedfresh@0.3.0
Updatedon-finished@~2.3.0
Updatedpath-to-regexp@0.1.6
Updatedsend@0.13.0
Updatedserve-static@~1.10.0
Updatedtype-is@~1.6.3