koa-better-error-handler
Advanced tools
Comparing version 3.0.1 to 3.0.3
@@ -1,1 +0,1 @@ | ||
{"processes":{"cda59ecf-3869-44a7-bb6f-25345e876788":{"parent":null,"children":["d48e8d1c-b1f4-4285-a78e-a8721177360c"]},"d48e8d1c-b1f4-4285-a78e-a8721177360c":{"parent":"cda59ecf-3869-44a7-bb6f-25345e876788","children":[]}},"files":{"/Users/jack/Projects/koa-better-error-handler/lib/index.js":["d48e8d1c-b1f4-4285-a78e-a8721177360c"]},"externalIds":{}} | ||
{"processes":{"ddb73522-3a22-4d09-a401-82c7e745339e":{"parent":null,"children":["f1b9c710-18d1-469d-921a-92f7b2ea9db5"]},"f1b9c710-18d1-469d-921a-92f7b2ea9db5":{"parent":"ddb73522-3a22-4d09-a401-82c7e745339e","children":[]}},"files":{"/Users/jack/Projects/koa-better-error-handler/lib/index.js":["f1b9c710-18d1-469d-921a-92f7b2ea9db5"]},"externalIds":{}} |
188
lib/index.js
@@ -1,4 +0,40 @@ | ||
'use strict'; | ||
"use strict"; | ||
// initialize try/catch error handling right away | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const Boom = require('@hapi/boom'); | ||
const Debug = require('debug'); | ||
const _ = require('lodash'); | ||
const capitalize = require('capitalize'); | ||
const camelCase = require('camelcase'); | ||
const co = require('co'); | ||
const humanize = require('humanize-string'); | ||
const statuses = require('statuses'); | ||
const toIdentifier = require('toidentifier'); | ||
const opts = { | ||
encoding: 'utf8' | ||
}; // error pages were inspired by HTML5 Boilerplate's default 404.html page | ||
// https://github.com/h5bp/html5-boilerplate/blob/master/src/404.html | ||
const _404 = fs.readFileSync(path.join(__dirname, '..', '404.html'), opts); | ||
const _500 = fs.readFileSync(path.join(__dirname, '..', '500.html'), opts); | ||
const debug = new Debug('koa-better-error-handler'); | ||
const passportLocalMongooseErrorNames = ['AuthenticationError', 'MissingPasswordError', 'AttemptTooSoonError', 'TooManyAttemptsError', 'NoSaltValueStoredError', 'IncorrectPasswordError', 'IncorrectUsernameError', 'MissingUsernameError', 'UserExistsError']; // initialize try/catch error handling right away | ||
// adapted from: https://github.com/koajs/onerror/blob/master/index.js | ||
@@ -10,10 +46,12 @@ // https://github.com/koajs/examples/issues/20#issuecomment-31568401 | ||
// https://goo.gl/8Z7aMe | ||
// eslint-disable-next-line complexity | ||
// eslint-disable-next-line complexity | ||
let errorHandler = (() => { | ||
var _ref = _asyncToGenerator(function* (err) { | ||
function errorHandler(_x) { | ||
return _errorHandler.apply(this, arguments); | ||
} | ||
function _errorHandler() { | ||
_errorHandler = _asyncToGenerator(function* (err) { | ||
if (!err) return; | ||
if (!_.isError(err)) err = new Error(err); | ||
const type = this.accepts(['text', 'json', 'html']); | ||
@@ -25,35 +63,30 @@ | ||
err.message = Boom.notAcceptable().output.payload; | ||
} | ||
} // parse mongoose validation errors | ||
// parse mongoose validation errors | ||
err = parseValidationError(this, err); | ||
// check if we threw just a status code in order to keep it simple | ||
err = parseValidationError(this, err); // check if we threw just a status code in order to keep it simple | ||
const val = parseInt(err.message, 10); | ||
if (_.isNumber(val) && val >= 400) err = Boom.create(val); | ||
if (_.isNumber(val) && val >= 400) err = Boom[camelCase(toIdentifier(statuses[val]))](); // check if we have a boom error that specified | ||
// a status code already for us (and then use it) | ||
// check if we have a boom error that specified | ||
// a status code already for us (and then use it) | ||
if (_.isObject(err.output) && _.isNumber(err.output.statusCode)) err.status = err.output.statusCode; | ||
if (!_.isNumber(err.status)) err.status = 500; // check if there is flash messaging | ||
if (!_.isNumber(err.status)) err.status = 500; | ||
// check if there is flash messaging | ||
const hasFlash = _.isFunction(this.flash); | ||
debug('hasFlash', hasFlash); | ||
// check if there is session support | ||
debug('hasFlash', hasFlash); // check if there is session support | ||
const hasSessions = _.isObject(this.session) && _.isObject(this.sessionStore) && _.isString(this.sessionId) && _.isObject(this.session) && _.isFunction(this.sessionStore.set); | ||
debug('hasSessions', hasSessions); | ||
// check if there is a view rendering engine binding `this.render` | ||
debug('hasSessions', hasSessions); // check if there is a view rendering engine binding `this.render` | ||
const hasRender = _.isFunction(this.render); | ||
debug('hasRender', hasRender); | ||
// check if we're about to go into a possible endless redirect loop | ||
const noReferrer = this.get('Referrer') === ''; | ||
debug('hasRender', hasRender); // check if we're about to go into a possible endless redirect loop | ||
// nothing we can do here other | ||
const noReferrer = this.get('Referrer') === ''; // nothing we can do here other | ||
// than delegate to the app-level | ||
// handler and log. | ||
if (this.headerSent || !this.writable) { | ||
@@ -63,6 +96,6 @@ debug('headers were already sent, returning early'); | ||
return; | ||
} | ||
} // populate the status and body with `boom` error message payload | ||
// (e.g. you can do `ctx.throw(404)` and it will output a beautiful err obj) | ||
// populate the status and body with `boom` error message payload | ||
// (e.g. you can do `ctx.throw(404)` and it will output a beautiful err obj) | ||
err.status = err.status || 500; | ||
@@ -72,13 +105,11 @@ err.statusCode = err.status; | ||
this.status = this.statusCode; | ||
this.body = Boom.create(err.status, err.message).output.payload; | ||
this.body = new Boom(err.message, { | ||
statusCode: err.status | ||
}).output.payload; // set any additional error headers specified | ||
// (e.g. for BasicAuth we use `basic-auth` which specifies WWW-Authenticate) | ||
// set any additional error headers specified | ||
// (e.g. for BasicAuth we use `basic-auth` which specifies WWW-Authenticate) | ||
if (_.isObject(err.headers) && Object.keys(err.headers).length > 0) this.set(err.headers); | ||
debug('status code was %d', this.status); | ||
this.app.emit('error', err, this); // fix page title and description | ||
this.app.emit('error', err, this); | ||
// fix page title and description | ||
this.state.meta = this.state.meta || {}; | ||
@@ -89,3 +120,2 @@ this.state.meta.title = this.body.error; | ||
debug('set `this.state.meta.desc` to %s', this.state.meta.description); | ||
debug('type was %s', type); | ||
@@ -115,8 +145,6 @@ | ||
// would endlessly rediret the user with `this.redirect('back')` | ||
if (noReferrer) debug('prevented endless redirect loop!'); | ||
if (noReferrer) debug('prevented endless redirect loop!'); // flash an error message | ||
// flash an error message | ||
if (hasFlash) this.flash('error', err.message); | ||
if (hasFlash) this.flash('error', err.message); // render the 500 page | ||
// render the 500 page | ||
if (hasRender) { | ||
@@ -135,6 +163,5 @@ try { | ||
// flash an error message | ||
if (hasFlash) this.flash('error', err.message); | ||
if (hasFlash) this.flash('error', err.message); // TODO: until the issue is resolved, we need to add this here | ||
// <https://github.com/koajs/generic-session/pull/95#issuecomment-246308544> | ||
// TODO: until the issue is resolved, we need to add this here | ||
// <https://github.com/koajs/generic-session/pull/95#issuecomment-246308544> | ||
if (this.sessionStore && this.sessionId && this.session && this.state.cookiesKey) { | ||
@@ -144,3 +171,2 @@ yield co.wrap(this.sessionStore.set).call(this.sessionStore, this.sessionId, this.session); | ||
} | ||
/* | ||
@@ -158,4 +184,5 @@ // if we're using `koa-session-store` we need to add | ||
*/ | ||
// redirect the user to the page they were just on | ||
// redirect the user to the page they were just on | ||
this.redirect('back'); | ||
@@ -165,2 +192,3 @@ } | ||
break; | ||
case 'json': | ||
@@ -170,2 +198,3 @@ this.type = 'json'; | ||
break; | ||
default: | ||
@@ -180,63 +209,35 @@ this.type = this.api ? 'json' : 'text'; | ||
}); | ||
return _errorHandler.apply(this, arguments); | ||
} | ||
return function errorHandler(_x) { | ||
return _ref.apply(this, arguments); | ||
}; | ||
})(); | ||
function parseValidationError(ctx, err) { | ||
// translate messages | ||
const translate = message => _.isFunction(ctx.request.t) ? ctx.request.t(message) : message; // passport-local-mongoose support | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const s = require('underscore.string'); | ||
const co = require('co'); | ||
const Debug = require('debug'); | ||
const _ = require('lodash'); | ||
const Boom = require('boom'); | ||
if (passportLocalMongooseErrorNames.includes(err.name)) { | ||
err.message = translate(err.message); // this ensures the error shows up client-side | ||
const opts = { | ||
encoding: 'utf8' | ||
}; | ||
err.status = 400; // 429 = too many requests | ||
// error pages were inspired by HTML5 Boilerplate's default 404.html page | ||
// https://github.com/h5bp/html5-boilerplate/blob/master/src/404.html | ||
const _404 = fs.readFileSync(path.join(__dirname, '..', '404.html'), opts); | ||
const _500 = fs.readFileSync(path.join(__dirname, '..', '500.html'), opts); | ||
const debug = new Debug('koa-better-error-handler'); | ||
const passportLocalMongooseErrorNames = ['AuthenticationError', 'MissingPasswordError', 'AttemptTooSoonError', 'TooManyAttemptsError', 'NoSaltValueStoredError', 'IncorrectPasswordError', 'IncorrectUsernameError', 'MissingUsernameError', 'UserExistsError']; | ||
function parseValidationError(ctx, err) { | ||
// translate messages | ||
const translate = message => _.isFunction(ctx.request.t) ? ctx.request.t(message) : message; | ||
// passport-local-mongoose support | ||
if (passportLocalMongooseErrorNames.includes(err.name)) { | ||
err.message = translate(err.message); | ||
// this ensures the error shows up client-side | ||
err.status = 400; | ||
// 429 = too many requests | ||
if (['AttemptTooSoonError', 'TooManyAttemptsError'].includes(err.name)) err.status = 429; | ||
return err; | ||
} | ||
} // inspired by https://github.com/syntagma/mongoose-error-helper | ||
// inspired by https://github.com/syntagma/mongoose-error-helper | ||
if (err.name !== 'ValidationError') return err; | ||
// transform the error messages to be humanized as adapted from: | ||
if (err.name !== 'ValidationError') return err; // transform the error messages to be humanized as adapted from: | ||
// https://github.com/niftylettuce/mongoose-validation-error-transform | ||
err.errors = _.map(err.errors, error => { | ||
if (!_.isString(error.path)) { | ||
error.message = s.capitalize(error.message); | ||
error.message = capitalize(error.message); | ||
return error; | ||
} | ||
error.message = error.message.replace(new RegExp(error.path, 'g'), s.humanize(error.path)); | ||
error.message = s.capitalize(error.message); | ||
error.message = error.message.replace(new RegExp(error.path, 'g'), humanize(error.path)); | ||
error.message = capitalize(error.message); | ||
return error; | ||
}); | ||
}); // loop over the errors object of the Validation Error | ||
// with support for HTML error lists | ||
// loop over the errors object of the Validation Error | ||
// with support for HTML error lists | ||
if (_.values(err.errors).length === 1) { | ||
@@ -246,12 +247,11 @@ err.message = translate(_.values(err.errors)[0].message); | ||
const errors = _.map(_.map(_.values(err.errors), 'message'), translate); | ||
err.message = ctx.api ? errors.join(', ') : `<ul class="text-left mb-0"><li>${errors.join('</li><li>')}</li></ul>`; | ||
} | ||
} // this ensures the error shows up client-side | ||
// this ensures the error shows up client-side | ||
err.status = 400; | ||
return err; | ||
} | ||
module.exports = errorHandler; | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJlcnIiLCJfIiwiaXNFcnJvciIsIkVycm9yIiwidHlwZSIsImFjY2VwdHMiLCJkZWJ1ZyIsInN0YXR1cyIsIm1lc3NhZ2UiLCJCb29tIiwibm90QWNjZXB0YWJsZSIsIm91dHB1dCIsInBheWxvYWQiLCJwYXJzZVZhbGlkYXRpb25FcnJvciIsInZhbCIsInBhcnNlSW50IiwiaXNOdW1iZXIiLCJjcmVhdGUiLCJpc09iamVjdCIsInN0YXR1c0NvZGUiLCJoYXNGbGFzaCIsImlzRnVuY3Rpb24iLCJmbGFzaCIsImhhc1Nlc3Npb25zIiwic2Vzc2lvbiIsInNlc3Npb25TdG9yZSIsImlzU3RyaW5nIiwic2Vzc2lvbklkIiwic2V0IiwiaGFzUmVuZGVyIiwicmVuZGVyIiwibm9SZWZlcnJlciIsImdldCIsImhlYWRlclNlbnQiLCJ3cml0YWJsZSIsImJvZHkiLCJoZWFkZXJzIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsImFwcCIsImVtaXQiLCJzdGF0ZSIsIm1ldGEiLCJ0aXRsZSIsImVycm9yIiwiZGVzY3JpcHRpb24iLCJlcnIyIiwiXzQwNCIsIl81MDAiLCJjb29raWVzS2V5IiwiY28iLCJ3cmFwIiwiY2FsbCIsImNvb2tpZXMiLCJjb29raWUiLCJyZWRpcmVjdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJhcGkiLCJCdWZmZXIiLCJieXRlTGVuZ3RoIiwicmVzIiwiZW5kIiwiZXJyb3JIYW5kbGVyIiwiZnMiLCJyZXF1aXJlIiwicGF0aCIsInMiLCJEZWJ1ZyIsIm9wdHMiLCJlbmNvZGluZyIsInJlYWRGaWxlU3luYyIsImpvaW4iLCJfX2Rpcm5hbWUiLCJwYXNzcG9ydExvY2FsTW9uZ29vc2VFcnJvck5hbWVzIiwiY3R4IiwidHJhbnNsYXRlIiwicmVxdWVzdCIsInQiLCJpbmNsdWRlcyIsIm5hbWUiLCJlcnJvcnMiLCJtYXAiLCJjYXBpdGFsaXplIiwicmVwbGFjZSIsIlJlZ0V4cCIsImh1bWFuaXplIiwi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S0FBUDtBQUNEOztBQUVEQSxVQUFNckMsT0FBTixHQUFnQnFDLE1BQU1yQyxPQUFOLENBQWM2RSxPQUFkLENBQ2QsSUFBSUMsTUFBSixDQUFXekMsTUFBTXNCLElBQWpCLEVBQXVCLEdBQXZCLENBRGMsRUFFZEMsRUFBRW1CLFFBQUYsQ0FBVzFDLE1BQU1zQixJQUFqQixDQUZjLENBQWhCO0FBSUF0QixVQUFNckMsT0FBTixHQUFnQjRELEVBQUVnQixVQUFGLENBQWF2QyxNQUFNckMsT0FBbkIsQ0FBaEI7QUFDQSxXQUFPcUMsS0FBUDtBQUNELEdBWlksQ0FBYjs7QUFjQTtBQUNBO0FBQ0EsTUFBSTVDLEVBQUV1RixNQUFGLENBQVN4RixJQUFJa0YsTUFBYixFQUFxQjNDLE1BQXJCLEtBQWdDLENBQXBDLEVBQXVDO0FBQ3JDdkMsUUFBSVEsT0FBSixHQUFjcUUsVUFBVTVFLEVBQUV1RixNQUFGLENBQVN4RixJQUFJa0YsTUFBYixFQUFxQixDQUFyQixFQUF3QjFFLE9BQWxDLENBQWQ7QUFDRCxHQUZELE1BRU87QUFDTCxVQUFNMEUsU0FBU2pGLEVBQUVrRixHQUFGLENBQU1sRixFQUFFa0YsR0FBRixDQUFNbEYsRUFBRXVGLE1BQUYsQ0FBU3hGLElBQUlrRixNQUFiLENBQU4sRUFBNEIsU0FBNUIsQ0FBTixFQUE4Q0wsU0FBOUMsQ0FBZjtBQUNBN0UsUUFBSVEsT0FBSixHQUFjb0UsSUFBSWpCLEdBQUosR0FDVnVCLE9BQU9ULElBQVAsQ0FBWSxJQUFaLENBRFUsR0FFVCxrQ0FBaUNTLE9BQU9ULElBQVAsQ0FBWSxXQUFaLENBQXlCLFlBRi9EO0FBR0Q7O0FBRUQ7QUFDQXpFLE1BQUlPLE1BQUosR0FBYSxHQUFiOztBQUVBLFNBQU9QLEdBQVA7QUFDRDs7QUFFRHlGLE9BQU9DLE9BQVAsR0FBaUIxQixZQUFqQiIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKTtcbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5jb25zdCBzID0gcmVxdWlyZSgndW5kZXJzY29yZS5zdHJpbmcnKTtcbmNvbnN0IGNvID0gcmVxdWlyZSgnY28nKTtcbmNvbnN0IERlYnVnID0gcmVxdWlyZSgnZGVidWcnKTtcbmNvbnN0IF8gPSByZXF1aXJlKCdsb2Rhc2gnKTtcbmNvbnN0IEJvb20gPSByZXF1aXJlKCdib29tJyk7XG5cbmNvbnN0IG9wdHMgPSB7XG4gIGVuY29kaW5nOiAndXRmOCdcbn07XG5cbi8vIGVycm9yIHBhZ2VzIHdlcmUgaW5zcGlyZWQgYnkgSFRNTDUgQm9pbGVycGxhdGUncyBkZWZhdWx0IDQwNC5odG1sIHBhZ2Vcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9oNWJwL2h0bWw1LWJvaWxlcnBsYXRlL2Jsb2IvbWFzdGVyL3NyYy80MDQuaHRtbFxuY29uc3QgXzQwNCA9IGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnNDA0Lmh0bWwnKSwgb3B0cyk7XG5jb25zdCBfNTAwID0gZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICc1MDAuaHRtbCcpLCBvcHRzKTtcblxuY29uc3QgZGVidWcgPSBuZXcgRGVidWcoJ2tvYS1iZXR0ZXItZXJyb3ItaGFuZGxlcicpO1xuXG5jb25zdCBwYXNzcG9ydExvY2FsTW9uZ29vc2VFcnJvck5hbWVzID0gW1xuICAnQXV0aGVudGljYXRpb25FcnJvcicsXG4gICdNaXNzaW5nUGFzc3dvcmRFcnJvcicsXG4gICdBdHRlbXB0VG9vU29vbkVycm9yJyxcbiAgJ1Rvb01hbnlBdHRlbXB0c0Vycm9yJyxcbiAgJ05vU2FsdFZhbHVlU3RvcmVkRXJyb3InLFxuICAnSW5jb3JyZWN0UGFzc3dvcmRFcnJvcicsXG4gICdJbmNvcnJlY3RVc2VybmFtZUVycm9yJyxcbiAgJ01pc3NpbmdVc2VybmFtZUVycm9yJyxcbiAgJ1VzZXJFeGlzdHNFcnJvcidcbl07XG5cbi8vIGluaXRpYWxpemUgdHJ5L2NhdGNoIGVycm9yIGhhbmRsaW5nIHJpZ2h0IGF3YXlcbi8vIGFkYXB0ZWQgZnJvbTogaHR0cHM6Ly9naXRodWIuY29tL2tvYWpzL29uZXJyb3IvYmxvYi9tYXN0ZXIvaW5kZXguanNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rb2Fqcy9leGFtcGxlcy9pc3N1ZXMvMjAjaXNzdWVjb21tZW50LTMxNTY4NDAxXG4vL1xuLy8gaW5zcGlyZWQgYnk6XG4vLyBodHRwczovL2dvby5nbC82Mm9VN1Bcbi8vIGh0dHBzOi8vZ29vLmdsLzhaN2FNZVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuYXN5bmMgZnVuY3Rpb24gZXJyb3JIYW5kbGVyKGVycikge1xuICBpZiAoIWVycikgcmV0dXJuO1xuXG4gIGlmICghXy5pc0Vycm9yKGVycikpIGVyciA9IG5ldyBFcnJvcihlcnIpO1xuXG4gIGNvbnN0IHR5cGUgPSB0aGlzLmFjY2VwdHMoWyd0ZXh0JywgJ2pzb24nLCAnaHRtbCddKTtcblxuICBpZiAoIXR5cGUpIHtcbiAgICBkZWJ1ZygnaW52YWxpZCB0eXBlLCBzZW5kaW5nIDQwNiBlcnJvcicpO1xuICAgIGVyci5zdGF0dXMgPSA0MDY7XG4gICAgZXJyLm1lc3NhZ2UgPSBCb29tLm5vdEFjY2VwdGFibGUoKS5vdXRwdXQucGF5bG9hZDtcbiAgfVxuXG4gIC8vIHBhcnNlIG1vbmdvb3NlIHZhbGlkYXRpb24gZXJyb3JzXG4gIGVyciA9IHBhcnNlVmFsaWRhdGlvbkVycm9yKHRoaXMsIGVycik7XG5cbiAgLy8gY2hlY2sgaWYgd2UgdGhyZXcganVzdCBhIHN0YXR1cyBjb2RlIGluIG9yZGVyIHRvIGtlZXAgaXQgc2ltcGxlXG4gIGNvbnN0IHZhbCA9IHBhcnNlSW50KGVyci5tZXNzYWdlLCAxMCk7XG4gIGlmIChfLmlzTnVtYmVyKHZhbCkgJiYgdmFsID49IDQwMCkgZXJyID0gQm9vbS5jcmVhdGUodmFsKTtcblxuICAvLyBjaGVjayBpZiB3ZSBoYXZlIGEgYm9vbSBlcnJvciB0aGF0IHNwZWNpZmllZFxuICAvLyBhIHN0YXR1cyBjb2RlIGFscmVhZHkgZm9yIHVzIChhbmQgdGhlbiB1c2UgaXQpXG4gIGlmIChfLmlzT2JqZWN0KGVyci5vdXRwdXQpICYmIF8uaXNOdW1iZXIoZXJyLm91dHB1dC5zdGF0dXNDb2RlKSlcbiAgICBlcnIuc3RhdHVzID0gZXJyLm91dHB1dC5zdGF0dXNDb2RlO1xuXG4gIGlmICghXy5pc051bWJlcihlcnIuc3RhdHVzKSkgZXJyLnN0YXR1cyA9IDUwMDtcblxuICAvLyBjaGVjayBpZiB0aGVyZSBpcyBmbGFzaCBtZXNzYWdpbmdcbiAgY29uc3QgaGFzRmxhc2ggPSBfLmlzRnVuY3Rpb24odGhpcy5mbGFzaCk7XG4gIGRlYnVnKCdoYXNGbGFzaCcsIGhhc0ZsYXNoKTtcblxuICAvLyBjaGVjayBpZiB0aGVyZSBpcyBzZXNzaW9uIHN1cHBvcnRcbiAgY29uc3QgaGFzU2Vzc2lvbnMgPVxuICAgIF8uaXNPYmplY3QodGhpcy5zZXNzaW9uKSAmJlxuICAgIF8uaXNPYmplY3QodGhpcy5zZXNzaW9uU3RvcmUpICYmXG4gICAgXy5pc1N0cmluZyh0aGlzLnNlc3Npb25JZCkgJiZcbiAgICBfLmlzT2JqZWN0KHRoaXMuc2Vzc2lvbikgJiZcbiAgICBfLmlzRnVuY3Rpb24odGhpcy5zZXNzaW9uU3RvcmUuc2V0KTtcbiAgZGVidWcoJ2hhc1Nlc3Npb25zJywgaGFzU2Vzc2lvbnMpO1xuXG4gIC8vIGNoZWNrIGlmIHRoZXJlIGlzIGEgdmlldyByZW5kZXJpbmcgZW5naW5lIGJpbmRpbmcgYHRoaXMucmVuZGVyYFxuICBjb25zdCBoYXNSZW5kZXIgPSBfLmlzRnVuY3Rpb24odGhpcy5yZW5kZXIpO1xuICBkZWJ1ZygnaGFzUmVuZGVyJywgaGFzUmVuZGVyKTtcblxuICAvLyBjaGVjayBpZiB3ZSdyZSBhYm91dCB0byBnbyBpbnRvIGEgcG9zc2libGUgZW5kbGVzcyByZWRpcmVjdCBsb29wXG4gIGNvbnN0IG5vUmVmZXJyZXIgPSB0aGlzLmdldCgnUmVmZXJyZXInKSA9PT0gJyc7XG5cbiAgLy8gbm90aGluZyB3ZSBjYW4gZG8gaGVyZSBvdGhlclxuICAvLyB0aGFuIGRlbGVnYXRlIHRvIHRoZSBhcHAtbGV2ZWxcbiAgLy8gaGFuZGxlciBhbmQgbG9nLlxuICBpZiAodGhpcy5oZWFkZXJTZW50IHx8ICF0aGlzLndyaXRhYmxlKSB7XG4gICAgZGVidWcoJ2hlYWRlcnMgd2VyZSBhbHJlYWR5IHNlbnQsIHJldHVybmluZyBlYXJseScpO1xuICAgIGVyci5oZWFkZXJTZW50ID0gdHJ1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBwb3B1bGF0ZSB0aGUgc3RhdHVzIGFuZCBib2R5IHdpdGggYGJvb21gIGVycm9yIG1lc3NhZ2UgcGF5bG9hZFxuICAvLyAoZS5nLiB5b3UgY2FuIGRvIGBjdHgudGhyb3coNDA0KWAgYW5kIGl0IHdpbGwgb3V0cHV0IGEgYmVhdXRpZnVsIGVyciBvYmopXG4gIGVyci5zdGF0dXMgPSBlcnIuc3RhdHVzIHx8IDUwMDtcbiAgZXJyLnN0YXR1c0NvZGUgPSBlcnIuc3RhdHVzO1xuICB0aGlzLnN0YXR1c0NvZGUgPSBlcnIuc3RhdHVzQ29kZTtcbiAgdGhpcy5zdGF0dXMgPSB0aGlzLnN0YXR1c0NvZGU7XG4gIHRoaXMuYm9keSA9IEJvb20uY3JlYXRlKGVyci5zdGF0dXMsIGVyci5tZXNzYWdlKS5vdXRwdXQucGF5bG9hZDtcblxuICAvLyBzZXQgYW55IGFkZGl0aW9uYWwgZXJyb3IgaGVhZGVycyBzcGVjaWZpZWRcbiAgLy8gKGUuZy4gZm9yIEJhc2ljQXV0aCB3ZSB1c2UgYGJhc2ljLWF1dGhgIHdoaWNoIHNwZWNpZmllcyBXV1ctQXV0aGVudGljYXRlKVxuICBpZiAoXy5pc09iamVjdChlcnIuaGVhZGVycykgJiYgT2JqZWN0LmtleXMoZXJyLmhlYWRlcnMpLmxlbmd0aCA+IDApXG4gICAgdGhpcy5zZXQoZXJyLmhlYWRlcnMpO1xuXG4gIGRlYnVnKCdzdGF0dXMgY29kZSB3YXMgJWQnLCB0aGlzLnN0YXR1cyk7XG5cbiAgdGhpcy5hcHAuZW1pdCgnZXJyb3InLCBlcnIsIHRoaXMpO1xuXG4gIC8vIGZpeCBwYWdlIHRpdGxlIGFuZCBkZXNjcmlwdGlvblxuICB0aGlzLnN0YXRlLm1ldGEgPSB0aGlzLnN0YXRlLm1ldGEgfHwge307XG4gIHRoaXMuc3RhdGUubWV0YS50aXRsZSA9IHRoaXMuYm9keS5lcnJvcjtcbiAgdGhpcy5zdGF0ZS5tZXRhLmRlc2NyaXB0aW9uID0gZXJyLm1lc3NhZ2U7XG4gIGRlYnVnKCdzZXQgYHRoaXMuc3RhdGUubWV0YS50aXRsZWAgdG8gJXMnLCB0aGlzLnN0YXRlLm1ldGEudGl0bGUpO1xuICBkZWJ1Zygnc2V0IGB0aGlzLnN0YXRlLm1ldGEuZGVzY2AgdG8gJXMnLCB0aGlzLnN0YXRlLm1ldGEuZGVzY3JpcHRpb24pO1xuXG4gIGRlYnVnKCd0eXBlIHdhcyAlcycsIHR5cGUpO1xuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2h0bWwnOlxuICAgICAgdGhpcy50eXBlID0gJ2h0bWwnO1xuXG4gICAgICBpZiAodGhpcy5zdGF0dXMgPT09IDQwNCkge1xuICAgICAgICAvLyByZW5kZXIgdGhlIDQwNCBwYWdlXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9rb2Fqcy9rb2EvaXNzdWVzLzY0NlxuICAgICAgICBpZiAoaGFzUmVuZGVyKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRlYnVnKCdyZW5kZXJpbmcgNDA0IHBhZ2UnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVuZGVyKCc0MDQnKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIyKSB7XG4gICAgICAgICAgICBkZWJ1ZygnY291bGQgbm90IGZpbmQgNDA0IHBhZ2UsIHVzaW5nIGJ1aWx0LWluIDQwNCBodG1sJyk7XG4gICAgICAgICAgICB0aGlzLmJvZHkgPSBfNDA0O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmJvZHkgPSBfNDA0O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vUmVmZXJyZXIgfHwgdGhpcy5zdGF0dXMgPT09IDUwMCkge1xuICAgICAgICAvLyB0aGlzIHByZXZlbnRzIGEgcmVkaXJlY3QgbG9vcCBieSBkZXRlY3RpbmcgYW4gZW1wdHkgUmVmZXJyZXJcbiAgICAgICAgLy8gLi4ub3RoZXJ3aXNlIGl0IHdvdWxkIHJlYWNoIHRoZSBuZXh0IGNvbmRpdGlvbmFsIGJsb2NrIHdoaWNoXG4gICAgICAgIC8vIHdvdWxkIGVuZGxlc3NseSByZWRpcmV0IHRoZSB1c2VyIHdpdGggYHRoaXMucmVkaXJlY3QoJ2JhY2snKWBcbiAgICAgICAgaWYgKG5vUmVmZXJyZXIpIGRlYnVnKCdwcmV2ZW50ZWQgZW5kbGVzcyByZWRpcmVjdCBsb29wIScpO1xuXG4gICAgICAgIC8vIGZsYXNoIGFuIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgaWYgKGhhc0ZsYXNoKSB0aGlzLmZsYXNoKCdlcnJvcicsIGVyci5tZXNzYWdlKTtcblxuICAgICAgICAvLyByZW5kZXIgdGhlIDUwMCBwYWdlXG4gICAgICAgIGlmIChoYXNSZW5kZXIpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGVidWcoJ3JlbmRlcmluZyA1MDAgcGFnZScpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoJzUwMCcpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycjIpIHtcbiAgICAgICAgICAgIGRlYnVnKCdjb3VsZCBub3QgZmluZCA1MDAgcGFnZSwgdXNpbmcgYnVpbHQtaW4gNTAwIGh0bWwnKTtcbiAgICAgICAgICAgIHRoaXMuYm9keSA9IF81MDA7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYm9keSA9IF81MDA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGZsYXNoIGFuIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgaWYgKGhhc0ZsYXNoKSB0aGlzLmZsYXNoKCdlcnJvcicsIGVyci5tZXNzYWdlKTtcblxuICAgICAgICAvLyBUT0RPOiB1bnRpbCB0aGUgaXNzdWUgaXMgcmVzb2x2ZWQsIHdlIG5lZWQgdG8gYWRkIHRoaXMgaGVyZVxuICAgICAgICAvLyA8aHR0cHM6Ly9naXRodWIuY29tL2tvYWpzL2dlbmVyaWMtc2Vzc2lvbi9wdWxsLzk1I2lzc3VlY29tbWVudC0yNDYzMDg1NDQ+XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLnNlc3Npb25TdG9yZSAmJlxuICAgICAgICAgIHRoaXMuc2Vzc2lvbklkICYmXG4gICAgICAgICAgdGhpcy5zZXNzaW9uICYmXG4gICAgICAgICAgdGhpcy5zdGF0ZS5jb29raWVzS2V5XG4gICAgICAgICkge1xuICAgICAgICAgIGF3YWl0IGNvXG4gICAgICAgICAgICAud3JhcCh0aGlzLnNlc3Npb25TdG9yZS5zZXQpXG4gICAgICAgICAgICAuY2FsbCh0aGlzLnNlc3Npb25TdG9yZSwgdGhpcy5zZXNzaW9uSWQsIHRoaXMuc2Vzc2lvbik7XG4gICAgICAgICAgdGhpcy5jb29raWVzLnNldChcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuY29va2llc0tleSxcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmNvb2tpZVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvKlxuICAgICAgICAvLyBpZiB3ZSdyZSB1c2luZyBga29hLXNlc3Npb24tc3RvcmVgIHdlIG5lZWQgdG8gYWRkXG4gICAgICAgIC8vIGB0aGlzLl9zZXNzaW9uID0gbmV3IFNlc3Npb24oKWAsIGFuZCB0aGVuIHJ1biB0aGlzOlxuICAgICAgICBhd2FpdCBjby53cmFwKHRoaXMuX3Nlc3Npb24uX3N0b3JlLnNhdmUpLmNhbGwoXG4gICAgICAgICAgdGhpcy5fc2Vzc2lvbi5fc3RvcmUsXG4gICAgICAgICAgdGhpcy5fc2Vzc2lvbi5fc2lkLFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuc2Vzc2lvbilcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5jb29raWVzLnNldCh0aGlzLl9zZXNzaW9uLl9uYW1lLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgX3NpZDogdGhpcy5fc2Vzc2lvbi5fc2lkXG4gICAgICAgIH0pLCB0aGlzLl9zZXNzaW9uLl9jb29raWVPcHRzKTtcbiAgICAgICAgKi9cblxuICAgICAgICAvLyByZWRpcmVjdCB0aGUgdXNlciB0byB0aGUgcGFnZSB0aGV5IHdlcmUganVzdCBvblxuICAgICAgICB0aGlzLnJlZGlyZWN0KCdiYWNrJyk7XG4gICAgICB9XG5cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2pzb24nOlxuICAgICAgdGhpcy50eXBlID0gJ2pzb24nO1xuICAgICAgdGhpcy5ib2R5ID0gSlNPTi5zdHJpbmdpZnkodGhpcy5ib2R5LCBudWxsLCAyKTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLnR5cGUgPSB0aGlzLmFwaSA/ICdqc29uJyA6ICd0ZXh0JztcbiAgICAgIHRoaXMuYm9keSA9IEpTT04uc3RyaW5naWZ5KHRoaXMuYm9keSwgbnVsbCwgMik7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHRoaXMubGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgodGhpcy5ib2R5KTtcbiAgdGhpcy5yZXMuZW5kKHRoaXMuYm9keSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlVmFsaWRhdGlvbkVycm9yKGN0eCwgZXJyKSB7XG4gIC8vIHRyYW5zbGF0ZSBtZXNzYWdlc1xuICBjb25zdCB0cmFuc2xhdGUgPSBtZXNzYWdlID0+XG4gICAgXy5pc0Z1bmN0aW9uKGN0eC5yZXF1ZXN0LnQpID8gY3R4LnJlcXVlc3QudChtZXNzYWdlKSA6IG1lc3NhZ2U7XG5cbiAgLy8gcGFzc3BvcnQtbG9jYWwtbW9uZ29vc2Ugc3VwcG9ydFxuICBpZiAocGFzc3BvcnRMb2NhbE1vbmdvb3NlRXJyb3JOYW1lcy5pbmNsdWRlcyhlcnIubmFtZSkpIHtcbiAgICBlcnIubWVzc2FnZSA9IHRyYW5zbGF0ZShlcnIubWVzc2FnZSk7XG4gICAgLy8gdGhpcyBlbnN1cmVzIHRoZSBlcnJvciBzaG93cyB1cCBjbGllbnQtc2lkZVxuICAgIGVyci5zdGF0dXMgPSA0MDA7XG4gICAgLy8gNDI5ID0gdG9vIG1hbnkgcmVxdWVzdHNcbiAgICBpZiAoWydBdHRlbXB0VG9vU29vbkVycm9yJywgJ1Rvb01hbnlBdHRlbXB0c0Vycm9yJ10uaW5jbHVkZXMoZXJyLm5hbWUpKVxuICAgICAgZXJyLnN0YXR1cyA9IDQyOTtcbiAgICByZXR1cm4gZXJyO1xuICB9XG5cbiAgLy8gaW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL3N5bnRhZ21hL21vbmdvb3NlLWVycm9yLWhlbHBlclxuICBpZiAoZXJyLm5hbWUgIT09ICdWYWxpZGF0aW9uRXJyb3InKSByZXR1cm4gZXJyO1xuXG4gIC8vIHRyYW5zZm9ybSB0aGUgZXJyb3IgbWVzc2FnZXMgdG8gYmUgaHVtYW5pemVkIGFzIGFkYXB0ZWQgZnJvbTpcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25pZnR5bGV0dHVjZS9tb25nb29zZS12YWxpZGF0aW9uLWVycm9yLXRyYW5zZm9ybVxuICBlcnIuZXJyb3JzID0gXy5tYXAoZXJyLmVycm9ycywgZXJyb3IgPT4ge1xuICAgIGlmICghXy5pc1N0cmluZyhlcnJvci5wYXRoKSkge1xuICAgICAgZXJyb3IubWVzc2FnZSA9IHMuY2FwaXRhbGl6ZShlcnJvci5tZXNzYWdlKTtcbiAgICAgIHJldHVybiBlcnJvcjtcbiAgICB9XG5cbiAgICBlcnJvci5tZXNzYWdlID0gZXJyb3IubWVzc2FnZS5yZXBsYWNlKFxuICAgICAgbmV3IFJlZ0V4cChlcnJvci5wYXRoLCAnZycpLFxuICAgICAgcy5odW1hbml6ZShlcnJvci5wYXRoKVxuICAgICk7XG4gICAgZXJyb3IubWVzc2FnZSA9IHMuY2FwaXRhbGl6ZShlcnJvci5tZXNzYWdlKTtcbiAgICByZXR1cm4gZXJyb3I7XG4gIH0pO1xuXG4gIC8vIGxvb3Agb3ZlciB0aGUgZXJyb3JzIG9iamVjdCBvZiB0aGUgVmFsaWRhdGlvbiBFcnJvclxuICAvLyB3aXRoIHN1cHBvcnQgZm9yIEhUTUwgZXJyb3IgbGlzdHNcbiAgaWYgKF8udmFsdWVzKGVyci5lcnJvcnMpLmxlbmd0aCA9PT0gMSkge1xuICAgIGVyci5tZXNzYWdlID0gdHJhbnNsYXRlKF8udmFsdWVzKGVyci5lcnJvcnMpWzBdLm1lc3NhZ2UpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGVycm9ycyA9IF8ubWFwKF8ubWFwKF8udmFsdWVzKGVyci5lcnJvcnMpLCAnbWVzc2FnZScpLCB0cmFuc2xhdGUpO1xuICAgIGVyci5tZXNzYWdlID0gY3R4LmFwaVxuICAgICAgPyBlcnJvcnMuam9pbignLCAnKVxuICAgICAgOiBgPHVsIGNsYXNzPVwidGV4dC1sZWZ0IG1iLTBcIj48bGk+JHtlcnJvcnMuam9pbignPC9saT48bGk+Jyl9PC9saT48L3VsPmA7XG4gIH1cblxuICAvLyB0aGlzIGVuc3VyZXMgdGhlIGVycm9yIHNob3dzIHVwIGNsaWVudC1zaWRlXG4gIGVyci5zdGF0dXMgPSA0MDA7XG5cbiAgcmV0dXJuIGVycjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcnJvckhhbmRsZXI7XG4iXX0= | ||
module.exports = errorHandler; |
{ | ||
"name": "koa-better-error-handler", | ||
"description": "A better error-handler for Lad and Koa. Makes `ctx.throw` awesome (best used with koa-404-handler)", | ||
"version": "3.0.1", | ||
"version": "3.0.3", | ||
"author": "Nick Baugh <niftylettuce@gmail.com>", | ||
@@ -16,14 +16,19 @@ "bugs": "https://github.com/ladjs/koa-better-error-handler/issues", | ||
"dependencies": { | ||
"boom": "5.1.0", | ||
"@hapi/boom": "^7.4.3", | ||
"camelcase": "^5.3.1", | ||
"capitalize": "^2.0.0", | ||
"co": "^4.6.0", | ||
"debug": "^4.1.1", | ||
"humanize-string": "^2.1.0", | ||
"lodash": "^4.17.15", | ||
"underscore.string": "^3.3.5" | ||
"statuses": "^1.5.0", | ||
"toidentifier": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.5.5", | ||
"@babel/core": "^7.5.5", | ||
"@babel/preset-env": "^7.5.5", | ||
"@commitlint/cli": "^8.1.0", | ||
"@commitlint/config-conventional": "^8.1.0", | ||
"ava": "^2.3.0", | ||
"babel-cli": "^6.26.0", | ||
"babel-preset-env": "^1.7.0", | ||
"codecov": "^3.5.0", | ||
@@ -33,2 +38,3 @@ "cross-env": "^5.2.1", | ||
"eslint-config-xo-lass": "^1.0.3", | ||
"eslint-plugin-node": "^10.0.0", | ||
"fixpack": "^2.3.1", | ||
@@ -38,3 +44,3 @@ "husky": "^3.0.5", | ||
"koa-404-handler": "^0.0.2", | ||
"koa-basic-auth": "https://github.com/niftylettuce/basic-auth", | ||
"koa-basic-auth": "^4.0.0", | ||
"koa-connect-flash": "^0.1.2", | ||
@@ -59,3 +65,3 @@ "koa-convert": "^1.2.0", | ||
"hooks": { | ||
"pre-commit": "npm test", | ||
"pre-commit": "lint-staged && npm test", | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" | ||
@@ -89,16 +95,14 @@ } | ||
"lint-staged": { | ||
"linters": { | ||
"*.js": [ | ||
"xo --fix", | ||
"git add" | ||
], | ||
"*.md": [ | ||
"remark . -qfo", | ||
"git add" | ||
], | ||
"package.json": [ | ||
"fixpack", | ||
"git add" | ||
] | ||
} | ||
"*.js": [ | ||
"xo --fix", | ||
"git add" | ||
], | ||
"*.md": [ | ||
"remark . -qfo", | ||
"git add" | ||
], | ||
"package.json": [ | ||
"fixpack", | ||
"git add" | ||
] | ||
}, | ||
@@ -120,3 +124,3 @@ "main": "lib/index.js", | ||
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov", | ||
"lint": "xo && remark . -qfo", | ||
"lint": "xo && remark . -qfo && eslint --no-inline-config -c .lib.eslintrc lib", | ||
"precommit": "lint-staged && npm test", | ||
@@ -123,0 +127,0 @@ "test": "npm run build && npm run lint && npm run test-coverage", |
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
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
52017
9
28
19
324
+ Added@hapi/boom@^7.4.3
+ Addedcamelcase@^5.3.1
+ Addedcapitalize@^2.0.0
+ Addedhumanize-string@^2.1.0
+ Addedstatuses@^1.5.0
+ Addedtoidentifier@^1.0.0
+ Added@hapi/boom@7.4.11(transitive)
+ Added@hapi/hoek@8.5.1(transitive)
+ Addedcamelcase@5.3.1(transitive)
+ Addedcapitalize@2.0.4(transitive)
+ Addeddecamelize@2.0.0(transitive)
+ Addedhumanize-string@2.1.0(transitive)
+ Addedstatuses@1.5.0(transitive)
+ Addedtoidentifier@1.0.1(transitive)
+ Addedxregexp@4.0.0(transitive)
- Removedboom@5.1.0
- Removedunderscore.string@^3.3.5
- Removedboom@5.1.0(transitive)
- Removedhoek@4.3.1(transitive)
- Removedsprintf-js@1.1.3(transitive)
- Removedunderscore.string@3.3.6(transitive)
- Removedutil-deprecate@1.0.2(transitive)