├── .github └── workflows │ └── nodejs.yml ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── lib ├── backend.js ├── honeybadger.js ├── logger.js ├── middleware.js ├── notice.js └── util.js ├── package-lock.json ├── package.json ├── scripts └── update-versions.sh └── test ├── honeybadger.js ├── logger.js ├── middleware.js ├── mocha.opts └── util.js /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [10.x, 12.x, 14.x] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v1 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | - run: npm ci 28 | - run: npm run build --if-present 29 | - run: npm test 30 | env: 31 | CI: true 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | nb.js 2 | node_modules 3 | npm-debug\.log 4 | *.swp 5 | package-lock.json 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | nb.js 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. See [Keep a 3 | CHANGELOG](http://keepachangelog.com/) for how to update this file. This project 4 | adheres to [Semantic Versioning](http://semver.org/). 5 | 6 | ## [Unreleased] 7 | 8 | ## [1.4.1] - 2021-08-17 9 | 10 | ## [1.4.0] - 2020-03-19 11 | ### Fixed 12 | - Support async functions in lambdaHandler (#54, #82) 13 | 14 | ## [1.3.0] - 2018-06-19 15 | ### Added 16 | - Add an option to report uncaught exceptions. -@aryehischechter/#31 17 | 18 | ## [1.2.1] - 2016-10-14 19 | ### Fixed 20 | - Update request package to ~2.79.0 21 | 22 | ## [1.2.0] - 2016-10-14 23 | ### Changed 24 | - Sunset performance metrics. See 25 | http://blog.honeybadger.io/sunsetting-performance-metrics/ 26 | 27 | ## [1.1.3] - 2016-08-15 28 | ### Changed 29 | - Deprecate `Honeybadger.wrap()` 30 | - Updated dependency for request package. 31 | 32 | ### Fixed 33 | - Add missing filters configuration option. 34 | 35 | ## [1.1.2] - 2016-07-12 36 | ### Fixed 37 | - `setTimeout` is now called when metrics are recorded instead of recursively. 38 | This fixes an issue in environments like AWS Lambda where the execution waits 39 | for the event loop to empty. 40 | - Fixed a bug where uncaught exception handler wasn't called in development 41 | environment (see #14). 42 | - Call original handler with arguments in `Honeybadger.lambdaHandler()`. 43 | 44 | ### Added 45 | - Use `Honeybadger.flushMetrics()` to clear the timeout interval and flush 46 | metrics immediately. 47 | 48 | ## [1.1.1] - 2016-06-16 49 | ### Fixed 50 | - Bump *request* package to `~2.72.0` to fix security vulnerabilities. -@gazay 51 | 52 | ## [1.1.0] - 2016-05-12 53 | ### Added 54 | - Use `Honeybadger.metricsHandler` to send us request metrics! 55 | 56 | ## [1.0.0] - 2016-04-21 57 | ### Changed 58 | - Entirely new API. See the [README](README.md) for details! 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Honeybadger Industries LLC 4 | Copyright (c) 2014 Charlie McConnell 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > **Note:** This project is deprecated; use the new universal [@honeybadger-io/js](https://github.com/honeybadger-io/honeybadger-js) instead. See the [blog post](https://www.honeybadger.io/blog/universal-honeybadger-js/) for more info and upgrade instructions. 2 | 3 | # Honeybadger for NodeJS 4 | 5 | ![Node.js CI](https://github.com/honeybadger-io/honeybadger-node/workflows/Node.js%20CI/badge.svg) 6 | [![npm version](https://badge.fury.io/js/honeybadger.svg)](https://badge.fury.io/js/honeybadger) 7 | 8 | This is the Node.js module for integrating apps with the :zap: [Honeybadger Exception Notifier for JavaScript and Node](http://honeybadger.io). 9 | 10 | When an uncaught exception occurs, Honeybadger will POST the relevant data to the Honeybadger service, and we'll alert you to the problem. 11 | 12 | ## Upgrading from 0.x 13 | 14 | We made some breaking changes in 1.0, so if you currently use 0.x, you will need to update your usage. In most cases you should be able to replace the old `hb.send()` function with `hb.notify()`. Instead of configuring the client as an instance, you can require the global singleton instead: 15 | 16 | ```javascript 17 | var hb = require('honeybadger'); 18 | 19 | hb.configure({ 20 | apiKey: '[ YOUR API KEY HERE ]' 21 | }); 22 | 23 | # Change: 24 | # hb.send(err, opts); 25 | # To: 26 | hb.notify(err, opts); 27 | ``` 28 | 29 | We also stopped emitting the `remoteError` event and now emit `error` for all failures to notify Honeybadger. 30 | 31 | ## Getting Started 32 | 33 | In this section, we'll cover the basics. More advanced installations are covered later. 34 | 35 | ### 1. Install the npm package 36 | 37 | ```javascript 38 | npm install honeybadger --save 39 | ``` 40 | 41 | ### 2. Require the honeybadger module 42 | 43 | ```javascript 44 | var Honeybadger = require('honeybadger'); 45 | ``` 46 | 47 | ### 3. Set your API key 48 | 49 | ```javascript 50 | Honeybadger.configure({ 51 | apiKey: '[ YOUR API KEY HERE ]' 52 | }); 53 | ``` 54 | 55 | You can also place your API key in the `HONEYBADGER_API_KEY` environment variable if you prefer the 12-factor app configuration style. 56 | 57 | ### 4. Set up your code 58 | 59 | By default Honeybadger will be notified automatically of all unhandled errors which crash your node processes. Many applications catch errors, however, so you may want to set up some additional framework integrations: 60 | 61 | #### Express or Connect Framework 62 | 63 | Errors which happen in [Express](http://expressjs.com/) or [Connect](https://github.com/senchalabs/connect#readme) apps can be automatically reported to Honeybadger by installing our middleware. 64 | 65 | In order to function properly our middleware must be added before and after your normal app middleware, but before any other error handling middleware: 66 | 67 | ```javascript 68 | app.use(Honeybadger.requestHandler); // Use *before* all other app middleware. 69 | // app.use(myMiddleware); 70 | app.use(Honeybadger.errorHandler); // Use *after* all other app middleware. 71 | // app.use(myErrorMiddleware); 72 | ``` 73 | 74 | Note: If you use the [connect-domain](https://www.npmjs.com/package/connect-domain) middleware, you do *not* need to use `Honeybadger.requestHandler` because they are essentially the same. 75 | 76 | #### AWS Lambda 77 | 78 | Honeybadger can automatically report errors which happen on [AWS Lambda](https://aws.amazon.com/lambda/): 79 | 80 | ```javascript 81 | // Your handler function. 82 | function handler(event, context) { 83 | console.log('Event:', event); 84 | console.log('Context:', context); 85 | throw(new Error('Something went wrong.')); 86 | console.log("Shouldn't make it here."); 87 | } 88 | 89 | // Build and export the function. 90 | exports.handler = Honeybadger.lambdaHandler(handler); 91 | ``` 92 | 93 | Check out our [example Lambda project](https://github.com/honeybadger-io/honeybadger-lambda-node) for a complete example. 94 | 95 | Note: [Async Handlers](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html#nodejs-handler-async) are not supported by `Honeybadger.lambdaHandler`. See [this issue](https://github.com/honeybadger-io/honeybadger-node/issues/54) for status. 96 | 97 | #### Manually reporting exceptions 98 | 99 | To catch exceptions and report them manually: 100 | 101 | ```javascript 102 | try { 103 | throw(new Error('Badgers!')); 104 | } catch(err) { 105 | Honeybadger.notify(err); 106 | throw(err); 107 | } 108 | ``` 109 | 110 | Note that re-throwing the exceptions will cause them to be reported by any additional error handlers that may catch them. 111 | 112 | ## Sample Application 113 | 114 | If you'd like to see the library in action before you integrate it with your apps, check out our [sample Node.js/Express application](https://github.com/honeybadger-io/crywolf-node). 115 | 116 | You can deploy the sample app to your Heroku account by clicking this button: 117 | 118 | [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/honeybadger-io/crywolf-node) 119 | 120 | Don't forget to destroy the Heroku app after you're done so that you aren't charged for usage. 121 | 122 | The code for the sample app is [available on Github](https://github.com/honeybadger-io/crywolf-node), in case you'd like to read through it, or run it locally. 123 | 124 | ## Advanced Configuration 125 | 126 | There are a few ways to configure the Honeybadger module. You can use `#configure()` at runtime. You can use environment variables. Or you can use a combination of the two. 127 | 128 | Note that the only configuration option you *have* to provide is `apiKey`. 129 | 130 | ```javascript 131 | Honeybadger.configure({ 132 | // The API key of your Honeybadger project. (env: HONEYBADGER_API_KEY) 133 | apiKey: 'your api key goes here', 134 | 135 | // The API endpoint to use. Must be a valid URL with no trailing slash. (env: HONEYBADGER_ENDPOINT) 136 | endpoint: 'https://api.honeybadger.io', 137 | 138 | // Defaults to the server's hostname. (env: HONEYBADGER_HOSTNAME) 139 | hostname: 'badger01', 140 | 141 | // Defaults to the current node environment. (env: HONEYBADGER_ENVIRONMENT) 142 | environment: 'staging', 143 | 144 | // Defaults to the node process's current working directory. (env: HONEYBADGER_PROJECT_ROOT) 145 | projectRoot: '/var/www', 146 | 147 | // An object with `info` and `error` methods. 148 | logger: console, 149 | 150 | // Environments which will not report data. 151 | developmentEnvironments: ['dev', 'development', 'test'], 152 | 153 | // Key values to filter from request data. Matches are partial, so "password" 154 | // and "password_confirmation" will both be filtered. 155 | filters: ['creditcard', 'password'] 156 | }); 157 | ``` 158 | 159 | ### Configuring the default logger 160 | 161 | Honeybadger provides a default logger which reports info and error level logs to 162 | stdout/stderr (basically a proxy to `console`). The default level is "error" 163 | ("info" logs will be silenced). To configure the log level you can set 164 | `Honeybadger.logger.level = 'info'` or set the `HONEYBADGER_LOG_LEVEL=info` 165 | environment variable before executing your program. 166 | 167 | ## Public Interface 168 | 169 | ### `Honeybadger.notify()`: Report an error to Honeybadger 170 | 171 | This is the only function you need. Give it an `Error` object, and some optional metadata and it reports the error to Honeybadger. 172 | 173 | #### Examples: 174 | 175 | ```javascript 176 | // You can report an error without any metadata 177 | Honeybadger.notify(error); 178 | 179 | // Metadata is provided via a second or third argument. 180 | Honeybadger.notify(error, { 181 | context: { 182 | user: 'jane', 183 | email: 'a@b.net' 184 | }, 185 | session: { user_token: "asdf" }, 186 | headers: req.headers, 187 | params: {}, 188 | cgiData: { 189 | 'server-software': 'Node ' + process.version 190 | } 191 | }); 192 | ``` 193 | 194 | You can send the following metadata: 195 | 196 | Key | Description 197 | ---- | ---- 198 | `name` | (`String`) The error's type/class name. 199 | `message` | (`String`) The error message. 200 | `context` | (`Object`) The context object is for app-specific data that will make error followup easier, like user ids 201 | `session` | (`Object`) The session data as defined by whatever session manager you use 202 | `headers` | (`Object`) HTTP headers for the current request 203 | `params` | (`Object`) GET or POST params for the current request 204 | `cgiData` | (`Object`) Information about the application environment. 205 | `url` | (`String`) The URL associated with the request, if any. 206 | `component` | (`String`) The software component (displayed in Honeybadger as: component#action). 207 | `action` | (`String`) The action within the component. 208 | `fingerprint` | (`String`) An optional grouping fingerprint. 209 | 210 | JavaScript often uses generic class names -- such as `Error` -- which are uninformative and also cause unrelated errors to be grouped together. To get around this issue it's a good practice to send a custom error class when notifying Honeybadger: 211 | 212 | ```javascript 213 | Honeybadger.notify(error, 'DescriptiveClass'); 214 | Honeybadger.notify(error, 'DescriptiveClass', { ... }); 215 | ``` 216 | 217 | You can notify Honeybadger of anything, even if you don't have an error object. We'll automatically generate a stacktrace for you: 218 | 219 | ```javascript 220 | Honeybadger.notify('Badgers!'); 221 | Honeybadger.notify('Badgers!', { ... }); 222 | Honeybadger.notify('Badgers!', 'CustomClass'); 223 | Honeybadger.notify('Badgers!', 'CustomClass', { ... }); 224 | Honeybadger.notify({ 225 | message: 'Badgers!', 226 | name: 'CustomClass', 227 | ... 228 | }); 229 | ``` 230 | 231 | Finally, you can provide an optional callback as the last argument to any call to `Honeybadger.notify()`. The callback will always be called regardless of the result of the notification: 232 | 233 | ```javascript 234 | Honeybadger.notify(err, function notifyCallback(err, notice) { 235 | if (err) { 236 | return console.error(err); 237 | } 238 | // If there was no error, log the notice: 239 | console.log(notice); // { id: 'uuid' } 240 | }); 241 | ``` 242 | 243 | --- 244 | 245 | ### `Honeybadger.setContext()`: Set metadata to be sent if an exception occurs 246 | 247 | Javascript exceptions are pretty bare-bones. You probably have some additional data that could make them a lot easier to understand - perhaps the name of the current controller/view, or the id of the current user. This function lets you set context data that will be sent if an error should occur. 248 | 249 | You can call `setContext` as many times as you like. New context data will be merged with the existing data. 250 | 251 | #### Examples: 252 | 253 | ```javascript 254 | // On load 255 | Honeybadger.setContext({ 256 | user_id: 123 257 | }); 258 | 259 | // Later 260 | Honeybadger.setContext({ 261 | controller_name: 'posts' 262 | }); 263 | 264 | // The context now contains { user_id: 123, controller_name: 'posts' } 265 | ``` 266 | 267 | --- 268 | 269 | ### `Honeybadger.resetContext()`: Clear context metadata 270 | 271 | If you've used `Honeybadger.setContext` to store context data, you can clear it with `Honeybadger.resetContext`. 272 | 273 | #### Example: 274 | 275 | ```javascript 276 | // Set the context to {} 277 | Honeybadger.resetContext(); 278 | 279 | // Clear the context, then set it to `{ user_id: 123 }` 280 | Honeybadger.resetContext({ 281 | user_id: 123 282 | }); 283 | ``` 284 | 285 | --- 286 | 287 | ### `Honeybadger.configure()`: Set configuration values 288 | 289 | The `configure` method takes an object containing config values. Its return value is unspecified. 290 | 291 | #### Examples: 292 | 293 | ```javascript 294 | Honeybadger.configure({apiKey: "adlkjfljk"}); 295 | ``` 296 | 297 | --- 298 | 299 | ### `Honeybadger.factory()`: create a new client instance 300 | 301 | The `factory` method returns a new instance of Honeybadger which can be configured differently than the global/singleton instance. 302 | 303 | #### Examples: 304 | 305 | ```javascript 306 | var other_hb = Honeybadger.factory({apiKey: "zxcvbnm"}); 307 | other_hb.notify("This will go to an alternate project."); 308 | ``` 309 | 310 | --- 311 | 312 | ### `Honeybadger.errorHandler()`: error handling middleware for Express and Connect 313 | 314 | The `errorHandler` method is an error reporting middleware for [Express](http://expressjs.com/) and [Connect](https://github.com/senchalabs/connect#readme) apps. Use the middleware in your app to report all errors which happen during the request. Request data such as params, session, and cookies will be automatically reported. 315 | 316 | #### Examples: 317 | 318 | ```javascript 319 | app.use(Honeybadger.errorHandler); 320 | ``` 321 | 322 | --- 323 | 324 | ### `Honeybadger.lambdaHandler()`: handler for AWS Lambda 325 | 326 | The `lambdaHandler` method is a wrapper for [AWS Lambda](https://aws.amazon.com/lambda/). You pass it your Lambda function and it returns a new function which reports errors to Honeybadger. 327 | 328 | #### Examples: 329 | 330 | ```javascript 331 | // Your handler function. 332 | function handler(event, context) { 333 | console.log('Event:', event); 334 | console.log('Context:', context); 335 | throw(new Error('Something went wrong.')); 336 | console.log("Shouldn't make it here."); 337 | } 338 | 339 | // Build and export the function. 340 | exports.handler = Honeybadger.lambdaHandler(handler); 341 | ``` 342 | 343 | Note: [Async Handlers](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html#nodejs-handler-async) are not supported by `Honeybadger.lambdaHandler`. See [this issue](https://github.com/honeybadger-io/honeybadger-node/issues/54) for status. 344 | 345 | --- 346 | 347 | ### `Honeybadger.onUncaughtException()`: configure the uncaught exception handler 348 | 349 | Honeybadger's default uncaught exception handler logs the error and exits the 350 | process after notifying Honeybadger of the uncaught exception. You can change 351 | the default handler by calling `Honeybadger.onUncaughtException()` with a new 352 | handler function. Honeybadger will still be notified before your handler is 353 | invoked. Note that it's important to exit the process cleanly if you replace the 354 | handler; see [Warning: using 'uncaughtException' 355 | correctly](https://nodejs.org/api/process.html#process_warning_using_uncaughtexception_correctly) 356 | for additional information. 357 | 358 | #### Examples: 359 | 360 | ```javascript 361 | Honeybadger.onUncaughtException(function(err) { 362 | doSomethingWith(err); 363 | process.exit(1); 364 | }); 365 | ``` 366 | 367 | --- 368 | 369 | ### Events 370 | 371 | Instances of `honeybadger-node` can emit the following events: 372 | 373 | Event | Description 374 | ---- | ---- 375 | `sent` | This is emitted when honeybadger.io returns a 201 successfully. The response body, containing metadata about the submitted error, is emitted as data. 376 | `error` | Emitted in the case of any error while trying to connect to honeybadger.io. *Will not be emitted unless a listener is present*. 377 | 378 | ## Changelog 379 | 380 | See https://github.com/honeybadger-io/honeybadger-node/blob/master/CHANGELOG.md 381 | 382 | ## Contributing 383 | 384 | If you're adding a new feature, please [submit an issue](https://github.com/honeybadger-io/honeybadger-node/issues/new) as a preliminary step; that way you can be (moderately) sure that your pull request will be accepted. 385 | 386 | ### To contribute your code: 387 | 388 | 1. Fork it. 389 | 2. Create a topic branch `git checkout -b my_branch` 390 | 3. Commit your changes `git commit -am "Boom"` 391 | 3. Push to your branch `git push origin my_branch` 392 | 4. Send a [pull request](https://github.com/honeybadger-io/honeybadger-node/pulls) 393 | 394 | ### Development 395 | 396 | Clone the repo, and then `npm install`. Now you should be able to run `npm test`. 397 | 398 | ## Releasing 399 | 400 | Releasing is done with two commands: `npm version` and `npm publish`. **Both 401 | commands should be used with care.** The `npm publish` command publishes to NPM. 402 | 403 | To perform a full release: 404 | 405 | 1. With a clean working tree, use `npm version [new version]` to bump the 406 | version, commit the changes, tag the release, and push to GitHub. See `npm 407 | help version` for documentation. 408 | 409 | 2. To publish the release, use `npm publish`. See `npm help publish` for 410 | documentation. 411 | 412 | ### License 413 | 414 | The Honeybadger gem is MIT licensed. See the [LICENSE](https://raw.github.com/honeybadger-io/honeybadger-node/master/LICENSE) file in this repository for details. 415 | -------------------------------------------------------------------------------- /lib/backend.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var request = require('request'); 4 | var util = require('./util'); 5 | 6 | function backend(path) { 7 | return function(client, payload, callback) { 8 | if (!util.is('Function', callback)) { 9 | callback = function defaultCallback(err, res, body){}; 10 | } 11 | 12 | if (!client.apiKey) { 13 | callback(new Error('API key is missing or invalid.')); 14 | return; 15 | } 16 | 17 | var headers = { 18 | 'content-type':'application/json', 19 | 'X-API-Key': client.apiKey, 20 | 'Accept':'application/json' 21 | }; 22 | 23 | request.post({ 24 | url: client.endpoint + path, 25 | headers: headers, 26 | json: payload 27 | }, callback); 28 | } 29 | } 30 | 31 | module.exports = { 32 | notice: backend('/v1/notices') 33 | } 34 | -------------------------------------------------------------------------------- /lib/honeybadger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var EventEmitter = require('events').EventEmitter; 4 | var domain = require('domain'); 5 | var util = require('./util'); 6 | var backend = require('./backend'); 7 | var logger = require('./logger'); 8 | var notice = require('./notice'); 9 | var middleware = require('./middleware'); 10 | var configOpts = ['apiKey', 'endpoint', 'projectRoot', 'environment', 11 | 'hostname', 'developmentEnvironments', 'logger', 'filters', 'reportUncaught']; 12 | var uncaughtExceptionInstalled; 13 | var uncaughtExceptionHandler; 14 | 15 | function Honeybadger(opts) { 16 | var self = Object.create(EventEmitter.prototype); 17 | 18 | EventEmitter.call(self); 19 | 20 | self.configure = configure; 21 | self.setContext = setContext; 22 | self.resetContext = resetContext; 23 | self.wrap = wrap; 24 | self.notify = notify; 25 | 26 | self.errorHandler = middleware.errorHandler.bind(self); 27 | self.requestHandler = middleware.requestHandler.bind(self); 28 | self.lambdaHandler = middleware.lambdaHandler.bind(self); 29 | 30 | self.apiKey = process.env.HONEYBADGER_API_KEY; 31 | self.endpoint = process.env.HONEYBADGER_ENDPOINT || 'https://api.honeybadger.io'; 32 | self.projectRoot = process.env.HONEYBADGER_PROJECT_ROOT || process.cwd(); 33 | self.environment = process.env.HONEYBADGER_ENVIRONMENT || process.env.NODE_ENV; 34 | self.hostname = process.env.HONEYBADGER_HOSTNAME || require('os').hostname(); 35 | self.developmentEnvironments = ['dev', 'development', 'test']; 36 | self.filters = ['creditcard', 'password']; 37 | self.reportUncaught = true; 38 | self.onUncaughtException = function(err) { 39 | self.logger.error(err.stack || err); 40 | process.exit(1); 41 | } 42 | 43 | self.logger = logger(process.env.HONEYBADGER_LOG_LEVEL || 'error'); 44 | self.context = {}; 45 | 46 | self.configure(opts); 47 | 48 | withUncaught.call(self); 49 | 50 | // Deprecated. 51 | self.timing = deprecatedNoop('Honeybadger.timing has no effect and will be removed.').bind(self); 52 | self.increment = deprecatedNoop('Honeybadger.increment has no effect and will be removed.').bind(self); 53 | self.flushMetrics = deprecatedNoop('Honeybadger.flushMetrics has no effect and will be removed.').bind(self); 54 | self.metricsHandler = middleware.metricsHandler.bind(self); 55 | 56 | return self; 57 | } 58 | 59 | function withUncaught() { 60 | if (this.reportUncaught !== false && !uncaughtExceptionInstalled) { 61 | var self = this; 62 | uncaughtExceptionHandler = function (err) { 63 | self.notify(err, function() { 64 | self.onUncaughtException(err); 65 | }); 66 | } 67 | process.on('uncaughtException', uncaughtExceptionHandler); 68 | uncaughtExceptionInstalled = true; 69 | } 70 | return this; 71 | } 72 | 73 | function configure(opts) { 74 | var opt; 75 | if (!(opts instanceof Object)) { return this; } 76 | for (opt in opts) { 77 | if (configOpts.indexOf(opt) < 0) { throw(new Error('Invalid config option: ' + opt)); } 78 | this[opt] = opts[opt]; 79 | } 80 | // Defualt value for reportUncaught is true. 81 | // If reportUncaught is anything but false, treat it as defualt. 82 | if (this.reportUncaught === false && uncaughtExceptionHandler) { 83 | process.removeListener("uncaughtException", uncaughtExceptionHandler); 84 | } 85 | return this; 86 | } 87 | 88 | function setContext(context) { 89 | if (context instanceof Object) { 90 | this.context = util.merge(this.context, context); 91 | } 92 | return this; 93 | } 94 | 95 | function resetContext(context) { 96 | if (context instanceof Object) { 97 | this.context = util.merge({}, context); 98 | } else { 99 | this.context = {}; 100 | } 101 | return this; 102 | } 103 | 104 | // Deprecated: will likely be removed or changed in the future. 105 | function wrap(func) { 106 | if (!util.is('Function', func)) { func = function noop(){}; } 107 | 108 | return function wrapper() { 109 | try { 110 | return func.apply(this, arguments); 111 | } catch(err) { 112 | this.notify(err, {stackShift: 3}); 113 | throw(err); 114 | } 115 | }.bind(this); 116 | } 117 | 118 | function notify(err, name, extra, callback) { 119 | if (!err) { err = {}; } 120 | 121 | if (util.is('Error', err)) { 122 | var e = err; 123 | err = {name: e.name, message: e.message, stack: e.stack}; 124 | } 125 | if (!util.is('Object', err)) { 126 | var m = String(err); 127 | err = {message: m}; 128 | } 129 | 130 | if (!callback && name && util.is('Function', name)) { 131 | callback = name; 132 | name = {}; 133 | } 134 | if (!callback && extra && util.is('Function', extra)) { 135 | callback = extra; 136 | extra = undefined; 137 | } 138 | if (!util.is('Function', callback)) { 139 | callback = function(){}; 140 | } 141 | 142 | if (name && !util.is('Object', name)) { 143 | var n = String(name); 144 | name = {name: n}; 145 | } 146 | if (name) { 147 | err = util.merge(err, name); 148 | } 149 | 150 | if (util.is('Object', extra)) { 151 | err = util.merge(err, extra); 152 | } 153 | 154 | if (!err.environment) { err.environment = this.environment; } 155 | if (this.developmentEnvironments.indexOf(err.environment) !== -1) { 156 | callback(new Error('The environment "' + err.environment + '" is disabled. See `config.developmentEnvironments` for more info.')); 157 | return this; 158 | } 159 | 160 | if (!err.projectRoot) { err.projectRoot = this.projectRoot; } 161 | if (!err.hostname) { err.hostname = this.hostname; } 162 | if (!err.filters) { err.filters = this.filters; } 163 | 164 | err.context = util.merge(this.context, err.context || {}); 165 | err.stackFilter = stackFilter(err.projectRoot); 166 | if (!err.stackShift) { err.stackShift = 2; } 167 | 168 | var self = this; 169 | notice(err, function (payload) { 170 | backend.notice(self, payload, function(backendErr, res, body) { 171 | if (!backendErr && res.statusCode !== 201) { 172 | backendErr = new Error('Bad HTTP response: ' + res.statusCode); 173 | } 174 | 175 | if (backendErr) { 176 | self.logger.error('Unable to notify Honeybadger: ' + backendErr); 177 | emit.call(self, 'error', backendErr, err); 178 | callback(backendErr); 179 | return; 180 | } 181 | 182 | self.logger.info('POST to honeybadger successful', body); 183 | emit.call(self, 'sent', body, err); 184 | callback(null, body); 185 | }); 186 | }); 187 | 188 | return this; 189 | } 190 | 191 | function emit(event) { 192 | // Don't emit unless there's a listener. 193 | // Otherwise, we'll end up crashing some poor stranger's server. 194 | if (this.listeners(event).length) { 195 | this.emit.apply(this, arguments); 196 | } 197 | } 198 | 199 | function stackFilter(projectRoot) { 200 | return function(f) { 201 | if (f.file) { 202 | f.file = f.file.replace(/.*\/node_modules\/(.+)/, '[NODE_MODULES]/$1'); 203 | f.file = f.file.replace(projectRoot, '[PROJECT_ROOT]'); 204 | } 205 | return f; 206 | } 207 | } 208 | 209 | function deprecatedNoop(msg) { 210 | return function() { 211 | this.logger.error('DEPRECATION WARNING: ' + msg); 212 | return this; 213 | }; 214 | } 215 | 216 | var singleton = Honeybadger(); 217 | singleton.factory = Honeybadger; 218 | module.exports = singleton; 219 | -------------------------------------------------------------------------------- /lib/logger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var defaultLevel = 'info'; 4 | 5 | function info() { 6 | if (this.level === 'info') { 7 | try { 8 | console.log.apply(console, arguments); 9 | } catch(_) {} 10 | } 11 | } 12 | 13 | function error() { 14 | if (this.level) { 15 | try { 16 | console.error.apply(console, arguments); 17 | } catch(_) {} 18 | } 19 | } 20 | 21 | module.exports = function(level) { 22 | if (!level) { level = defaultLevel; } 23 | return { 24 | level: level, 25 | info: info, 26 | error: error 27 | }; 28 | }; 29 | -------------------------------------------------------------------------------- /lib/middleware.js: -------------------------------------------------------------------------------- 1 | var url = require('url'); 2 | var domain = require('domain'); 3 | 4 | function fullUrl(req) { 5 | var connection = req.connection; 6 | var address = connection && connection.address(); 7 | var port = address ? address.port : undefined; 8 | return url.format({ 9 | protocol: req.protocol, 10 | hostname: req.hostname, 11 | port: port, 12 | pathname: req.path, 13 | query: req.query 14 | }); 15 | } 16 | 17 | function requestHandler(req, res, next) { 18 | var dom = domain.create(); 19 | dom.on('error', next); 20 | dom.run(next); 21 | } 22 | 23 | function errorHandler(err, req, res, next) { 24 | this.notify(err, { 25 | url: fullUrl(req), 26 | params: req.body, // http://expressjs.com/en/api.html#req.body 27 | session: req.session, // https://github.com/expressjs/session#reqsession 28 | headers: req.headers, // https://nodejs.org/api/http.html#http_message_headers 29 | cgiData: { 30 | REQUEST_METHOD: req.method 31 | } 32 | }); 33 | return next(err); 34 | } 35 | 36 | function lambdaHandler(handler) { 37 | return function lambdaHandler(event, context, callback) { 38 | const args = arguments; 39 | const dom = require('domain').create(); 40 | const hb = this; 41 | 42 | dom.on('error', function(err) { 43 | hb.notify(err, function() { 44 | callback(err); 45 | }); 46 | }); 47 | 48 | dom.run(function() { 49 | process.nextTick(function() { 50 | Promise.resolve(handler.apply(this, args)) 51 | .catch(function(err) { 52 | hb.notify(err, function() { 53 | callback(err); 54 | }); 55 | }) 56 | }); 57 | }); 58 | }.bind(this); 59 | } 60 | 61 | // Deprecated. 62 | function metricsHandler(req, res, next) { 63 | this.logger.error('DEPRECATION WARNING: Honeybadger.metricsHandler has no effect and will be removed.'); 64 | return next(); 65 | } 66 | 67 | module.exports = { 68 | errorHandler: errorHandler, 69 | requestHandler: requestHandler, 70 | metricsHandler: metricsHandler, 71 | lambdaHandler: lambdaHandler 72 | }; 73 | -------------------------------------------------------------------------------- /lib/notice.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var stackTrace = require('stack-trace'); 4 | var util = require('./util'); 5 | var notifier = { 6 | name: 'honeybadger-node', 7 | url: 'https://github.com/honeybadger-io/honeybadger-node', 8 | version: require('../package.json').version 9 | } 10 | 11 | function makeBacktrace(stack, cb) { 12 | return stack.map(function (c) { 13 | return cb({ 14 | number: c.lineNumber, 15 | file: c.fileName, 16 | method: c.methodName || c.functionName 17 | }); 18 | }); 19 | } 20 | 21 | function makeRequest(err) { 22 | var request = { 23 | context: err.context, 24 | params: err.params, 25 | session: err.session, 26 | component: err.component, 27 | action: err.action, 28 | url: err.url 29 | }; 30 | 31 | if (err.cgiData) { 32 | request.cgi_data = util.formatCGIData(err.cgiData); 33 | } else { 34 | request.cgi_data = {}; 35 | } 36 | 37 | if (err.headers) { 38 | request.cgi_data = util.merge(request.cgi_data, util.formatCGIData(err.headers, 'HTTP_')); 39 | } 40 | 41 | request.context = util.filter(request.context); 42 | request.cgi_data = util.filter(request.cgi_data, err.filters); 43 | request.params = util.filter(request.params, err.filters); 44 | request.session = util.filter(request.session, err.filters); 45 | 46 | return request; 47 | } 48 | 49 | function makeNotice(err, cb) { 50 | var stack; 51 | if (!cb) cb = function(f) { return f; }; 52 | if (!err.stackShift) { err.stackShift = 0; } 53 | 54 | stack = stackTrace.parse(err); 55 | if (stack.length === 0) { 56 | stack = stackTrace.parse(new Error()); 57 | for (var i = 0; i < err.stackShift; i++) { 58 | stack.shift(); 59 | } 60 | } 61 | 62 | var payload = { 63 | notifier: notifier, 64 | error: { 65 | class: err.name || 'Error', 66 | message: err.message, 67 | backtrace: makeBacktrace(stack, err.stackFilter), 68 | fingerprint: err.fingerprint 69 | }, 70 | request: makeRequest(err), 71 | server: { 72 | hostname: err.hostname, 73 | environment_name: err.environment, 74 | project_root: err.projectRoot, 75 | } 76 | }; 77 | 78 | util.getStats(function(stats) { 79 | payload.server.stats = stats; 80 | return cb(payload); 81 | }); 82 | } 83 | 84 | module.exports = makeNotice; 85 | -------------------------------------------------------------------------------- /lib/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var os = require('os'); 4 | var fs = require('fs'); 5 | 6 | function is(type, obj) { 7 | var klass = Object.prototype.toString.call(obj).slice(8, -1); 8 | return obj !== undefined && obj !== null && klass === type; 9 | } 10 | 11 | function merge(obj1, obj2) { 12 | var k, obj3 = {}; 13 | for (k in obj1) { obj3[k] = obj1[k]; } 14 | for (k in obj2) { obj3[k] = obj2[k]; } 15 | return obj3; 16 | } 17 | 18 | function getStats(cb) { 19 | var load = os.loadavg(), 20 | stats = { 21 | load: { 22 | one: load[0], 23 | five: load[1], 24 | fifteen: load[2] 25 | } 26 | }; 27 | 28 | if (fs.existsSync('/proc/meminfo')) { 29 | return fs.readFile('/proc/meminfo', 'utf8', parseStats); 30 | } 31 | fallback(); 32 | 33 | function parseStats(err, memData) { 34 | if (err) return fallback(); 35 | 36 | // The first four lines, in order, are Total, Free, Buffers, Cached. 37 | // @TODO: Figure out if there's a way to only read these lines 38 | var data = memData.split('\n').slice(0,4), 39 | results; 40 | 41 | results = data.map(function (i) { 42 | return parseInt(/\s+(\d+)\skB/i.exec(i)[1], 10) / 1024.0; 43 | }); 44 | 45 | stats.mem = { 46 | total: results[0], 47 | free: results[1], 48 | buffers: results[2], 49 | cached: results[3], 50 | free_total: results[1] + results[2] + results[3] 51 | }; 52 | return cb(stats); 53 | } 54 | 55 | function fallback() { 56 | stats.mem = { 57 | free: os.freemem(), 58 | total: os.totalmem() 59 | }; 60 | return cb(stats); 61 | } 62 | } 63 | 64 | function formatCGIData(vars, prefix) { 65 | var formattedVars = {}, 66 | prefix = prefix || ''; 67 | 68 | Object.keys(vars).forEach(function(key) { 69 | var formattedKey = prefix + key.replace(/\W/g, '_').toUpperCase(); 70 | formattedVars[formattedKey] = vars[key]; 71 | }); 72 | 73 | return formattedVars; 74 | } 75 | 76 | function filterMatch(key, filters) { 77 | var i; 78 | for (i = 0; i < filters.length; i++) { 79 | if (key.indexOf(filters[i]) !== -1) { 80 | return true; 81 | } 82 | } 83 | return false; 84 | } 85 | 86 | function filter(obj, filters) { 87 | var seen; 88 | 89 | if (!is('Object', obj)) { 90 | return; 91 | } 92 | 93 | if (!is('Array', filters)) { 94 | filters = []; 95 | } 96 | 97 | seen = []; 98 | function filter(obj) { 99 | var k, newObj; 100 | 101 | if (is('Object', obj) || is('Array', obj)) { 102 | if (seen.indexOf(obj) !== -1) { 103 | return '[CIRCULAR DATA STRUCTURE]'; 104 | } 105 | seen.push(obj); 106 | } 107 | 108 | if (is('Object', obj)) { 109 | newObj = {}; 110 | for (k in obj) { 111 | if (filterMatch(k, filters)) { 112 | newObj[k] = '[FILTERED]'; 113 | } else { 114 | newObj[k] = filter(obj[k]); 115 | } 116 | } 117 | return newObj; 118 | } 119 | 120 | if (is('Array', obj)) { 121 | return obj.map(function(v) { return filter(v); }); 122 | } 123 | 124 | if (is('Function', obj)) { return '[FUNC]'; } 125 | 126 | return obj; 127 | } 128 | 129 | return filter(obj); 130 | } 131 | 132 | module.exports = { 133 | merge: merge, 134 | getStats: getStats, 135 | formatCGIData: formatCGIData, 136 | filter: filter, 137 | is: is 138 | }; 139 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "honeybadger", 3 | "version": "1.4.1", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "honeybadger", 9 | "version": "1.4.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "request": "~2.88.0", 13 | "stack-trace": "~0.0.9" 14 | }, 15 | "devDependencies": { 16 | "express": "^4.17.1", 17 | "mocha": "^5.1.1", 18 | "nock": "^10.0.0", 19 | "sinon": "^9.0.1", 20 | "supertest": "^5.0.0" 21 | } 22 | }, 23 | "node_modules/@sinonjs/commons": { 24 | "version": "1.8.3", 25 | "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", 26 | "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", 27 | "dev": true, 28 | "dependencies": { 29 | "type-detect": "4.0.8" 30 | } 31 | }, 32 | "node_modules/@sinonjs/fake-timers": { 33 | "version": "6.0.1", 34 | "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", 35 | "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", 36 | "dev": true, 37 | "dependencies": { 38 | "@sinonjs/commons": "^1.7.0" 39 | } 40 | }, 41 | "node_modules/@sinonjs/samsam": { 42 | "version": "5.3.1", 43 | "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", 44 | "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", 45 | "dev": true, 46 | "dependencies": { 47 | "@sinonjs/commons": "^1.6.0", 48 | "lodash.get": "^4.4.2", 49 | "type-detect": "^4.0.8" 50 | } 51 | }, 52 | "node_modules/@sinonjs/text-encoding": { 53 | "version": "0.7.1", 54 | "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", 55 | "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", 56 | "dev": true 57 | }, 58 | "node_modules/accepts": { 59 | "version": "1.3.7", 60 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 61 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 62 | "dev": true, 63 | "dependencies": { 64 | "mime-types": "~2.1.24", 65 | "negotiator": "0.6.2" 66 | }, 67 | "engines": { 68 | "node": ">= 0.6" 69 | } 70 | }, 71 | "node_modules/ajv": { 72 | "version": "6.12.6", 73 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 74 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 75 | "dependencies": { 76 | "fast-deep-equal": "^3.1.1", 77 | "fast-json-stable-stringify": "^2.0.0", 78 | "json-schema-traverse": "^0.4.1", 79 | "uri-js": "^4.2.2" 80 | }, 81 | "funding": { 82 | "type": "github", 83 | "url": "https://github.com/sponsors/epoberezkin" 84 | } 85 | }, 86 | "node_modules/array-flatten": { 87 | "version": "1.1.1", 88 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 89 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", 90 | "dev": true 91 | }, 92 | "node_modules/asn1": { 93 | "version": "0.2.4", 94 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 95 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 96 | "dependencies": { 97 | "safer-buffer": "~2.1.0" 98 | } 99 | }, 100 | "node_modules/assert-plus": { 101 | "version": "1.0.0", 102 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 103 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 104 | "engines": { 105 | "node": ">=0.8" 106 | } 107 | }, 108 | "node_modules/assertion-error": { 109 | "version": "1.1.0", 110 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 111 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 112 | "dev": true, 113 | "engines": { 114 | "node": "*" 115 | } 116 | }, 117 | "node_modules/asynckit": { 118 | "version": "0.4.0", 119 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 120 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 121 | }, 122 | "node_modules/aws-sign2": { 123 | "version": "0.7.0", 124 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 125 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", 126 | "engines": { 127 | "node": "*" 128 | } 129 | }, 130 | "node_modules/aws4": { 131 | "version": "1.11.0", 132 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", 133 | "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" 134 | }, 135 | "node_modules/balanced-match": { 136 | "version": "1.0.2", 137 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 138 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 139 | "dev": true 140 | }, 141 | "node_modules/bcrypt-pbkdf": { 142 | "version": "1.0.2", 143 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 144 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 145 | "dependencies": { 146 | "tweetnacl": "^0.14.3" 147 | } 148 | }, 149 | "node_modules/body-parser": { 150 | "version": "1.19.0", 151 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 152 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 153 | "dev": true, 154 | "dependencies": { 155 | "bytes": "3.1.0", 156 | "content-type": "~1.0.4", 157 | "debug": "2.6.9", 158 | "depd": "~1.1.2", 159 | "http-errors": "1.7.2", 160 | "iconv-lite": "0.4.24", 161 | "on-finished": "~2.3.0", 162 | "qs": "6.7.0", 163 | "raw-body": "2.4.0", 164 | "type-is": "~1.6.17" 165 | }, 166 | "engines": { 167 | "node": ">= 0.8" 168 | } 169 | }, 170 | "node_modules/brace-expansion": { 171 | "version": "1.1.11", 172 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 173 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 174 | "dev": true, 175 | "dependencies": { 176 | "balanced-match": "^1.0.0", 177 | "concat-map": "0.0.1" 178 | } 179 | }, 180 | "node_modules/browser-stdout": { 181 | "version": "1.3.1", 182 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 183 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 184 | "dev": true 185 | }, 186 | "node_modules/bytes": { 187 | "version": "3.1.0", 188 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 189 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", 190 | "dev": true, 191 | "engines": { 192 | "node": ">= 0.8" 193 | } 194 | }, 195 | "node_modules/call-bind": { 196 | "version": "1.0.2", 197 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 198 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 199 | "dev": true, 200 | "dependencies": { 201 | "function-bind": "^1.1.1", 202 | "get-intrinsic": "^1.0.2" 203 | }, 204 | "funding": { 205 | "url": "https://github.com/sponsors/ljharb" 206 | } 207 | }, 208 | "node_modules/caseless": { 209 | "version": "0.12.0", 210 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 211 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 212 | }, 213 | "node_modules/chai": { 214 | "version": "4.3.4", 215 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", 216 | "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", 217 | "dev": true, 218 | "dependencies": { 219 | "assertion-error": "^1.1.0", 220 | "check-error": "^1.0.2", 221 | "deep-eql": "^3.0.1", 222 | "get-func-name": "^2.0.0", 223 | "pathval": "^1.1.1", 224 | "type-detect": "^4.0.5" 225 | }, 226 | "engines": { 227 | "node": ">=4" 228 | } 229 | }, 230 | "node_modules/check-error": { 231 | "version": "1.0.2", 232 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 233 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 234 | "dev": true, 235 | "engines": { 236 | "node": "*" 237 | } 238 | }, 239 | "node_modules/combined-stream": { 240 | "version": "1.0.8", 241 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 242 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 243 | "dependencies": { 244 | "delayed-stream": "~1.0.0" 245 | }, 246 | "engines": { 247 | "node": ">= 0.8" 248 | } 249 | }, 250 | "node_modules/commander": { 251 | "version": "2.15.1", 252 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 253 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", 254 | "dev": true 255 | }, 256 | "node_modules/component-emitter": { 257 | "version": "1.3.0", 258 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 259 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", 260 | "dev": true 261 | }, 262 | "node_modules/concat-map": { 263 | "version": "0.0.1", 264 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 265 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 266 | "dev": true 267 | }, 268 | "node_modules/content-disposition": { 269 | "version": "0.5.3", 270 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 271 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 272 | "dev": true, 273 | "dependencies": { 274 | "safe-buffer": "5.1.2" 275 | }, 276 | "engines": { 277 | "node": ">= 0.6" 278 | } 279 | }, 280 | "node_modules/content-type": { 281 | "version": "1.0.4", 282 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 283 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 284 | "dev": true, 285 | "engines": { 286 | "node": ">= 0.6" 287 | } 288 | }, 289 | "node_modules/cookie": { 290 | "version": "0.4.0", 291 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 292 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", 293 | "dev": true, 294 | "engines": { 295 | "node": ">= 0.6" 296 | } 297 | }, 298 | "node_modules/cookie-signature": { 299 | "version": "1.0.6", 300 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 301 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", 302 | "dev": true 303 | }, 304 | "node_modules/cookiejar": { 305 | "version": "2.1.2", 306 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", 307 | "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", 308 | "dev": true 309 | }, 310 | "node_modules/core-util-is": { 311 | "version": "1.0.2", 312 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 313 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 314 | }, 315 | "node_modules/dashdash": { 316 | "version": "1.14.1", 317 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 318 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 319 | "dependencies": { 320 | "assert-plus": "^1.0.0" 321 | }, 322 | "engines": { 323 | "node": ">=0.10" 324 | } 325 | }, 326 | "node_modules/debug": { 327 | "version": "2.6.9", 328 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 329 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 330 | "dev": true, 331 | "dependencies": { 332 | "ms": "2.0.0" 333 | } 334 | }, 335 | "node_modules/deep-eql": { 336 | "version": "3.0.1", 337 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 338 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 339 | "dev": true, 340 | "dependencies": { 341 | "type-detect": "^4.0.0" 342 | }, 343 | "engines": { 344 | "node": ">=0.12" 345 | } 346 | }, 347 | "node_modules/deep-equal": { 348 | "version": "1.1.1", 349 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", 350 | "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", 351 | "dev": true, 352 | "dependencies": { 353 | "is-arguments": "^1.0.4", 354 | "is-date-object": "^1.0.1", 355 | "is-regex": "^1.0.4", 356 | "object-is": "^1.0.1", 357 | "object-keys": "^1.1.1", 358 | "regexp.prototype.flags": "^1.2.0" 359 | }, 360 | "funding": { 361 | "url": "https://github.com/sponsors/ljharb" 362 | } 363 | }, 364 | "node_modules/define-properties": { 365 | "version": "1.1.3", 366 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 367 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 368 | "dev": true, 369 | "dependencies": { 370 | "object-keys": "^1.0.12" 371 | }, 372 | "engines": { 373 | "node": ">= 0.4" 374 | } 375 | }, 376 | "node_modules/delayed-stream": { 377 | "version": "1.0.0", 378 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 379 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 380 | "engines": { 381 | "node": ">=0.4.0" 382 | } 383 | }, 384 | "node_modules/depd": { 385 | "version": "1.1.2", 386 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 387 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 388 | "dev": true, 389 | "engines": { 390 | "node": ">= 0.6" 391 | } 392 | }, 393 | "node_modules/destroy": { 394 | "version": "1.0.4", 395 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 396 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 397 | "dev": true 398 | }, 399 | "node_modules/diff": { 400 | "version": "3.5.0", 401 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 402 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 403 | "dev": true, 404 | "engines": { 405 | "node": ">=0.3.1" 406 | } 407 | }, 408 | "node_modules/ecc-jsbn": { 409 | "version": "0.1.2", 410 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 411 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 412 | "dependencies": { 413 | "jsbn": "~0.1.0", 414 | "safer-buffer": "^2.1.0" 415 | } 416 | }, 417 | "node_modules/ee-first": { 418 | "version": "1.1.1", 419 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 420 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 421 | "dev": true 422 | }, 423 | "node_modules/encodeurl": { 424 | "version": "1.0.2", 425 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 426 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 427 | "dev": true, 428 | "engines": { 429 | "node": ">= 0.8" 430 | } 431 | }, 432 | "node_modules/escape-html": { 433 | "version": "1.0.3", 434 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 435 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 436 | "dev": true 437 | }, 438 | "node_modules/escape-string-regexp": { 439 | "version": "1.0.5", 440 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 441 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 442 | "dev": true, 443 | "engines": { 444 | "node": ">=0.8.0" 445 | } 446 | }, 447 | "node_modules/etag": { 448 | "version": "1.8.1", 449 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 450 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 451 | "dev": true, 452 | "engines": { 453 | "node": ">= 0.6" 454 | } 455 | }, 456 | "node_modules/express": { 457 | "version": "4.17.1", 458 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 459 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 460 | "dev": true, 461 | "dependencies": { 462 | "accepts": "~1.3.7", 463 | "array-flatten": "1.1.1", 464 | "body-parser": "1.19.0", 465 | "content-disposition": "0.5.3", 466 | "content-type": "~1.0.4", 467 | "cookie": "0.4.0", 468 | "cookie-signature": "1.0.6", 469 | "debug": "2.6.9", 470 | "depd": "~1.1.2", 471 | "encodeurl": "~1.0.2", 472 | "escape-html": "~1.0.3", 473 | "etag": "~1.8.1", 474 | "finalhandler": "~1.1.2", 475 | "fresh": "0.5.2", 476 | "merge-descriptors": "1.0.1", 477 | "methods": "~1.1.2", 478 | "on-finished": "~2.3.0", 479 | "parseurl": "~1.3.3", 480 | "path-to-regexp": "0.1.7", 481 | "proxy-addr": "~2.0.5", 482 | "qs": "6.7.0", 483 | "range-parser": "~1.2.1", 484 | "safe-buffer": "5.1.2", 485 | "send": "0.17.1", 486 | "serve-static": "1.14.1", 487 | "setprototypeof": "1.1.1", 488 | "statuses": "~1.5.0", 489 | "type-is": "~1.6.18", 490 | "utils-merge": "1.0.1", 491 | "vary": "~1.1.2" 492 | }, 493 | "engines": { 494 | "node": ">= 0.10.0" 495 | } 496 | }, 497 | "node_modules/extend": { 498 | "version": "3.0.2", 499 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 500 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 501 | }, 502 | "node_modules/extsprintf": { 503 | "version": "1.3.0", 504 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 505 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", 506 | "engines": [ 507 | "node >=0.6.0" 508 | ] 509 | }, 510 | "node_modules/fast-deep-equal": { 511 | "version": "3.1.3", 512 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 513 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 514 | }, 515 | "node_modules/fast-json-stable-stringify": { 516 | "version": "2.1.0", 517 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 518 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 519 | }, 520 | "node_modules/fast-safe-stringify": { 521 | "version": "2.0.8", 522 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz", 523 | "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==", 524 | "dev": true 525 | }, 526 | "node_modules/finalhandler": { 527 | "version": "1.1.2", 528 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 529 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 530 | "dev": true, 531 | "dependencies": { 532 | "debug": "2.6.9", 533 | "encodeurl": "~1.0.2", 534 | "escape-html": "~1.0.3", 535 | "on-finished": "~2.3.0", 536 | "parseurl": "~1.3.3", 537 | "statuses": "~1.5.0", 538 | "unpipe": "~1.0.0" 539 | }, 540 | "engines": { 541 | "node": ">= 0.8" 542 | } 543 | }, 544 | "node_modules/forever-agent": { 545 | "version": "0.6.1", 546 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 547 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 548 | "engines": { 549 | "node": "*" 550 | } 551 | }, 552 | "node_modules/form-data": { 553 | "version": "2.3.3", 554 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 555 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 556 | "dependencies": { 557 | "asynckit": "^0.4.0", 558 | "combined-stream": "^1.0.6", 559 | "mime-types": "^2.1.12" 560 | }, 561 | "engines": { 562 | "node": ">= 0.12" 563 | } 564 | }, 565 | "node_modules/formidable": { 566 | "version": "1.2.2", 567 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", 568 | "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", 569 | "dev": true, 570 | "funding": { 571 | "url": "https://ko-fi.com/tunnckoCore/commissions" 572 | } 573 | }, 574 | "node_modules/forwarded": { 575 | "version": "0.2.0", 576 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 577 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 578 | "dev": true, 579 | "engines": { 580 | "node": ">= 0.6" 581 | } 582 | }, 583 | "node_modules/fresh": { 584 | "version": "0.5.2", 585 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 586 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 587 | "dev": true, 588 | "engines": { 589 | "node": ">= 0.6" 590 | } 591 | }, 592 | "node_modules/fs.realpath": { 593 | "version": "1.0.0", 594 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 595 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 596 | "dev": true 597 | }, 598 | "node_modules/function-bind": { 599 | "version": "1.1.1", 600 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 601 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 602 | "dev": true 603 | }, 604 | "node_modules/get-func-name": { 605 | "version": "2.0.0", 606 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 607 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 608 | "dev": true, 609 | "engines": { 610 | "node": "*" 611 | } 612 | }, 613 | "node_modules/get-intrinsic": { 614 | "version": "1.1.1", 615 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 616 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 617 | "dev": true, 618 | "dependencies": { 619 | "function-bind": "^1.1.1", 620 | "has": "^1.0.3", 621 | "has-symbols": "^1.0.1" 622 | }, 623 | "funding": { 624 | "url": "https://github.com/sponsors/ljharb" 625 | } 626 | }, 627 | "node_modules/getpass": { 628 | "version": "0.1.7", 629 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 630 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 631 | "dependencies": { 632 | "assert-plus": "^1.0.0" 633 | } 634 | }, 635 | "node_modules/glob": { 636 | "version": "7.1.2", 637 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 638 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 639 | "dev": true, 640 | "dependencies": { 641 | "fs.realpath": "^1.0.0", 642 | "inflight": "^1.0.4", 643 | "inherits": "2", 644 | "minimatch": "^3.0.4", 645 | "once": "^1.3.0", 646 | "path-is-absolute": "^1.0.0" 647 | }, 648 | "engines": { 649 | "node": "*" 650 | } 651 | }, 652 | "node_modules/growl": { 653 | "version": "1.10.5", 654 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 655 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 656 | "dev": true, 657 | "engines": { 658 | "node": ">=4.x" 659 | } 660 | }, 661 | "node_modules/har-schema": { 662 | "version": "2.0.0", 663 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 664 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", 665 | "engines": { 666 | "node": ">=4" 667 | } 668 | }, 669 | "node_modules/har-validator": { 670 | "version": "5.1.5", 671 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", 672 | "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", 673 | "deprecated": "this library is no longer supported", 674 | "dependencies": { 675 | "ajv": "^6.12.3", 676 | "har-schema": "^2.0.0" 677 | }, 678 | "engines": { 679 | "node": ">=6" 680 | } 681 | }, 682 | "node_modules/has": { 683 | "version": "1.0.3", 684 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 685 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 686 | "dev": true, 687 | "dependencies": { 688 | "function-bind": "^1.1.1" 689 | }, 690 | "engines": { 691 | "node": ">= 0.4.0" 692 | } 693 | }, 694 | "node_modules/has-flag": { 695 | "version": "3.0.0", 696 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 697 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 698 | "dev": true, 699 | "engines": { 700 | "node": ">=4" 701 | } 702 | }, 703 | "node_modules/has-symbols": { 704 | "version": "1.0.2", 705 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", 706 | "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", 707 | "dev": true, 708 | "engines": { 709 | "node": ">= 0.4" 710 | }, 711 | "funding": { 712 | "url": "https://github.com/sponsors/ljharb" 713 | } 714 | }, 715 | "node_modules/has-tostringtag": { 716 | "version": "1.0.0", 717 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 718 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 719 | "dev": true, 720 | "dependencies": { 721 | "has-symbols": "^1.0.2" 722 | }, 723 | "engines": { 724 | "node": ">= 0.4" 725 | }, 726 | "funding": { 727 | "url": "https://github.com/sponsors/ljharb" 728 | } 729 | }, 730 | "node_modules/he": { 731 | "version": "1.1.1", 732 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 733 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 734 | "dev": true, 735 | "bin": { 736 | "he": "bin/he" 737 | } 738 | }, 739 | "node_modules/http-errors": { 740 | "version": "1.7.2", 741 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 742 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 743 | "dev": true, 744 | "dependencies": { 745 | "depd": "~1.1.2", 746 | "inherits": "2.0.3", 747 | "setprototypeof": "1.1.1", 748 | "statuses": ">= 1.5.0 < 2", 749 | "toidentifier": "1.0.0" 750 | }, 751 | "engines": { 752 | "node": ">= 0.6" 753 | } 754 | }, 755 | "node_modules/http-signature": { 756 | "version": "1.2.0", 757 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 758 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 759 | "dependencies": { 760 | "assert-plus": "^1.0.0", 761 | "jsprim": "^1.2.2", 762 | "sshpk": "^1.7.0" 763 | }, 764 | "engines": { 765 | "node": ">=0.8", 766 | "npm": ">=1.3.7" 767 | } 768 | }, 769 | "node_modules/iconv-lite": { 770 | "version": "0.4.24", 771 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 772 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 773 | "dev": true, 774 | "dependencies": { 775 | "safer-buffer": ">= 2.1.2 < 3" 776 | }, 777 | "engines": { 778 | "node": ">=0.10.0" 779 | } 780 | }, 781 | "node_modules/inflight": { 782 | "version": "1.0.6", 783 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 784 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 785 | "dev": true, 786 | "dependencies": { 787 | "once": "^1.3.0", 788 | "wrappy": "1" 789 | } 790 | }, 791 | "node_modules/inherits": { 792 | "version": "2.0.3", 793 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 794 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 795 | "dev": true 796 | }, 797 | "node_modules/ipaddr.js": { 798 | "version": "1.9.1", 799 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 800 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 801 | "dev": true, 802 | "engines": { 803 | "node": ">= 0.10" 804 | } 805 | }, 806 | "node_modules/is-arguments": { 807 | "version": "1.1.1", 808 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 809 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 810 | "dev": true, 811 | "dependencies": { 812 | "call-bind": "^1.0.2", 813 | "has-tostringtag": "^1.0.0" 814 | }, 815 | "engines": { 816 | "node": ">= 0.4" 817 | }, 818 | "funding": { 819 | "url": "https://github.com/sponsors/ljharb" 820 | } 821 | }, 822 | "node_modules/is-date-object": { 823 | "version": "1.0.5", 824 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", 825 | "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", 826 | "dev": true, 827 | "dependencies": { 828 | "has-tostringtag": "^1.0.0" 829 | }, 830 | "engines": { 831 | "node": ">= 0.4" 832 | }, 833 | "funding": { 834 | "url": "https://github.com/sponsors/ljharb" 835 | } 836 | }, 837 | "node_modules/is-regex": { 838 | "version": "1.1.4", 839 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", 840 | "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", 841 | "dev": true, 842 | "dependencies": { 843 | "call-bind": "^1.0.2", 844 | "has-tostringtag": "^1.0.0" 845 | }, 846 | "engines": { 847 | "node": ">= 0.4" 848 | }, 849 | "funding": { 850 | "url": "https://github.com/sponsors/ljharb" 851 | } 852 | }, 853 | "node_modules/is-typedarray": { 854 | "version": "1.0.0", 855 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 856 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 857 | }, 858 | "node_modules/isarray": { 859 | "version": "0.0.1", 860 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 861 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 862 | "dev": true 863 | }, 864 | "node_modules/isstream": { 865 | "version": "0.1.2", 866 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 867 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 868 | }, 869 | "node_modules/jsbn": { 870 | "version": "0.1.1", 871 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 872 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 873 | }, 874 | "node_modules/json-schema": { 875 | "version": "0.2.3", 876 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 877 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 878 | }, 879 | "node_modules/json-schema-traverse": { 880 | "version": "0.4.1", 881 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 882 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 883 | }, 884 | "node_modules/json-stringify-safe": { 885 | "version": "5.0.1", 886 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 887 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 888 | }, 889 | "node_modules/jsprim": { 890 | "version": "1.4.1", 891 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 892 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 893 | "engines": [ 894 | "node >=0.6.0" 895 | ], 896 | "dependencies": { 897 | "assert-plus": "1.0.0", 898 | "extsprintf": "1.3.0", 899 | "json-schema": "0.2.3", 900 | "verror": "1.10.0" 901 | } 902 | }, 903 | "node_modules/just-extend": { 904 | "version": "4.2.1", 905 | "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", 906 | "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", 907 | "dev": true 908 | }, 909 | "node_modules/lodash": { 910 | "version": "4.17.21", 911 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 912 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 913 | "dev": true 914 | }, 915 | "node_modules/lodash.get": { 916 | "version": "4.4.2", 917 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 918 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", 919 | "dev": true 920 | }, 921 | "node_modules/lru-cache": { 922 | "version": "6.0.0", 923 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 924 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 925 | "dev": true, 926 | "dependencies": { 927 | "yallist": "^4.0.0" 928 | }, 929 | "engines": { 930 | "node": ">=10" 931 | } 932 | }, 933 | "node_modules/media-typer": { 934 | "version": "0.3.0", 935 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 936 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 937 | "dev": true, 938 | "engines": { 939 | "node": ">= 0.6" 940 | } 941 | }, 942 | "node_modules/merge-descriptors": { 943 | "version": "1.0.1", 944 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 945 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 946 | "dev": true 947 | }, 948 | "node_modules/methods": { 949 | "version": "1.1.2", 950 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 951 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 952 | "dev": true, 953 | "engines": { 954 | "node": ">= 0.6" 955 | } 956 | }, 957 | "node_modules/mime": { 958 | "version": "1.6.0", 959 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 960 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 961 | "dev": true, 962 | "bin": { 963 | "mime": "cli.js" 964 | }, 965 | "engines": { 966 | "node": ">=4" 967 | } 968 | }, 969 | "node_modules/mime-db": { 970 | "version": "1.49.0", 971 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", 972 | "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", 973 | "engines": { 974 | "node": ">= 0.6" 975 | } 976 | }, 977 | "node_modules/mime-types": { 978 | "version": "2.1.32", 979 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", 980 | "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", 981 | "dependencies": { 982 | "mime-db": "1.49.0" 983 | }, 984 | "engines": { 985 | "node": ">= 0.6" 986 | } 987 | }, 988 | "node_modules/minimatch": { 989 | "version": "3.0.4", 990 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 991 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 992 | "dev": true, 993 | "dependencies": { 994 | "brace-expansion": "^1.1.7" 995 | }, 996 | "engines": { 997 | "node": "*" 998 | } 999 | }, 1000 | "node_modules/minimist": { 1001 | "version": "0.0.8", 1002 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1003 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 1004 | "dev": true 1005 | }, 1006 | "node_modules/mkdirp": { 1007 | "version": "0.5.1", 1008 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1009 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1010 | "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", 1011 | "dev": true, 1012 | "dependencies": { 1013 | "minimist": "0.0.8" 1014 | }, 1015 | "bin": { 1016 | "mkdirp": "bin/cmd.js" 1017 | } 1018 | }, 1019 | "node_modules/mocha": { 1020 | "version": "5.2.0", 1021 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", 1022 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", 1023 | "dev": true, 1024 | "dependencies": { 1025 | "browser-stdout": "1.3.1", 1026 | "commander": "2.15.1", 1027 | "debug": "3.1.0", 1028 | "diff": "3.5.0", 1029 | "escape-string-regexp": "1.0.5", 1030 | "glob": "7.1.2", 1031 | "growl": "1.10.5", 1032 | "he": "1.1.1", 1033 | "minimatch": "3.0.4", 1034 | "mkdirp": "0.5.1", 1035 | "supports-color": "5.4.0" 1036 | }, 1037 | "bin": { 1038 | "_mocha": "bin/_mocha", 1039 | "mocha": "bin/mocha" 1040 | }, 1041 | "engines": { 1042 | "node": ">= 4.0.0" 1043 | } 1044 | }, 1045 | "node_modules/mocha/node_modules/debug": { 1046 | "version": "3.1.0", 1047 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1048 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1049 | "dev": true, 1050 | "dependencies": { 1051 | "ms": "2.0.0" 1052 | } 1053 | }, 1054 | "node_modules/ms": { 1055 | "version": "2.0.0", 1056 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1057 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 1058 | "dev": true 1059 | }, 1060 | "node_modules/negotiator": { 1061 | "version": "0.6.2", 1062 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 1063 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", 1064 | "dev": true, 1065 | "engines": { 1066 | "node": ">= 0.6" 1067 | } 1068 | }, 1069 | "node_modules/nise": { 1070 | "version": "4.1.0", 1071 | "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", 1072 | "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", 1073 | "dev": true, 1074 | "dependencies": { 1075 | "@sinonjs/commons": "^1.7.0", 1076 | "@sinonjs/fake-timers": "^6.0.0", 1077 | "@sinonjs/text-encoding": "^0.7.1", 1078 | "just-extend": "^4.0.2", 1079 | "path-to-regexp": "^1.7.0" 1080 | } 1081 | }, 1082 | "node_modules/nise/node_modules/path-to-regexp": { 1083 | "version": "1.8.0", 1084 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 1085 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 1086 | "dev": true, 1087 | "dependencies": { 1088 | "isarray": "0.0.1" 1089 | } 1090 | }, 1091 | "node_modules/nock": { 1092 | "version": "10.0.6", 1093 | "resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz", 1094 | "integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==", 1095 | "dev": true, 1096 | "dependencies": { 1097 | "chai": "^4.1.2", 1098 | "debug": "^4.1.0", 1099 | "deep-equal": "^1.0.0", 1100 | "json-stringify-safe": "^5.0.1", 1101 | "lodash": "^4.17.5", 1102 | "mkdirp": "^0.5.0", 1103 | "propagate": "^1.0.0", 1104 | "qs": "^6.5.1", 1105 | "semver": "^5.5.0" 1106 | }, 1107 | "engines": { 1108 | "node": ">= 6.0" 1109 | } 1110 | }, 1111 | "node_modules/nock/node_modules/debug": { 1112 | "version": "4.3.2", 1113 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 1114 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 1115 | "dev": true, 1116 | "dependencies": { 1117 | "ms": "2.1.2" 1118 | }, 1119 | "engines": { 1120 | "node": ">=6.0" 1121 | }, 1122 | "peerDependenciesMeta": { 1123 | "supports-color": { 1124 | "optional": true 1125 | } 1126 | } 1127 | }, 1128 | "node_modules/nock/node_modules/ms": { 1129 | "version": "2.1.2", 1130 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1131 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1132 | "dev": true 1133 | }, 1134 | "node_modules/oauth-sign": { 1135 | "version": "0.9.0", 1136 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 1137 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", 1138 | "engines": { 1139 | "node": "*" 1140 | } 1141 | }, 1142 | "node_modules/object-inspect": { 1143 | "version": "1.11.0", 1144 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", 1145 | "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", 1146 | "dev": true, 1147 | "funding": { 1148 | "url": "https://github.com/sponsors/ljharb" 1149 | } 1150 | }, 1151 | "node_modules/object-is": { 1152 | "version": "1.1.5", 1153 | "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", 1154 | "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", 1155 | "dev": true, 1156 | "dependencies": { 1157 | "call-bind": "^1.0.2", 1158 | "define-properties": "^1.1.3" 1159 | }, 1160 | "engines": { 1161 | "node": ">= 0.4" 1162 | }, 1163 | "funding": { 1164 | "url": "https://github.com/sponsors/ljharb" 1165 | } 1166 | }, 1167 | "node_modules/object-keys": { 1168 | "version": "1.1.1", 1169 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1170 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1171 | "dev": true, 1172 | "engines": { 1173 | "node": ">= 0.4" 1174 | } 1175 | }, 1176 | "node_modules/on-finished": { 1177 | "version": "2.3.0", 1178 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1179 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1180 | "dev": true, 1181 | "dependencies": { 1182 | "ee-first": "1.1.1" 1183 | }, 1184 | "engines": { 1185 | "node": ">= 0.8" 1186 | } 1187 | }, 1188 | "node_modules/once": { 1189 | "version": "1.4.0", 1190 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1191 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1192 | "dev": true, 1193 | "dependencies": { 1194 | "wrappy": "1" 1195 | } 1196 | }, 1197 | "node_modules/parseurl": { 1198 | "version": "1.3.3", 1199 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1200 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1201 | "dev": true, 1202 | "engines": { 1203 | "node": ">= 0.8" 1204 | } 1205 | }, 1206 | "node_modules/path-is-absolute": { 1207 | "version": "1.0.1", 1208 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1209 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1210 | "dev": true, 1211 | "engines": { 1212 | "node": ">=0.10.0" 1213 | } 1214 | }, 1215 | "node_modules/path-to-regexp": { 1216 | "version": "0.1.7", 1217 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1218 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", 1219 | "dev": true 1220 | }, 1221 | "node_modules/pathval": { 1222 | "version": "1.1.1", 1223 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", 1224 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", 1225 | "dev": true, 1226 | "engines": { 1227 | "node": "*" 1228 | } 1229 | }, 1230 | "node_modules/performance-now": { 1231 | "version": "2.1.0", 1232 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1233 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 1234 | }, 1235 | "node_modules/propagate": { 1236 | "version": "1.0.0", 1237 | "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", 1238 | "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", 1239 | "dev": true, 1240 | "engines": [ 1241 | "node >= 0.8.1" 1242 | ] 1243 | }, 1244 | "node_modules/proxy-addr": { 1245 | "version": "2.0.7", 1246 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1247 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1248 | "dev": true, 1249 | "dependencies": { 1250 | "forwarded": "0.2.0", 1251 | "ipaddr.js": "1.9.1" 1252 | }, 1253 | "engines": { 1254 | "node": ">= 0.10" 1255 | } 1256 | }, 1257 | "node_modules/psl": { 1258 | "version": "1.8.0", 1259 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 1260 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 1261 | }, 1262 | "node_modules/punycode": { 1263 | "version": "2.1.1", 1264 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1265 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1266 | "engines": { 1267 | "node": ">=6" 1268 | } 1269 | }, 1270 | "node_modules/qs": { 1271 | "version": "6.7.0", 1272 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 1273 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", 1274 | "dev": true, 1275 | "engines": { 1276 | "node": ">=0.6" 1277 | } 1278 | }, 1279 | "node_modules/range-parser": { 1280 | "version": "1.2.1", 1281 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1282 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1283 | "dev": true, 1284 | "engines": { 1285 | "node": ">= 0.6" 1286 | } 1287 | }, 1288 | "node_modules/raw-body": { 1289 | "version": "2.4.0", 1290 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 1291 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 1292 | "dev": true, 1293 | "dependencies": { 1294 | "bytes": "3.1.0", 1295 | "http-errors": "1.7.2", 1296 | "iconv-lite": "0.4.24", 1297 | "unpipe": "1.0.0" 1298 | }, 1299 | "engines": { 1300 | "node": ">= 0.8" 1301 | } 1302 | }, 1303 | "node_modules/readable-stream": { 1304 | "version": "3.6.0", 1305 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 1306 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 1307 | "dev": true, 1308 | "dependencies": { 1309 | "inherits": "^2.0.3", 1310 | "string_decoder": "^1.1.1", 1311 | "util-deprecate": "^1.0.1" 1312 | } 1313 | }, 1314 | "node_modules/regexp.prototype.flags": { 1315 | "version": "1.3.1", 1316 | "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", 1317 | "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", 1318 | "dev": true, 1319 | "dependencies": { 1320 | "call-bind": "^1.0.2", 1321 | "define-properties": "^1.1.3" 1322 | }, 1323 | "engines": { 1324 | "node": ">= 0.4" 1325 | }, 1326 | "funding": { 1327 | "url": "https://github.com/sponsors/ljharb" 1328 | } 1329 | }, 1330 | "node_modules/request": { 1331 | "version": "2.88.2", 1332 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 1333 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 1334 | "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", 1335 | "dependencies": { 1336 | "aws-sign2": "~0.7.0", 1337 | "aws4": "^1.8.0", 1338 | "caseless": "~0.12.0", 1339 | "combined-stream": "~1.0.6", 1340 | "extend": "~3.0.2", 1341 | "forever-agent": "~0.6.1", 1342 | "form-data": "~2.3.2", 1343 | "har-validator": "~5.1.3", 1344 | "http-signature": "~1.2.0", 1345 | "is-typedarray": "~1.0.0", 1346 | "isstream": "~0.1.2", 1347 | "json-stringify-safe": "~5.0.1", 1348 | "mime-types": "~2.1.19", 1349 | "oauth-sign": "~0.9.0", 1350 | "performance-now": "^2.1.0", 1351 | "qs": "~6.5.2", 1352 | "safe-buffer": "^5.1.2", 1353 | "tough-cookie": "~2.5.0", 1354 | "tunnel-agent": "^0.6.0", 1355 | "uuid": "^3.3.2" 1356 | }, 1357 | "engines": { 1358 | "node": ">= 6" 1359 | } 1360 | }, 1361 | "node_modules/request/node_modules/qs": { 1362 | "version": "6.5.2", 1363 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1364 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", 1365 | "engines": { 1366 | "node": ">=0.6" 1367 | } 1368 | }, 1369 | "node_modules/safe-buffer": { 1370 | "version": "5.1.2", 1371 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1372 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1373 | }, 1374 | "node_modules/safer-buffer": { 1375 | "version": "2.1.2", 1376 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1377 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1378 | }, 1379 | "node_modules/semver": { 1380 | "version": "5.7.1", 1381 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1382 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1383 | "dev": true, 1384 | "bin": { 1385 | "semver": "bin/semver" 1386 | } 1387 | }, 1388 | "node_modules/send": { 1389 | "version": "0.17.1", 1390 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 1391 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 1392 | "dev": true, 1393 | "dependencies": { 1394 | "debug": "2.6.9", 1395 | "depd": "~1.1.2", 1396 | "destroy": "~1.0.4", 1397 | "encodeurl": "~1.0.2", 1398 | "escape-html": "~1.0.3", 1399 | "etag": "~1.8.1", 1400 | "fresh": "0.5.2", 1401 | "http-errors": "~1.7.2", 1402 | "mime": "1.6.0", 1403 | "ms": "2.1.1", 1404 | "on-finished": "~2.3.0", 1405 | "range-parser": "~1.2.1", 1406 | "statuses": "~1.5.0" 1407 | }, 1408 | "engines": { 1409 | "node": ">= 0.8.0" 1410 | } 1411 | }, 1412 | "node_modules/send/node_modules/ms": { 1413 | "version": "2.1.1", 1414 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1415 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 1416 | "dev": true 1417 | }, 1418 | "node_modules/serve-static": { 1419 | "version": "1.14.1", 1420 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 1421 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 1422 | "dev": true, 1423 | "dependencies": { 1424 | "encodeurl": "~1.0.2", 1425 | "escape-html": "~1.0.3", 1426 | "parseurl": "~1.3.3", 1427 | "send": "0.17.1" 1428 | }, 1429 | "engines": { 1430 | "node": ">= 0.8.0" 1431 | } 1432 | }, 1433 | "node_modules/setprototypeof": { 1434 | "version": "1.1.1", 1435 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 1436 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", 1437 | "dev": true 1438 | }, 1439 | "node_modules/side-channel": { 1440 | "version": "1.0.4", 1441 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1442 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1443 | "dev": true, 1444 | "dependencies": { 1445 | "call-bind": "^1.0.0", 1446 | "get-intrinsic": "^1.0.2", 1447 | "object-inspect": "^1.9.0" 1448 | }, 1449 | "funding": { 1450 | "url": "https://github.com/sponsors/ljharb" 1451 | } 1452 | }, 1453 | "node_modules/sinon": { 1454 | "version": "9.2.4", 1455 | "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", 1456 | "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", 1457 | "dev": true, 1458 | "dependencies": { 1459 | "@sinonjs/commons": "^1.8.1", 1460 | "@sinonjs/fake-timers": "^6.0.1", 1461 | "@sinonjs/samsam": "^5.3.1", 1462 | "diff": "^4.0.2", 1463 | "nise": "^4.0.4", 1464 | "supports-color": "^7.1.0" 1465 | }, 1466 | "funding": { 1467 | "type": "opencollective", 1468 | "url": "https://opencollective.com/sinon" 1469 | } 1470 | }, 1471 | "node_modules/sinon/node_modules/diff": { 1472 | "version": "4.0.2", 1473 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 1474 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 1475 | "dev": true, 1476 | "engines": { 1477 | "node": ">=0.3.1" 1478 | } 1479 | }, 1480 | "node_modules/sinon/node_modules/has-flag": { 1481 | "version": "4.0.0", 1482 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1483 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1484 | "dev": true, 1485 | "engines": { 1486 | "node": ">=8" 1487 | } 1488 | }, 1489 | "node_modules/sinon/node_modules/supports-color": { 1490 | "version": "7.2.0", 1491 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1492 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1493 | "dev": true, 1494 | "dependencies": { 1495 | "has-flag": "^4.0.0" 1496 | }, 1497 | "engines": { 1498 | "node": ">=8" 1499 | } 1500 | }, 1501 | "node_modules/sshpk": { 1502 | "version": "1.16.1", 1503 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 1504 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 1505 | "dependencies": { 1506 | "asn1": "~0.2.3", 1507 | "assert-plus": "^1.0.0", 1508 | "bcrypt-pbkdf": "^1.0.0", 1509 | "dashdash": "^1.12.0", 1510 | "ecc-jsbn": "~0.1.1", 1511 | "getpass": "^0.1.1", 1512 | "jsbn": "~0.1.0", 1513 | "safer-buffer": "^2.0.2", 1514 | "tweetnacl": "~0.14.0" 1515 | }, 1516 | "engines": { 1517 | "node": ">=0.10.0" 1518 | } 1519 | }, 1520 | "node_modules/stack-trace": { 1521 | "version": "0.0.10", 1522 | "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", 1523 | "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", 1524 | "engines": { 1525 | "node": "*" 1526 | } 1527 | }, 1528 | "node_modules/statuses": { 1529 | "version": "1.5.0", 1530 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1531 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 1532 | "dev": true, 1533 | "engines": { 1534 | "node": ">= 0.6" 1535 | } 1536 | }, 1537 | "node_modules/string_decoder": { 1538 | "version": "1.3.0", 1539 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 1540 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1541 | "dev": true, 1542 | "dependencies": { 1543 | "safe-buffer": "~5.2.0" 1544 | } 1545 | }, 1546 | "node_modules/string_decoder/node_modules/safe-buffer": { 1547 | "version": "5.2.1", 1548 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1549 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1550 | "dev": true, 1551 | "funding": [ 1552 | { 1553 | "type": "github", 1554 | "url": "https://github.com/sponsors/feross" 1555 | }, 1556 | { 1557 | "type": "patreon", 1558 | "url": "https://www.patreon.com/feross" 1559 | }, 1560 | { 1561 | "type": "consulting", 1562 | "url": "https://feross.org/support" 1563 | } 1564 | ] 1565 | }, 1566 | "node_modules/superagent": { 1567 | "version": "6.1.0", 1568 | "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", 1569 | "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", 1570 | "dev": true, 1571 | "dependencies": { 1572 | "component-emitter": "^1.3.0", 1573 | "cookiejar": "^2.1.2", 1574 | "debug": "^4.1.1", 1575 | "fast-safe-stringify": "^2.0.7", 1576 | "form-data": "^3.0.0", 1577 | "formidable": "^1.2.2", 1578 | "methods": "^1.1.2", 1579 | "mime": "^2.4.6", 1580 | "qs": "^6.9.4", 1581 | "readable-stream": "^3.6.0", 1582 | "semver": "^7.3.2" 1583 | }, 1584 | "engines": { 1585 | "node": ">= 4.0" 1586 | } 1587 | }, 1588 | "node_modules/superagent/node_modules/debug": { 1589 | "version": "4.3.2", 1590 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 1591 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 1592 | "dev": true, 1593 | "dependencies": { 1594 | "ms": "2.1.2" 1595 | }, 1596 | "engines": { 1597 | "node": ">=6.0" 1598 | }, 1599 | "peerDependenciesMeta": { 1600 | "supports-color": { 1601 | "optional": true 1602 | } 1603 | } 1604 | }, 1605 | "node_modules/superagent/node_modules/form-data": { 1606 | "version": "3.0.1", 1607 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", 1608 | "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", 1609 | "dev": true, 1610 | "dependencies": { 1611 | "asynckit": "^0.4.0", 1612 | "combined-stream": "^1.0.8", 1613 | "mime-types": "^2.1.12" 1614 | }, 1615 | "engines": { 1616 | "node": ">= 6" 1617 | } 1618 | }, 1619 | "node_modules/superagent/node_modules/mime": { 1620 | "version": "2.5.2", 1621 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", 1622 | "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", 1623 | "dev": true, 1624 | "bin": { 1625 | "mime": "cli.js" 1626 | }, 1627 | "engines": { 1628 | "node": ">=4.0.0" 1629 | } 1630 | }, 1631 | "node_modules/superagent/node_modules/ms": { 1632 | "version": "2.1.2", 1633 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1634 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1635 | "dev": true 1636 | }, 1637 | "node_modules/superagent/node_modules/qs": { 1638 | "version": "6.10.1", 1639 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", 1640 | "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", 1641 | "dev": true, 1642 | "dependencies": { 1643 | "side-channel": "^1.0.4" 1644 | }, 1645 | "engines": { 1646 | "node": ">=0.6" 1647 | }, 1648 | "funding": { 1649 | "url": "https://github.com/sponsors/ljharb" 1650 | } 1651 | }, 1652 | "node_modules/superagent/node_modules/semver": { 1653 | "version": "7.3.5", 1654 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 1655 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 1656 | "dev": true, 1657 | "dependencies": { 1658 | "lru-cache": "^6.0.0" 1659 | }, 1660 | "bin": { 1661 | "semver": "bin/semver.js" 1662 | }, 1663 | "engines": { 1664 | "node": ">=10" 1665 | } 1666 | }, 1667 | "node_modules/supertest": { 1668 | "version": "5.0.0", 1669 | "resolved": "https://registry.npmjs.org/supertest/-/supertest-5.0.0.tgz", 1670 | "integrity": "sha512-2JAWpPrUOZF4hHH5ZTCN2xjKXvJS3AEwPNXl0HUseHsfcXFvMy9kcsufIHCNAmQ5hlGCvgeAqaR5PBEouN3hlQ==", 1671 | "dev": true, 1672 | "dependencies": { 1673 | "methods": "1.1.2", 1674 | "superagent": "6.1.0" 1675 | }, 1676 | "engines": { 1677 | "node": ">=6.0.0" 1678 | } 1679 | }, 1680 | "node_modules/supports-color": { 1681 | "version": "5.4.0", 1682 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 1683 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 1684 | "dev": true, 1685 | "dependencies": { 1686 | "has-flag": "^3.0.0" 1687 | }, 1688 | "engines": { 1689 | "node": ">=4" 1690 | } 1691 | }, 1692 | "node_modules/toidentifier": { 1693 | "version": "1.0.0", 1694 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 1695 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", 1696 | "dev": true, 1697 | "engines": { 1698 | "node": ">=0.6" 1699 | } 1700 | }, 1701 | "node_modules/tough-cookie": { 1702 | "version": "2.5.0", 1703 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 1704 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 1705 | "dependencies": { 1706 | "psl": "^1.1.28", 1707 | "punycode": "^2.1.1" 1708 | }, 1709 | "engines": { 1710 | "node": ">=0.8" 1711 | } 1712 | }, 1713 | "node_modules/tunnel-agent": { 1714 | "version": "0.6.0", 1715 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1716 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1717 | "dependencies": { 1718 | "safe-buffer": "^5.0.1" 1719 | }, 1720 | "engines": { 1721 | "node": "*" 1722 | } 1723 | }, 1724 | "node_modules/tweetnacl": { 1725 | "version": "0.14.5", 1726 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1727 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 1728 | }, 1729 | "node_modules/type-detect": { 1730 | "version": "4.0.8", 1731 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 1732 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 1733 | "dev": true, 1734 | "engines": { 1735 | "node": ">=4" 1736 | } 1737 | }, 1738 | "node_modules/type-is": { 1739 | "version": "1.6.18", 1740 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1741 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1742 | "dev": true, 1743 | "dependencies": { 1744 | "media-typer": "0.3.0", 1745 | "mime-types": "~2.1.24" 1746 | }, 1747 | "engines": { 1748 | "node": ">= 0.6" 1749 | } 1750 | }, 1751 | "node_modules/unpipe": { 1752 | "version": "1.0.0", 1753 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1754 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 1755 | "dev": true, 1756 | "engines": { 1757 | "node": ">= 0.8" 1758 | } 1759 | }, 1760 | "node_modules/uri-js": { 1761 | "version": "4.4.1", 1762 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1763 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1764 | "dependencies": { 1765 | "punycode": "^2.1.0" 1766 | } 1767 | }, 1768 | "node_modules/util-deprecate": { 1769 | "version": "1.0.2", 1770 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1771 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 1772 | "dev": true 1773 | }, 1774 | "node_modules/utils-merge": { 1775 | "version": "1.0.1", 1776 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1777 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 1778 | "dev": true, 1779 | "engines": { 1780 | "node": ">= 0.4.0" 1781 | } 1782 | }, 1783 | "node_modules/uuid": { 1784 | "version": "3.4.0", 1785 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 1786 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", 1787 | "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", 1788 | "bin": { 1789 | "uuid": "bin/uuid" 1790 | } 1791 | }, 1792 | "node_modules/vary": { 1793 | "version": "1.1.2", 1794 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1795 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 1796 | "dev": true, 1797 | "engines": { 1798 | "node": ">= 0.8" 1799 | } 1800 | }, 1801 | "node_modules/verror": { 1802 | "version": "1.10.0", 1803 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 1804 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 1805 | "engines": [ 1806 | "node >=0.6.0" 1807 | ], 1808 | "dependencies": { 1809 | "assert-plus": "^1.0.0", 1810 | "core-util-is": "1.0.2", 1811 | "extsprintf": "^1.2.0" 1812 | } 1813 | }, 1814 | "node_modules/wrappy": { 1815 | "version": "1.0.2", 1816 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1817 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1818 | "dev": true 1819 | }, 1820 | "node_modules/yallist": { 1821 | "version": "4.0.0", 1822 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1823 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 1824 | "dev": true 1825 | } 1826 | }, 1827 | "dependencies": { 1828 | "@sinonjs/commons": { 1829 | "version": "1.8.3", 1830 | "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", 1831 | "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", 1832 | "dev": true, 1833 | "requires": { 1834 | "type-detect": "4.0.8" 1835 | } 1836 | }, 1837 | "@sinonjs/fake-timers": { 1838 | "version": "6.0.1", 1839 | "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", 1840 | "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", 1841 | "dev": true, 1842 | "requires": { 1843 | "@sinonjs/commons": "^1.7.0" 1844 | } 1845 | }, 1846 | "@sinonjs/samsam": { 1847 | "version": "5.3.1", 1848 | "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", 1849 | "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", 1850 | "dev": true, 1851 | "requires": { 1852 | "@sinonjs/commons": "^1.6.0", 1853 | "lodash.get": "^4.4.2", 1854 | "type-detect": "^4.0.8" 1855 | } 1856 | }, 1857 | "@sinonjs/text-encoding": { 1858 | "version": "0.7.1", 1859 | "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", 1860 | "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", 1861 | "dev": true 1862 | }, 1863 | "accepts": { 1864 | "version": "1.3.7", 1865 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 1866 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 1867 | "dev": true, 1868 | "requires": { 1869 | "mime-types": "~2.1.24", 1870 | "negotiator": "0.6.2" 1871 | } 1872 | }, 1873 | "ajv": { 1874 | "version": "6.12.6", 1875 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1876 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1877 | "requires": { 1878 | "fast-deep-equal": "^3.1.1", 1879 | "fast-json-stable-stringify": "^2.0.0", 1880 | "json-schema-traverse": "^0.4.1", 1881 | "uri-js": "^4.2.2" 1882 | } 1883 | }, 1884 | "array-flatten": { 1885 | "version": "1.1.1", 1886 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 1887 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", 1888 | "dev": true 1889 | }, 1890 | "asn1": { 1891 | "version": "0.2.4", 1892 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 1893 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 1894 | "requires": { 1895 | "safer-buffer": "~2.1.0" 1896 | } 1897 | }, 1898 | "assert-plus": { 1899 | "version": "1.0.0", 1900 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1901 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 1902 | }, 1903 | "assertion-error": { 1904 | "version": "1.1.0", 1905 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 1906 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 1907 | "dev": true 1908 | }, 1909 | "asynckit": { 1910 | "version": "0.4.0", 1911 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 1912 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 1913 | }, 1914 | "aws-sign2": { 1915 | "version": "0.7.0", 1916 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 1917 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 1918 | }, 1919 | "aws4": { 1920 | "version": "1.11.0", 1921 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", 1922 | "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" 1923 | }, 1924 | "balanced-match": { 1925 | "version": "1.0.2", 1926 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1927 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1928 | "dev": true 1929 | }, 1930 | "bcrypt-pbkdf": { 1931 | "version": "1.0.2", 1932 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 1933 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 1934 | "requires": { 1935 | "tweetnacl": "^0.14.3" 1936 | } 1937 | }, 1938 | "body-parser": { 1939 | "version": "1.19.0", 1940 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 1941 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 1942 | "dev": true, 1943 | "requires": { 1944 | "bytes": "3.1.0", 1945 | "content-type": "~1.0.4", 1946 | "debug": "2.6.9", 1947 | "depd": "~1.1.2", 1948 | "http-errors": "1.7.2", 1949 | "iconv-lite": "0.4.24", 1950 | "on-finished": "~2.3.0", 1951 | "qs": "6.7.0", 1952 | "raw-body": "2.4.0", 1953 | "type-is": "~1.6.17" 1954 | } 1955 | }, 1956 | "brace-expansion": { 1957 | "version": "1.1.11", 1958 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1959 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1960 | "dev": true, 1961 | "requires": { 1962 | "balanced-match": "^1.0.0", 1963 | "concat-map": "0.0.1" 1964 | } 1965 | }, 1966 | "browser-stdout": { 1967 | "version": "1.3.1", 1968 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 1969 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 1970 | "dev": true 1971 | }, 1972 | "bytes": { 1973 | "version": "3.1.0", 1974 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 1975 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", 1976 | "dev": true 1977 | }, 1978 | "call-bind": { 1979 | "version": "1.0.2", 1980 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 1981 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 1982 | "dev": true, 1983 | "requires": { 1984 | "function-bind": "^1.1.1", 1985 | "get-intrinsic": "^1.0.2" 1986 | } 1987 | }, 1988 | "caseless": { 1989 | "version": "0.12.0", 1990 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 1991 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 1992 | }, 1993 | "chai": { 1994 | "version": "4.3.4", 1995 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", 1996 | "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", 1997 | "dev": true, 1998 | "requires": { 1999 | "assertion-error": "^1.1.0", 2000 | "check-error": "^1.0.2", 2001 | "deep-eql": "^3.0.1", 2002 | "get-func-name": "^2.0.0", 2003 | "pathval": "^1.1.1", 2004 | "type-detect": "^4.0.5" 2005 | } 2006 | }, 2007 | "check-error": { 2008 | "version": "1.0.2", 2009 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 2010 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 2011 | "dev": true 2012 | }, 2013 | "combined-stream": { 2014 | "version": "1.0.8", 2015 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 2016 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 2017 | "requires": { 2018 | "delayed-stream": "~1.0.0" 2019 | } 2020 | }, 2021 | "commander": { 2022 | "version": "2.15.1", 2023 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 2024 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", 2025 | "dev": true 2026 | }, 2027 | "component-emitter": { 2028 | "version": "1.3.0", 2029 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 2030 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", 2031 | "dev": true 2032 | }, 2033 | "concat-map": { 2034 | "version": "0.0.1", 2035 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 2036 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 2037 | "dev": true 2038 | }, 2039 | "content-disposition": { 2040 | "version": "0.5.3", 2041 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 2042 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 2043 | "dev": true, 2044 | "requires": { 2045 | "safe-buffer": "5.1.2" 2046 | } 2047 | }, 2048 | "content-type": { 2049 | "version": "1.0.4", 2050 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 2051 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 2052 | "dev": true 2053 | }, 2054 | "cookie": { 2055 | "version": "0.4.0", 2056 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 2057 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", 2058 | "dev": true 2059 | }, 2060 | "cookie-signature": { 2061 | "version": "1.0.6", 2062 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 2063 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", 2064 | "dev": true 2065 | }, 2066 | "cookiejar": { 2067 | "version": "2.1.2", 2068 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", 2069 | "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", 2070 | "dev": true 2071 | }, 2072 | "core-util-is": { 2073 | "version": "1.0.2", 2074 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 2075 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 2076 | }, 2077 | "dashdash": { 2078 | "version": "1.14.1", 2079 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 2080 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 2081 | "requires": { 2082 | "assert-plus": "^1.0.0" 2083 | } 2084 | }, 2085 | "debug": { 2086 | "version": "2.6.9", 2087 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 2088 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 2089 | "dev": true, 2090 | "requires": { 2091 | "ms": "2.0.0" 2092 | } 2093 | }, 2094 | "deep-eql": { 2095 | "version": "3.0.1", 2096 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 2097 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 2098 | "dev": true, 2099 | "requires": { 2100 | "type-detect": "^4.0.0" 2101 | } 2102 | }, 2103 | "deep-equal": { 2104 | "version": "1.1.1", 2105 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", 2106 | "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", 2107 | "dev": true, 2108 | "requires": { 2109 | "is-arguments": "^1.0.4", 2110 | "is-date-object": "^1.0.1", 2111 | "is-regex": "^1.0.4", 2112 | "object-is": "^1.0.1", 2113 | "object-keys": "^1.1.1", 2114 | "regexp.prototype.flags": "^1.2.0" 2115 | } 2116 | }, 2117 | "define-properties": { 2118 | "version": "1.1.3", 2119 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 2120 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 2121 | "dev": true, 2122 | "requires": { 2123 | "object-keys": "^1.0.12" 2124 | } 2125 | }, 2126 | "delayed-stream": { 2127 | "version": "1.0.0", 2128 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 2129 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 2130 | }, 2131 | "depd": { 2132 | "version": "1.1.2", 2133 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 2134 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 2135 | "dev": true 2136 | }, 2137 | "destroy": { 2138 | "version": "1.0.4", 2139 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 2140 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 2141 | "dev": true 2142 | }, 2143 | "diff": { 2144 | "version": "3.5.0", 2145 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 2146 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 2147 | "dev": true 2148 | }, 2149 | "ecc-jsbn": { 2150 | "version": "0.1.2", 2151 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 2152 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 2153 | "requires": { 2154 | "jsbn": "~0.1.0", 2155 | "safer-buffer": "^2.1.0" 2156 | } 2157 | }, 2158 | "ee-first": { 2159 | "version": "1.1.1", 2160 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 2161 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 2162 | "dev": true 2163 | }, 2164 | "encodeurl": { 2165 | "version": "1.0.2", 2166 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 2167 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 2168 | "dev": true 2169 | }, 2170 | "escape-html": { 2171 | "version": "1.0.3", 2172 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 2173 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 2174 | "dev": true 2175 | }, 2176 | "escape-string-regexp": { 2177 | "version": "1.0.5", 2178 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 2179 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 2180 | "dev": true 2181 | }, 2182 | "etag": { 2183 | "version": "1.8.1", 2184 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 2185 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 2186 | "dev": true 2187 | }, 2188 | "express": { 2189 | "version": "4.17.1", 2190 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 2191 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 2192 | "dev": true, 2193 | "requires": { 2194 | "accepts": "~1.3.7", 2195 | "array-flatten": "1.1.1", 2196 | "body-parser": "1.19.0", 2197 | "content-disposition": "0.5.3", 2198 | "content-type": "~1.0.4", 2199 | "cookie": "0.4.0", 2200 | "cookie-signature": "1.0.6", 2201 | "debug": "2.6.9", 2202 | "depd": "~1.1.2", 2203 | "encodeurl": "~1.0.2", 2204 | "escape-html": "~1.0.3", 2205 | "etag": "~1.8.1", 2206 | "finalhandler": "~1.1.2", 2207 | "fresh": "0.5.2", 2208 | "merge-descriptors": "1.0.1", 2209 | "methods": "~1.1.2", 2210 | "on-finished": "~2.3.0", 2211 | "parseurl": "~1.3.3", 2212 | "path-to-regexp": "0.1.7", 2213 | "proxy-addr": "~2.0.5", 2214 | "qs": "6.7.0", 2215 | "range-parser": "~1.2.1", 2216 | "safe-buffer": "5.1.2", 2217 | "send": "0.17.1", 2218 | "serve-static": "1.14.1", 2219 | "setprototypeof": "1.1.1", 2220 | "statuses": "~1.5.0", 2221 | "type-is": "~1.6.18", 2222 | "utils-merge": "1.0.1", 2223 | "vary": "~1.1.2" 2224 | } 2225 | }, 2226 | "extend": { 2227 | "version": "3.0.2", 2228 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 2229 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 2230 | }, 2231 | "extsprintf": { 2232 | "version": "1.3.0", 2233 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 2234 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 2235 | }, 2236 | "fast-deep-equal": { 2237 | "version": "3.1.3", 2238 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 2239 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 2240 | }, 2241 | "fast-json-stable-stringify": { 2242 | "version": "2.1.0", 2243 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 2244 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 2245 | }, 2246 | "fast-safe-stringify": { 2247 | "version": "2.0.8", 2248 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz", 2249 | "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==", 2250 | "dev": true 2251 | }, 2252 | "finalhandler": { 2253 | "version": "1.1.2", 2254 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 2255 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 2256 | "dev": true, 2257 | "requires": { 2258 | "debug": "2.6.9", 2259 | "encodeurl": "~1.0.2", 2260 | "escape-html": "~1.0.3", 2261 | "on-finished": "~2.3.0", 2262 | "parseurl": "~1.3.3", 2263 | "statuses": "~1.5.0", 2264 | "unpipe": "~1.0.0" 2265 | } 2266 | }, 2267 | "forever-agent": { 2268 | "version": "0.6.1", 2269 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 2270 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 2271 | }, 2272 | "form-data": { 2273 | "version": "2.3.3", 2274 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 2275 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 2276 | "requires": { 2277 | "asynckit": "^0.4.0", 2278 | "combined-stream": "^1.0.6", 2279 | "mime-types": "^2.1.12" 2280 | } 2281 | }, 2282 | "formidable": { 2283 | "version": "1.2.2", 2284 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", 2285 | "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", 2286 | "dev": true 2287 | }, 2288 | "forwarded": { 2289 | "version": "0.2.0", 2290 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 2291 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 2292 | "dev": true 2293 | }, 2294 | "fresh": { 2295 | "version": "0.5.2", 2296 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 2297 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 2298 | "dev": true 2299 | }, 2300 | "fs.realpath": { 2301 | "version": "1.0.0", 2302 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 2303 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 2304 | "dev": true 2305 | }, 2306 | "function-bind": { 2307 | "version": "1.1.1", 2308 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 2309 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 2310 | "dev": true 2311 | }, 2312 | "get-func-name": { 2313 | "version": "2.0.0", 2314 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 2315 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 2316 | "dev": true 2317 | }, 2318 | "get-intrinsic": { 2319 | "version": "1.1.1", 2320 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 2321 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 2322 | "dev": true, 2323 | "requires": { 2324 | "function-bind": "^1.1.1", 2325 | "has": "^1.0.3", 2326 | "has-symbols": "^1.0.1" 2327 | } 2328 | }, 2329 | "getpass": { 2330 | "version": "0.1.7", 2331 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 2332 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 2333 | "requires": { 2334 | "assert-plus": "^1.0.0" 2335 | } 2336 | }, 2337 | "glob": { 2338 | "version": "7.1.2", 2339 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 2340 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 2341 | "dev": true, 2342 | "requires": { 2343 | "fs.realpath": "^1.0.0", 2344 | "inflight": "^1.0.4", 2345 | "inherits": "2", 2346 | "minimatch": "^3.0.4", 2347 | "once": "^1.3.0", 2348 | "path-is-absolute": "^1.0.0" 2349 | } 2350 | }, 2351 | "growl": { 2352 | "version": "1.10.5", 2353 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 2354 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 2355 | "dev": true 2356 | }, 2357 | "har-schema": { 2358 | "version": "2.0.0", 2359 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 2360 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 2361 | }, 2362 | "har-validator": { 2363 | "version": "5.1.5", 2364 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", 2365 | "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", 2366 | "requires": { 2367 | "ajv": "^6.12.3", 2368 | "har-schema": "^2.0.0" 2369 | } 2370 | }, 2371 | "has": { 2372 | "version": "1.0.3", 2373 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 2374 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 2375 | "dev": true, 2376 | "requires": { 2377 | "function-bind": "^1.1.1" 2378 | } 2379 | }, 2380 | "has-flag": { 2381 | "version": "3.0.0", 2382 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 2383 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 2384 | "dev": true 2385 | }, 2386 | "has-symbols": { 2387 | "version": "1.0.2", 2388 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", 2389 | "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", 2390 | "dev": true 2391 | }, 2392 | "has-tostringtag": { 2393 | "version": "1.0.0", 2394 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 2395 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 2396 | "dev": true, 2397 | "requires": { 2398 | "has-symbols": "^1.0.2" 2399 | } 2400 | }, 2401 | "he": { 2402 | "version": "1.1.1", 2403 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 2404 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 2405 | "dev": true 2406 | }, 2407 | "http-errors": { 2408 | "version": "1.7.2", 2409 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 2410 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 2411 | "dev": true, 2412 | "requires": { 2413 | "depd": "~1.1.2", 2414 | "inherits": "2.0.3", 2415 | "setprototypeof": "1.1.1", 2416 | "statuses": ">= 1.5.0 < 2", 2417 | "toidentifier": "1.0.0" 2418 | } 2419 | }, 2420 | "http-signature": { 2421 | "version": "1.2.0", 2422 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 2423 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 2424 | "requires": { 2425 | "assert-plus": "^1.0.0", 2426 | "jsprim": "^1.2.2", 2427 | "sshpk": "^1.7.0" 2428 | } 2429 | }, 2430 | "iconv-lite": { 2431 | "version": "0.4.24", 2432 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 2433 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 2434 | "dev": true, 2435 | "requires": { 2436 | "safer-buffer": ">= 2.1.2 < 3" 2437 | } 2438 | }, 2439 | "inflight": { 2440 | "version": "1.0.6", 2441 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 2442 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 2443 | "dev": true, 2444 | "requires": { 2445 | "once": "^1.3.0", 2446 | "wrappy": "1" 2447 | } 2448 | }, 2449 | "inherits": { 2450 | "version": "2.0.3", 2451 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 2452 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 2453 | "dev": true 2454 | }, 2455 | "ipaddr.js": { 2456 | "version": "1.9.1", 2457 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 2458 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 2459 | "dev": true 2460 | }, 2461 | "is-arguments": { 2462 | "version": "1.1.1", 2463 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 2464 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 2465 | "dev": true, 2466 | "requires": { 2467 | "call-bind": "^1.0.2", 2468 | "has-tostringtag": "^1.0.0" 2469 | } 2470 | }, 2471 | "is-date-object": { 2472 | "version": "1.0.5", 2473 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", 2474 | "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", 2475 | "dev": true, 2476 | "requires": { 2477 | "has-tostringtag": "^1.0.0" 2478 | } 2479 | }, 2480 | "is-regex": { 2481 | "version": "1.1.4", 2482 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", 2483 | "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", 2484 | "dev": true, 2485 | "requires": { 2486 | "call-bind": "^1.0.2", 2487 | "has-tostringtag": "^1.0.0" 2488 | } 2489 | }, 2490 | "is-typedarray": { 2491 | "version": "1.0.0", 2492 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 2493 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 2494 | }, 2495 | "isarray": { 2496 | "version": "0.0.1", 2497 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 2498 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 2499 | "dev": true 2500 | }, 2501 | "isstream": { 2502 | "version": "0.1.2", 2503 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 2504 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 2505 | }, 2506 | "jsbn": { 2507 | "version": "0.1.1", 2508 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 2509 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 2510 | }, 2511 | "json-schema": { 2512 | "version": "0.2.3", 2513 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 2514 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 2515 | }, 2516 | "json-schema-traverse": { 2517 | "version": "0.4.1", 2518 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 2519 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 2520 | }, 2521 | "json-stringify-safe": { 2522 | "version": "5.0.1", 2523 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 2524 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 2525 | }, 2526 | "jsprim": { 2527 | "version": "1.4.1", 2528 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 2529 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 2530 | "requires": { 2531 | "assert-plus": "1.0.0", 2532 | "extsprintf": "1.3.0", 2533 | "json-schema": "0.2.3", 2534 | "verror": "1.10.0" 2535 | } 2536 | }, 2537 | "just-extend": { 2538 | "version": "4.2.1", 2539 | "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", 2540 | "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", 2541 | "dev": true 2542 | }, 2543 | "lodash": { 2544 | "version": "4.17.21", 2545 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 2546 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 2547 | "dev": true 2548 | }, 2549 | "lodash.get": { 2550 | "version": "4.4.2", 2551 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 2552 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", 2553 | "dev": true 2554 | }, 2555 | "lru-cache": { 2556 | "version": "6.0.0", 2557 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 2558 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 2559 | "dev": true, 2560 | "requires": { 2561 | "yallist": "^4.0.0" 2562 | } 2563 | }, 2564 | "media-typer": { 2565 | "version": "0.3.0", 2566 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 2567 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 2568 | "dev": true 2569 | }, 2570 | "merge-descriptors": { 2571 | "version": "1.0.1", 2572 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 2573 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 2574 | "dev": true 2575 | }, 2576 | "methods": { 2577 | "version": "1.1.2", 2578 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 2579 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 2580 | "dev": true 2581 | }, 2582 | "mime": { 2583 | "version": "1.6.0", 2584 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 2585 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 2586 | "dev": true 2587 | }, 2588 | "mime-db": { 2589 | "version": "1.49.0", 2590 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", 2591 | "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" 2592 | }, 2593 | "mime-types": { 2594 | "version": "2.1.32", 2595 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", 2596 | "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", 2597 | "requires": { 2598 | "mime-db": "1.49.0" 2599 | } 2600 | }, 2601 | "minimatch": { 2602 | "version": "3.0.4", 2603 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 2604 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 2605 | "dev": true, 2606 | "requires": { 2607 | "brace-expansion": "^1.1.7" 2608 | } 2609 | }, 2610 | "minimist": { 2611 | "version": "0.0.8", 2612 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 2613 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 2614 | "dev": true 2615 | }, 2616 | "mkdirp": { 2617 | "version": "0.5.1", 2618 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 2619 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 2620 | "dev": true, 2621 | "requires": { 2622 | "minimist": "0.0.8" 2623 | } 2624 | }, 2625 | "mocha": { 2626 | "version": "5.2.0", 2627 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", 2628 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", 2629 | "dev": true, 2630 | "requires": { 2631 | "browser-stdout": "1.3.1", 2632 | "commander": "2.15.1", 2633 | "debug": "3.1.0", 2634 | "diff": "3.5.0", 2635 | "escape-string-regexp": "1.0.5", 2636 | "glob": "7.1.2", 2637 | "growl": "1.10.5", 2638 | "he": "1.1.1", 2639 | "minimatch": "3.0.4", 2640 | "mkdirp": "0.5.1", 2641 | "supports-color": "5.4.0" 2642 | }, 2643 | "dependencies": { 2644 | "debug": { 2645 | "version": "3.1.0", 2646 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 2647 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 2648 | "dev": true, 2649 | "requires": { 2650 | "ms": "2.0.0" 2651 | } 2652 | } 2653 | } 2654 | }, 2655 | "ms": { 2656 | "version": "2.0.0", 2657 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2658 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 2659 | "dev": true 2660 | }, 2661 | "negotiator": { 2662 | "version": "0.6.2", 2663 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 2664 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", 2665 | "dev": true 2666 | }, 2667 | "nise": { 2668 | "version": "4.1.0", 2669 | "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", 2670 | "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", 2671 | "dev": true, 2672 | "requires": { 2673 | "@sinonjs/commons": "^1.7.0", 2674 | "@sinonjs/fake-timers": "^6.0.0", 2675 | "@sinonjs/text-encoding": "^0.7.1", 2676 | "just-extend": "^4.0.2", 2677 | "path-to-regexp": "^1.7.0" 2678 | }, 2679 | "dependencies": { 2680 | "path-to-regexp": { 2681 | "version": "1.8.0", 2682 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 2683 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 2684 | "dev": true, 2685 | "requires": { 2686 | "isarray": "0.0.1" 2687 | } 2688 | } 2689 | } 2690 | }, 2691 | "nock": { 2692 | "version": "10.0.6", 2693 | "resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz", 2694 | "integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==", 2695 | "dev": true, 2696 | "requires": { 2697 | "chai": "^4.1.2", 2698 | "debug": "^4.1.0", 2699 | "deep-equal": "^1.0.0", 2700 | "json-stringify-safe": "^5.0.1", 2701 | "lodash": "^4.17.5", 2702 | "mkdirp": "^0.5.0", 2703 | "propagate": "^1.0.0", 2704 | "qs": "^6.5.1", 2705 | "semver": "^5.5.0" 2706 | }, 2707 | "dependencies": { 2708 | "debug": { 2709 | "version": "4.3.2", 2710 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 2711 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 2712 | "dev": true, 2713 | "requires": { 2714 | "ms": "2.1.2" 2715 | } 2716 | }, 2717 | "ms": { 2718 | "version": "2.1.2", 2719 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2720 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2721 | "dev": true 2722 | } 2723 | } 2724 | }, 2725 | "oauth-sign": { 2726 | "version": "0.9.0", 2727 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 2728 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 2729 | }, 2730 | "object-inspect": { 2731 | "version": "1.11.0", 2732 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", 2733 | "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", 2734 | "dev": true 2735 | }, 2736 | "object-is": { 2737 | "version": "1.1.5", 2738 | "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", 2739 | "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", 2740 | "dev": true, 2741 | "requires": { 2742 | "call-bind": "^1.0.2", 2743 | "define-properties": "^1.1.3" 2744 | } 2745 | }, 2746 | "object-keys": { 2747 | "version": "1.1.1", 2748 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 2749 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 2750 | "dev": true 2751 | }, 2752 | "on-finished": { 2753 | "version": "2.3.0", 2754 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 2755 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 2756 | "dev": true, 2757 | "requires": { 2758 | "ee-first": "1.1.1" 2759 | } 2760 | }, 2761 | "once": { 2762 | "version": "1.4.0", 2763 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2764 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2765 | "dev": true, 2766 | "requires": { 2767 | "wrappy": "1" 2768 | } 2769 | }, 2770 | "parseurl": { 2771 | "version": "1.3.3", 2772 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 2773 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 2774 | "dev": true 2775 | }, 2776 | "path-is-absolute": { 2777 | "version": "1.0.1", 2778 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2779 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 2780 | "dev": true 2781 | }, 2782 | "path-to-regexp": { 2783 | "version": "0.1.7", 2784 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 2785 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", 2786 | "dev": true 2787 | }, 2788 | "pathval": { 2789 | "version": "1.1.1", 2790 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", 2791 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", 2792 | "dev": true 2793 | }, 2794 | "performance-now": { 2795 | "version": "2.1.0", 2796 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 2797 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 2798 | }, 2799 | "propagate": { 2800 | "version": "1.0.0", 2801 | "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", 2802 | "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=", 2803 | "dev": true 2804 | }, 2805 | "proxy-addr": { 2806 | "version": "2.0.7", 2807 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 2808 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 2809 | "dev": true, 2810 | "requires": { 2811 | "forwarded": "0.2.0", 2812 | "ipaddr.js": "1.9.1" 2813 | } 2814 | }, 2815 | "psl": { 2816 | "version": "1.8.0", 2817 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 2818 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 2819 | }, 2820 | "punycode": { 2821 | "version": "2.1.1", 2822 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 2823 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 2824 | }, 2825 | "qs": { 2826 | "version": "6.7.0", 2827 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 2828 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", 2829 | "dev": true 2830 | }, 2831 | "range-parser": { 2832 | "version": "1.2.1", 2833 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 2834 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 2835 | "dev": true 2836 | }, 2837 | "raw-body": { 2838 | "version": "2.4.0", 2839 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 2840 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 2841 | "dev": true, 2842 | "requires": { 2843 | "bytes": "3.1.0", 2844 | "http-errors": "1.7.2", 2845 | "iconv-lite": "0.4.24", 2846 | "unpipe": "1.0.0" 2847 | } 2848 | }, 2849 | "readable-stream": { 2850 | "version": "3.6.0", 2851 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 2852 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 2853 | "dev": true, 2854 | "requires": { 2855 | "inherits": "^2.0.3", 2856 | "string_decoder": "^1.1.1", 2857 | "util-deprecate": "^1.0.1" 2858 | } 2859 | }, 2860 | "regexp.prototype.flags": { 2861 | "version": "1.3.1", 2862 | "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", 2863 | "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", 2864 | "dev": true, 2865 | "requires": { 2866 | "call-bind": "^1.0.2", 2867 | "define-properties": "^1.1.3" 2868 | } 2869 | }, 2870 | "request": { 2871 | "version": "2.88.2", 2872 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 2873 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 2874 | "requires": { 2875 | "aws-sign2": "~0.7.0", 2876 | "aws4": "^1.8.0", 2877 | "caseless": "~0.12.0", 2878 | "combined-stream": "~1.0.6", 2879 | "extend": "~3.0.2", 2880 | "forever-agent": "~0.6.1", 2881 | "form-data": "~2.3.2", 2882 | "har-validator": "~5.1.3", 2883 | "http-signature": "~1.2.0", 2884 | "is-typedarray": "~1.0.0", 2885 | "isstream": "~0.1.2", 2886 | "json-stringify-safe": "~5.0.1", 2887 | "mime-types": "~2.1.19", 2888 | "oauth-sign": "~0.9.0", 2889 | "performance-now": "^2.1.0", 2890 | "qs": "~6.5.2", 2891 | "safe-buffer": "^5.1.2", 2892 | "tough-cookie": "~2.5.0", 2893 | "tunnel-agent": "^0.6.0", 2894 | "uuid": "^3.3.2" 2895 | }, 2896 | "dependencies": { 2897 | "qs": { 2898 | "version": "6.5.2", 2899 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 2900 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 2901 | } 2902 | } 2903 | }, 2904 | "safe-buffer": { 2905 | "version": "5.1.2", 2906 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2907 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 2908 | }, 2909 | "safer-buffer": { 2910 | "version": "2.1.2", 2911 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2912 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 2913 | }, 2914 | "semver": { 2915 | "version": "5.7.1", 2916 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 2917 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 2918 | "dev": true 2919 | }, 2920 | "send": { 2921 | "version": "0.17.1", 2922 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 2923 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 2924 | "dev": true, 2925 | "requires": { 2926 | "debug": "2.6.9", 2927 | "depd": "~1.1.2", 2928 | "destroy": "~1.0.4", 2929 | "encodeurl": "~1.0.2", 2930 | "escape-html": "~1.0.3", 2931 | "etag": "~1.8.1", 2932 | "fresh": "0.5.2", 2933 | "http-errors": "~1.7.2", 2934 | "mime": "1.6.0", 2935 | "ms": "2.1.1", 2936 | "on-finished": "~2.3.0", 2937 | "range-parser": "~1.2.1", 2938 | "statuses": "~1.5.0" 2939 | }, 2940 | "dependencies": { 2941 | "ms": { 2942 | "version": "2.1.1", 2943 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 2944 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 2945 | "dev": true 2946 | } 2947 | } 2948 | }, 2949 | "serve-static": { 2950 | "version": "1.14.1", 2951 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 2952 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 2953 | "dev": true, 2954 | "requires": { 2955 | "encodeurl": "~1.0.2", 2956 | "escape-html": "~1.0.3", 2957 | "parseurl": "~1.3.3", 2958 | "send": "0.17.1" 2959 | } 2960 | }, 2961 | "setprototypeof": { 2962 | "version": "1.1.1", 2963 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 2964 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", 2965 | "dev": true 2966 | }, 2967 | "side-channel": { 2968 | "version": "1.0.4", 2969 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 2970 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 2971 | "dev": true, 2972 | "requires": { 2973 | "call-bind": "^1.0.0", 2974 | "get-intrinsic": "^1.0.2", 2975 | "object-inspect": "^1.9.0" 2976 | } 2977 | }, 2978 | "sinon": { 2979 | "version": "9.2.4", 2980 | "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", 2981 | "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", 2982 | "dev": true, 2983 | "requires": { 2984 | "@sinonjs/commons": "^1.8.1", 2985 | "@sinonjs/fake-timers": "^6.0.1", 2986 | "@sinonjs/samsam": "^5.3.1", 2987 | "diff": "^4.0.2", 2988 | "nise": "^4.0.4", 2989 | "supports-color": "^7.1.0" 2990 | }, 2991 | "dependencies": { 2992 | "diff": { 2993 | "version": "4.0.2", 2994 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 2995 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 2996 | "dev": true 2997 | }, 2998 | "has-flag": { 2999 | "version": "4.0.0", 3000 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 3001 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 3002 | "dev": true 3003 | }, 3004 | "supports-color": { 3005 | "version": "7.2.0", 3006 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 3007 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 3008 | "dev": true, 3009 | "requires": { 3010 | "has-flag": "^4.0.0" 3011 | } 3012 | } 3013 | } 3014 | }, 3015 | "sshpk": { 3016 | "version": "1.16.1", 3017 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 3018 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 3019 | "requires": { 3020 | "asn1": "~0.2.3", 3021 | "assert-plus": "^1.0.0", 3022 | "bcrypt-pbkdf": "^1.0.0", 3023 | "dashdash": "^1.12.0", 3024 | "ecc-jsbn": "~0.1.1", 3025 | "getpass": "^0.1.1", 3026 | "jsbn": "~0.1.0", 3027 | "safer-buffer": "^2.0.2", 3028 | "tweetnacl": "~0.14.0" 3029 | } 3030 | }, 3031 | "stack-trace": { 3032 | "version": "0.0.10", 3033 | "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", 3034 | "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" 3035 | }, 3036 | "statuses": { 3037 | "version": "1.5.0", 3038 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 3039 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 3040 | "dev": true 3041 | }, 3042 | "string_decoder": { 3043 | "version": "1.3.0", 3044 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 3045 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 3046 | "dev": true, 3047 | "requires": { 3048 | "safe-buffer": "~5.2.0" 3049 | }, 3050 | "dependencies": { 3051 | "safe-buffer": { 3052 | "version": "5.2.1", 3053 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 3054 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 3055 | "dev": true 3056 | } 3057 | } 3058 | }, 3059 | "superagent": { 3060 | "version": "6.1.0", 3061 | "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", 3062 | "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", 3063 | "dev": true, 3064 | "requires": { 3065 | "component-emitter": "^1.3.0", 3066 | "cookiejar": "^2.1.2", 3067 | "debug": "^4.1.1", 3068 | "fast-safe-stringify": "^2.0.7", 3069 | "form-data": "^3.0.0", 3070 | "formidable": "^1.2.2", 3071 | "methods": "^1.1.2", 3072 | "mime": "^2.4.6", 3073 | "qs": "^6.9.4", 3074 | "readable-stream": "^3.6.0", 3075 | "semver": "^7.3.2" 3076 | }, 3077 | "dependencies": { 3078 | "debug": { 3079 | "version": "4.3.2", 3080 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 3081 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 3082 | "dev": true, 3083 | "requires": { 3084 | "ms": "2.1.2" 3085 | } 3086 | }, 3087 | "form-data": { 3088 | "version": "3.0.1", 3089 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", 3090 | "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", 3091 | "dev": true, 3092 | "requires": { 3093 | "asynckit": "^0.4.0", 3094 | "combined-stream": "^1.0.8", 3095 | "mime-types": "^2.1.12" 3096 | } 3097 | }, 3098 | "mime": { 3099 | "version": "2.5.2", 3100 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", 3101 | "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", 3102 | "dev": true 3103 | }, 3104 | "ms": { 3105 | "version": "2.1.2", 3106 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 3107 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 3108 | "dev": true 3109 | }, 3110 | "qs": { 3111 | "version": "6.10.1", 3112 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", 3113 | "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", 3114 | "dev": true, 3115 | "requires": { 3116 | "side-channel": "^1.0.4" 3117 | } 3118 | }, 3119 | "semver": { 3120 | "version": "7.3.5", 3121 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 3122 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 3123 | "dev": true, 3124 | "requires": { 3125 | "lru-cache": "^6.0.0" 3126 | } 3127 | } 3128 | } 3129 | }, 3130 | "supertest": { 3131 | "version": "5.0.0", 3132 | "resolved": "https://registry.npmjs.org/supertest/-/supertest-5.0.0.tgz", 3133 | "integrity": "sha512-2JAWpPrUOZF4hHH5ZTCN2xjKXvJS3AEwPNXl0HUseHsfcXFvMy9kcsufIHCNAmQ5hlGCvgeAqaR5PBEouN3hlQ==", 3134 | "dev": true, 3135 | "requires": { 3136 | "methods": "1.1.2", 3137 | "superagent": "6.1.0" 3138 | } 3139 | }, 3140 | "supports-color": { 3141 | "version": "5.4.0", 3142 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 3143 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 3144 | "dev": true, 3145 | "requires": { 3146 | "has-flag": "^3.0.0" 3147 | } 3148 | }, 3149 | "toidentifier": { 3150 | "version": "1.0.0", 3151 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 3152 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", 3153 | "dev": true 3154 | }, 3155 | "tough-cookie": { 3156 | "version": "2.5.0", 3157 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 3158 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 3159 | "requires": { 3160 | "psl": "^1.1.28", 3161 | "punycode": "^2.1.1" 3162 | } 3163 | }, 3164 | "tunnel-agent": { 3165 | "version": "0.6.0", 3166 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 3167 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 3168 | "requires": { 3169 | "safe-buffer": "^5.0.1" 3170 | } 3171 | }, 3172 | "tweetnacl": { 3173 | "version": "0.14.5", 3174 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 3175 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 3176 | }, 3177 | "type-detect": { 3178 | "version": "4.0.8", 3179 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 3180 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 3181 | "dev": true 3182 | }, 3183 | "type-is": { 3184 | "version": "1.6.18", 3185 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 3186 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 3187 | "dev": true, 3188 | "requires": { 3189 | "media-typer": "0.3.0", 3190 | "mime-types": "~2.1.24" 3191 | } 3192 | }, 3193 | "unpipe": { 3194 | "version": "1.0.0", 3195 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 3196 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 3197 | "dev": true 3198 | }, 3199 | "uri-js": { 3200 | "version": "4.4.1", 3201 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 3202 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 3203 | "requires": { 3204 | "punycode": "^2.1.0" 3205 | } 3206 | }, 3207 | "util-deprecate": { 3208 | "version": "1.0.2", 3209 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 3210 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 3211 | "dev": true 3212 | }, 3213 | "utils-merge": { 3214 | "version": "1.0.1", 3215 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 3216 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 3217 | "dev": true 3218 | }, 3219 | "uuid": { 3220 | "version": "3.4.0", 3221 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 3222 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" 3223 | }, 3224 | "vary": { 3225 | "version": "1.1.2", 3226 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 3227 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 3228 | "dev": true 3229 | }, 3230 | "verror": { 3231 | "version": "1.10.0", 3232 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 3233 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 3234 | "requires": { 3235 | "assert-plus": "^1.0.0", 3236 | "core-util-is": "1.0.2", 3237 | "extsprintf": "^1.2.0" 3238 | } 3239 | }, 3240 | "wrappy": { 3241 | "version": "1.0.2", 3242 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 3243 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 3244 | "dev": true 3245 | }, 3246 | "yallist": { 3247 | "version": "4.0.0", 3248 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 3249 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 3250 | "dev": true 3251 | } 3252 | } 3253 | } 3254 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "honeybadger", 3 | "version": "1.4.1", 4 | "description": "A node.js notifier for honeybadger.io", 5 | "main": "lib/honeybadger.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "dependencies": { 10 | "request": "~2.88.0", 11 | "stack-trace": "~0.0.9" 12 | }, 13 | "devDependencies": { 14 | "express": "^4.17.1", 15 | "mocha": "^5.1.1", 16 | "nock": "^10.0.0", 17 | "sinon": "^9.0.1", 18 | "supertest": "^5.0.0" 19 | }, 20 | "scripts": { 21 | "test": "mocha", 22 | "preversion": "npm test", 23 | "version": "scripts/update-versions.sh", 24 | "postversion": "git push && git push --tags", 25 | "prepublishOnly": "npm test" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "git://github.com/honeybadger-io/honeybadger-node.git" 30 | }, 31 | "author": "Joshua Wood ", 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/honeybadger-io/honeybadger-node/issues" 35 | }, 36 | "homepage": "https://github.com/honeybadger-io/honeybadger-node" 37 | } 38 | -------------------------------------------------------------------------------- /scripts/update-versions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | VERSION=$(cat package.json | jq -r '.version') 6 | DATE=$(date +"%Y-%m-%d") 7 | 8 | if grep -q "$VERSION" "CHANGELOG.md"; then 9 | echo "Error: $VERSION already exists in CHANGELOG.md" 10 | exit 1 11 | fi 12 | 13 | # Update CHANGELOG.md 14 | nl=$'\\\n\\\n' 15 | sed -i '' "s/## \[Unreleased\]/## \[Unreleased\]$nl## \[$VERSION\] - $DATE/" CHANGELOG.md 16 | 17 | # Stage for version commit 18 | git add -A CHANGELOG.md 19 | -------------------------------------------------------------------------------- /test/honeybadger.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | sinon = require('sinon'), 3 | nock = require('nock'), 4 | Singleton = require('../lib/honeybadger'), 5 | Honeybadger; 6 | 7 | describe('Honeybadger', function () { 8 | var api, payloadCount, payloads = []; 9 | 10 | setup(function () { 11 | Honeybadger = Singleton.factory({ apiKey: 'foo' }); 12 | 13 | payloadCount = 0; 14 | payloads = []; 15 | 16 | // Don't send actual requests to honeybadger.io from the test suite 17 | nock.cleanAll(); 18 | var api = nock("https://api.honeybadger.io") 19 | .post("/v1/notices") 20 | .reply(function(uri, requestBody) { 21 | payloads.push(requestBody); 22 | return [201, '{"id":"1a327bf6-e17a-40c1-ad79-404ea1489c7a"}']; 23 | }); 24 | }); 25 | 26 | teardown(function() { 27 | Singleton.configure({ 28 | apiKey: undefined 29 | }); 30 | }); 31 | 32 | describe('#timing()', function () { 33 | it('is chainable', function () { 34 | assert.equal(Honeybadger.timing('app.request.200', 1.0), Honeybadger); 35 | }); 36 | }); 37 | 38 | describe('#increment()', function () { 39 | it('is chainable', function () { 40 | assert.equal(Honeybadger.increment('foo', 1), Honeybadger); 41 | }); 42 | }); 43 | 44 | describe('#factory()', function () { 45 | it('creates a new client instance', function () { 46 | Singleton.configure({ 47 | apiKey: 'foo' 48 | }); 49 | var subject = Singleton.factory({ apiKey: 'bar' }); 50 | assert.equal(subject.notify, Singleton.notify); 51 | assert.equal(Singleton.apiKey, 'foo'); 52 | assert.equal(subject.apiKey, 'bar'); 53 | }); 54 | }); 55 | 56 | describe('#once()', function () { 57 | it('is chainable', function () { 58 | assert.equal(Honeybadger.once('sent', function() {}), Honeybadger); 59 | }); 60 | }); 61 | 62 | describe('#on()', function () { 63 | it('is chainable', function () { 64 | assert.equal(Honeybadger.on('sent', function() {}), Honeybadger); 65 | }); 66 | }); 67 | 68 | describe('#configure()', function () { 69 | it('is chainable', function () { 70 | assert.equal(Honeybadger.configure({}), Honeybadger); 71 | }); 72 | 73 | it('throws on invalid config options', function () { 74 | assert.throws(function(){ 75 | Honeybadger.configure({ 76 | notAValidOption: 'badgers' 77 | }); 78 | }, /invalid/i); 79 | }); 80 | 81 | it('sets valid config options', function () { 82 | Honeybadger.configure({ 83 | apiKey: 'badgers', 84 | environment: 'badger_env', 85 | endpoint: 'https://www.example.com/', 86 | projectRoot: 'badger_root', 87 | hostname: 'badger_host', 88 | logger: console 89 | }); 90 | assert.equal('badgers', Honeybadger.apiKey); 91 | assert.equal('badger_env', Honeybadger.environment); 92 | assert.equal('https://www.example.com/', Honeybadger.endpoint); 93 | assert.equal('badger_root', Honeybadger.projectRoot); 94 | assert.equal('badger_host', Honeybadger.hostname); 95 | assert.equal(console, Honeybadger.logger); 96 | }); 97 | }); 98 | 99 | describe('#setContext()', function () { 100 | it('is chainable', function () { 101 | assert.equal(Honeybadger.setContext({}), Honeybadger); 102 | }); 103 | }); 104 | 105 | describe('#resetContext()', function () { 106 | it('is chainable', function () { 107 | assert.equal(Honeybadger.resetContext({}), Honeybadger); 108 | }); 109 | }); 110 | 111 | describe('#wrap()', function () { 112 | it('returns wrapped function value', function () { 113 | var fn = function(result) { 114 | return result; 115 | }; 116 | assert.equal(Honeybadger.wrap(fn)('result'), 'result'); 117 | }); 118 | 119 | it('reports errors via #notify()', function () { 120 | sinon.spy(Honeybadger, 'notify'); 121 | assert.throws(Honeybadger.wrap(function() { 122 | throw(new Error('Badgers!')); 123 | }), /Badgers!/); 124 | assert(Honeybadger.notify.called); 125 | }); 126 | }); 127 | 128 | describe('#notify()', function () { 129 | it('is chainable', function (done) { 130 | var returnValue = Honeybadger.notify(new Error('test error 1'), function() { 131 | done(); 132 | }); 133 | assert.equal(returnValue, Honeybadger); 134 | }); 135 | 136 | context('when not configured', function () { 137 | beforeEach(function (done) { 138 | Honeybadger.apiKey = undefined; 139 | payloadCount = payloads.length; 140 | Honeybadger.notify(new Error('test error that should not be sent'), function(err, notice) { 141 | done(); 142 | }); 143 | }); 144 | 145 | it('skips notification', function () { 146 | assert.equal(payloads.length, payloadCount); 147 | }); 148 | }); 149 | 150 | context('when configured', function () { 151 | beforeEach(function (done) { 152 | payloadCount = payloads.length; 153 | Honeybadger.notify(new Error('test error that should be sent'), function(err, notice) { 154 | done(); 155 | }); 156 | }); 157 | 158 | it('sends notification', function () { 159 | var p; 160 | assert.equal(payloads.length, payloadCount + 1); 161 | p = payloads[payloads.length - 1]; 162 | assert.equal(p.error.message, 'test error that should be sent'); 163 | assert.strictEqual(p.error.backtrace[0].file, "[PROJECT_ROOT]/test/honeybadger.js") 164 | }); 165 | }); 166 | 167 | context('when in a development environment', function () { 168 | beforeEach(function (done) { 169 | payloadCount = payloads.length; 170 | Honeybadger.environment = 'development'; 171 | Honeybadger.notify(new Error('test error that should not be sent'), function(err, notice) { 172 | done(); 173 | }); 174 | }); 175 | 176 | it('skips notification', function () { 177 | assert.equal(payloads.length, payloadCount); 178 | }); 179 | }); 180 | 181 | context('without a stack trace', function () { 182 | beforeEach(function (done) { 183 | payloadCount = payloads.length; 184 | Honeybadger.notify('test error (string) with no stack trace', function(err, notice) { 185 | done(); 186 | }); 187 | }); 188 | 189 | it('generates a stack trace', function () { 190 | assert.equal(payloads.length, payloadCount + 1); 191 | var p = payloads[payloads.length - 1]; 192 | assert(p.error.message.match(/no stack trace/)); 193 | assert.strictEqual(p.error.backtrace[0].file, '[PROJECT_ROOT]/test/honeybadger.js') 194 | }); 195 | }); 196 | }); 197 | 198 | // The following suites test other areas of the lib through 199 | // `Honeybadger.notify` and could be better integrated in the future (they 200 | // are from an earlier version). 201 | 202 | suite('backend logging', function () { 203 | test('logs info on success', function (done) { 204 | var spy = sinon.spy(), 205 | hb = Singleton.factory({ 206 | apiKey: 'faked', 207 | logger: {info: spy} 208 | }); 209 | 210 | hb.notify(new Error('test error'), function() { 211 | sinon.assert.calledOnce(spy); 212 | done(); 213 | }); 214 | }); 215 | 216 | test('logs error on remote failure', function (done) { 217 | var spy = sinon.spy(), 218 | hb = Singleton.factory({ 219 | apiKey: 'faked', 220 | logger: {error: spy} 221 | }); 222 | 223 | nock.cleanAll(); 224 | nock("https://api.honeybadger.io") 225 | .post("/v1/notices") 226 | .reply([403, '']); 227 | 228 | hb.notify(new Error('test error'), function() { 229 | sinon.assert.calledOnce(spy); 230 | done(); 231 | }); 232 | }); 233 | 234 | test('logs error on exception', function (done) { 235 | var spy = sinon.spy(), 236 | hb = Singleton.factory({ 237 | apiKey: 'faked', 238 | logger: {error: spy} 239 | }); 240 | 241 | nock.cleanAll(); 242 | nock("https://api.honeybadger.io") 243 | .post("/v1/notices") 244 | .replyWithError("boom"); 245 | 246 | hb.notify(new Error('test error'), function () { 247 | sinon.assert.calledOnce(spy); 248 | done(); 249 | }); 250 | }); 251 | }); 252 | 253 | suite('Stack trace filters', function () { 254 | var hb = Singleton.factory({ 255 | apiKey: 'fake api key', 256 | projectRoot: '/path/to/badgers' 257 | }); 258 | var makePayload; 259 | 260 | beforeEach(function() { 261 | payloadCount = payloads.length; 262 | }); 263 | 264 | suite('Node modules', function () { 265 | test('always substitutes node modules', function (done) { 266 | var err = new Error('Testing'); 267 | err.stack = "Error: Testing\n" + 268 | // The double node_modules ensures that the regexp is inclusive. 269 | " at Badger (/path/to/badgers/node_modules/foo/node_modules/bar/baz.js:1:0)"; 270 | hb.once('sent', function () { 271 | var p; 272 | assert(payloads.length === (payloadCount + 1), 'payload not sent'); 273 | p = payloads[payloads.length - 1]; 274 | assert(p.error.backtrace[0].file === "[NODE_MODULES]/bar/baz.js", 'node modules not substituted: ' + p.error.backtrace[0].file); 275 | done(); 276 | }); 277 | hb.notify(err); 278 | }); 279 | }); 280 | 281 | suite('Outside project root', function () { 282 | test('does not substitute outside files', function (done) { 283 | var err = new Error('Testing'); 284 | hb.once('sent', function () { 285 | var p; 286 | assert(payloads.length === (payloadCount + 1), 'payload not sent'); 287 | p = payloads[payloads.length - 1]; 288 | assert(!p.error.backtrace[0].file.match(/^\[PROJECT_ROOT\]/), 'project should not be substituted: ' + p.error.backtrace[0].file); 289 | done(); 290 | }); 291 | hb.notify(err); 292 | }); 293 | }); 294 | 295 | suite('Inside project root', function () { 296 | test('substitutes files under project root', function (done) { 297 | var err = new Error('Testing'); 298 | err.stack = "Error: Testing\n" + 299 | " at Badger (/path/to/badgers/test/honeybadger.js:258:13)"; 300 | hb.once('sent', function () { 301 | var p; 302 | assert(payloads.length === (payloadCount + 1), 'payload not sent'); 303 | p = payloads[payloads.length - 1]; 304 | assert(p.error.backtrace[0].file.match(/^\[PROJECT_ROOT\]/), 'project root not substituted: ' + p.error.backtrace[0].file); 305 | done(); 306 | }); 307 | hb.notify(err); 308 | }); 309 | }); 310 | }); 311 | 312 | 313 | suite('Passing contextual metadata with an error', function () { 314 | var hb = new Singleton.factory({ apiKey: 'fake api key' }); 315 | 316 | var meta = { 317 | context: { 318 | uid: '0xdeadbeef', 319 | email: 'test@testing.biz' 320 | }, 321 | session: { 322 | id: '1234567890', 323 | data: {a: 1, b: 2, c: 3} 324 | }, 325 | params: { 326 | arg1: 'hello' 327 | }, 328 | cookies: { 329 | omnom: 'nom' 330 | } 331 | }; 332 | 333 | test('successfully sends the payload', function (done) { 334 | payloadCount = payloads.length; 335 | hb.once('sent', function () { 336 | var p; 337 | assert(payloads.length === (payloadCount + 1), 'payload not sent'); 338 | p = payloads[payloads.length - 1]; 339 | assert(p.error.message === 'test error 4', 'payload incorrect'); 340 | done(); 341 | }); 342 | hb.notify(new Error('test error 4'), meta); 343 | }); 344 | 345 | test('The contextual metadata is passed correctly', function () { 346 | hb.once('sent', function () { 347 | var p = payloads[payloads.length - 1]; 348 | assert.deepEqual(p.request, meta, 'Metadata incorrect'); 349 | done(); 350 | }); 351 | }); 352 | }); 353 | 354 | suite('Creating a notice with cgi_data meta', function () { 355 | var hb = Singleton.factory({ 356 | apiKey: 'fake api key' 357 | }); 358 | 359 | var sampleCGIData = { 360 | 'server-software': 'Whatever server', 361 | 'custom': 'custom fields with custom DATA, !#&*' 362 | }; 363 | 364 | test('successfully sends the payload', function (done) { 365 | payloadCount = payloads.length; 366 | hb.once('sent', function () { 367 | var p; 368 | assert(payloads.length === (payloadCount + 1), 'payload not sent'); 369 | p = payloads[payloads.length - 1]; 370 | assert(p.error.message === 'test error 5', 'payload incorrect'); 371 | done(); 372 | }); 373 | hb.notify(new Error('test error 5'), { cgi_data: sampleCGIData }); 374 | }); 375 | 376 | test('transforms data keys according to the RFC 3875', function () { 377 | hb.once('sent', function () { 378 | var n; 379 | n = payloads[payloads.length - 1].request.cgi_data; 380 | assert(n['SERVER_SOFTWARE'] === sampleCGIData['server-software'], 'server-software not set'); 381 | assert(n['CUSTOM'] === sampleCGIData['custom'], 'custom not set'); 382 | assert(('custom' in n) === false, 'untransformed keys present in payload'); 383 | }); 384 | }); 385 | }); 386 | 387 | suite('Creating a notice with headers meta', function () { 388 | var hb = Singleton.factory({ 389 | apiKey: 'fake api key' 390 | }); 391 | 392 | var sampleHeaders = { 393 | 'x-forwarded-for': '1.2.3.4', 394 | 'user-agent': 'Mozilla 5.0', 395 | 'cookie': 'a=b' 396 | }; 397 | 398 | test('successfully sends the payload', function (done) { 399 | payloadCount = payloads.length; 400 | hb.once('sent', function () { 401 | var p; 402 | assert(payloads.length === (payloadCount + 1), 'payload not sent'); 403 | p = payloads[payloads.length - 1]; 404 | assert(p.error.message === 'test error 6', 'payload incorrect'); 405 | done(); 406 | }); 407 | hb.notify(new Error('test error 6'), { headers: sampleHeaders }); 408 | }); 409 | 410 | test('correctly sets the headers field in the payload', function () { 411 | hb.once('sent', function () { 412 | var n; 413 | n = payloads[payloads.length - 1].request; 414 | assert(n.cgi_data['HTTP_X_FORWARDED_FOR'] === sampleHeaders['x-forwarded-for'], 'x-forwarded-for not set'); 415 | assert(n.cgi_data['HTTP_USER_AGENT'] === sampleHeaders['user-agent'], 'user-agent not set'); 416 | assert(n.cgi_data['HTTP_COOKIE'] === sampleHeaders['cookie'], 'cookie not set'); 417 | assert(('headers' in n) === false, 'headers field is not removed from the payload'); 418 | done(); 419 | }); 420 | }); 421 | }); 422 | 423 | suite('Creating a notice with both cgi_data and headers meta', function () { 424 | var hb = Singleton.factory({ 425 | apiKey: 'fake api key' 426 | }); 427 | 428 | var sampleCGIData = { 429 | 'server-software': 'Whatever server', 430 | 'custom': 'custom fields with custom DATA, !#&*' 431 | }; 432 | 433 | var sampleHeaders = { 434 | 'user-agent': 'Mozilla 5.0', 435 | 'cookie': 'a=b' 436 | }; 437 | 438 | test('successfully sends the payload', function (done) { 439 | payloadCount = payloads.length; 440 | hb.once('sent', function () { 441 | var p; 442 | assert(payloads.length === (payloadCount + 1), 'payload not sent'); 443 | p = payloads[payloads.length - 1]; 444 | assert(p.error.message === 'test error 6', 'payload incorrect'); 445 | done(); 446 | }); 447 | hb.notify(new Error('test error 6'), { 448 | headers: sampleHeaders, 449 | cgi_data: sampleCGIData 450 | }); 451 | }); 452 | 453 | test('resultig payload has combined data from headers and cgi_data', function () { 454 | hb.once('sent', function () { 455 | var n; 456 | n = payloads[payloads.length - 1].request; 457 | assert(n.cgi_data['SERVER_SOFTWARE'] === sampleCGIData['server-software'], 'server-software not set'); 458 | assert(n.cgi_data['CUSTOM'] === sampleCGIData['custom'], 'custom not set'); 459 | assert(n.cgi_data['HTTP_USER_AGENT'] === sampleHeaders['user-agent'], 'user-agent not set'); 460 | assert(n.cgi_data['HTTP_COOKIE'] === sampleHeaders['cookie'], 'cookie not set'); 461 | assert(('custom' in n) === false, 'untransformed keys from cgi_data present in payload'); 462 | assert(('user-agent' in n) === false, 'untransformed keys from headers present in payload'); 463 | assert(('headers' in n) === false, 'headers field is not removed from the payload'); 464 | done(); 465 | }); 466 | }); 467 | }); 468 | }); 469 | -------------------------------------------------------------------------------- /test/logger.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | sinon = require('sinon'), 3 | logger = require('../lib/logger'); 4 | 5 | describe('logger', function () { 6 | var subject; 7 | 8 | setup(function () { 9 | sinon.spy(console, 'log'); 10 | sinon.spy(console, 'error'); 11 | }); 12 | 13 | teardown(function () { 14 | console.log.restore(); 15 | console.error.restore(); 16 | }); 17 | 18 | context('log level is info', function () { 19 | it('logs info', function () { 20 | subject = logger('info'); 21 | subject.info('Should be logged'); 22 | assert(console.log.called); 23 | }); 24 | 25 | it('logs error', function () { 26 | subject = logger('info'); 27 | subject.error('Should be logged'); 28 | assert(console.error.called); 29 | }); 30 | }); 31 | 32 | context('log level is error', function () { 33 | it('silences info', function () { 34 | subject = logger('error'); 35 | subject.info('Should NOT be logged'); 36 | assert(!console.log.called); 37 | }); 38 | 39 | it('logs error', function () { 40 | subject = logger('error'); 41 | subject.error('Should be logged'); 42 | assert(console.error.called); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /test/middleware.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | sinon = require('sinon'), 3 | express = require('express'), 4 | request = require('supertest'), 5 | nock = require('nock'), 6 | Singleton = require('../lib/honeybadger'); 7 | 8 | describe('Express Middleware', function () { 9 | let subject, client_mock, client; 10 | const error = new Error('Badgers!'); 11 | 12 | beforeEach(function() { 13 | client = Singleton.factory({ apiKey: 'fake api key' }); 14 | subject = client.errorHandler; 15 | client_mock = sinon.mock(client); 16 | }); 17 | 18 | it('is sane', function(done) { 19 | const app = express(); 20 | 21 | app.get('/user', function(req, res) { 22 | res.status(200).json({ name: 'john' }); 23 | }); 24 | 25 | request(app) 26 | .get('/user') 27 | .set('Accept', 'application/json') 28 | .expect('Content-Type', /json/) 29 | .expect(200, done); 30 | }); 31 | 32 | it('reports the error to Honeybadger and calls next error handler', function(done) { 33 | const app = express(); 34 | const expected = sinon.spy(); 35 | 36 | app.use(client.requestHandler); 37 | 38 | app.get('/', function(req, res) { 39 | throw(error); 40 | }); 41 | 42 | app.use(subject); 43 | 44 | app.use(function(err, req, res, next) { 45 | expected(); 46 | next(); 47 | }); 48 | 49 | client_mock.expects('notify').once().withArgs(error); 50 | 51 | request(app) 52 | .get('/') 53 | .expect(500, function() { 54 | client_mock.verify(); 55 | assert(expected.calledOnce); 56 | done(); 57 | }); 58 | }); 59 | 60 | it('reports async errors to Honeybadger and calls next error handler', function(done) { 61 | const app = express(); 62 | const expected = sinon.spy(); 63 | 64 | app.use(client.requestHandler); 65 | 66 | app.get('/', function(req, res) { 67 | setTimeout(function asyncThrow() { 68 | throw(error); 69 | }, 0); 70 | }); 71 | 72 | app.use(subject); 73 | 74 | app.use(function(err, req, res, next) { 75 | expected(); 76 | next(); 77 | }); 78 | 79 | client_mock.expects('notify').once().withArgs(error); 80 | 81 | request(app) 82 | .get('/') 83 | .expect(500, function() { 84 | client_mock.verify(); 85 | assert(expected.calledOnce); 86 | done(); 87 | }); 88 | }); 89 | 90 | it('provides a noop metricsHandler', function(done) { 91 | const app = express(); 92 | const expected = sinon.spy(); 93 | 94 | app.use(client.metricsHandler); 95 | app.use(function(req, res, next) { 96 | expected(); 97 | next(); 98 | }); 99 | 100 | request(app) 101 | .get('/') 102 | .expect(200, function() { 103 | assert(expected.calledOnce); 104 | done(); 105 | }); 106 | }); 107 | }); 108 | 109 | describe('Lambda Handler', function () { 110 | var Honeybadger = require('../lib/honeybadger').factory({ apiKey: 'fake api key' }); 111 | 112 | context('with arguments', function() { 113 | var handlerFunc; 114 | 115 | beforeEach(function(done) { 116 | handlerFunc = sinon.spy(); 117 | var handler = Honeybadger.lambdaHandler(handlerFunc); 118 | handler(1, 2, 3); 119 | process.nextTick(function() { 120 | done(); 121 | }); 122 | }); 123 | 124 | it('calls original handler with arguments', function() { 125 | assert(handlerFunc.calledWith(1, 2, 3)); 126 | }); 127 | }); 128 | 129 | context('async handlers', function() { 130 | it('reports errors to Honeybadger', function(done) { 131 | nock.cleanAll(); 132 | const api = nock("https://api.honeybadger.io") 133 | .post("/v1/notices") 134 | .reply(201, '{"id":"1a327bf6-e17a-40c1-ad79-404ea1489c7a"}') 135 | const callback = function(err) { 136 | api.done(); 137 | done(); 138 | }; 139 | 140 | var handler = Honeybadger.lambdaHandler(async function(event) { 141 | throw new Error("Badgers!"); 142 | }); 143 | 144 | handler({}, {}, callback); 145 | }); 146 | 147 | it('reports async errors to Honeybadger', function(done) { 148 | nock.cleanAll(); 149 | const api = nock("https://api.honeybadger.io") 150 | .post("/v1/notices") 151 | .reply(201, '{"id":"1a327bf6-e17a-40c1-ad79-404ea1489c7a"}') 152 | const callback = function(err) { 153 | api.done(); 154 | done(); 155 | }; 156 | 157 | var handler = Honeybadger.lambdaHandler(async function(event) { 158 | setTimeout(function() { 159 | throw new Error("Badgers!"); 160 | }, 0); 161 | }); 162 | 163 | handler({}, {}, callback); 164 | }); 165 | }); 166 | 167 | context('non-async handlers', function() { 168 | it('reports errors to Honeybadger', function(done) { 169 | nock.cleanAll(); 170 | const api = nock("https://api.honeybadger.io") 171 | .post("/v1/notices") 172 | .reply(201, '{"id":"1a327bf6-e17a-40c1-ad79-404ea1489c7a"}') 173 | const callback = function(err) { 174 | api.done(); 175 | done(); 176 | }; 177 | 178 | var handler = Honeybadger.lambdaHandler(function(_event, _context, _callback) { 179 | throw new Error("Badgers!"); 180 | }); 181 | 182 | handler({}, {}, callback); 183 | }); 184 | 185 | it('reports async errors to Honeybadger', function(done) { 186 | nock.cleanAll(); 187 | const api = nock("https://api.honeybadger.io") 188 | .post("/v1/notices") 189 | .reply(201, '{"id":"1a327bf6-e17a-40c1-ad79-404ea1489c7a"}') 190 | const callback = function(err) { 191 | api.done(); 192 | done(); 193 | }; 194 | 195 | var handler = Honeybadger.lambdaHandler(function(_event, _context, _callback) { 196 | setTimeout(function() { 197 | throw new Error("Badgers!"); 198 | }, 0); 199 | }); 200 | 201 | handler({}, {}, callback); 202 | }); 203 | }); 204 | }); 205 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | -R spec 2 | -u tdd 3 | --timeout 2000 4 | -------------------------------------------------------------------------------- /test/util.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | sinon = require('sinon'), 3 | util = require('../lib/util'); 4 | 5 | describe('util', function () { 6 | describe('.filter()', function () { 7 | it('filters top level keys', function () { 8 | var obj = { foo: 'foo', bar: 'bar' }; 9 | var subject = util.filter(obj, ['foo']); 10 | assert.deepEqual(subject, { foo: '[FILTERED]', bar: 'bar' }); 11 | }); 12 | 13 | it('filters keys of objects in arrays', function () { 14 | var obj = { top: 'top', nested: [{ foo: 'foo', bar: 'bar' }] }; 15 | var subject = util.filter(obj, ['foo']); 16 | assert.deepEqual(subject, { top: 'top', nested: [{ foo: '[FILTERED]', bar: 'bar' }] }); 17 | }); 18 | 19 | it('filters partial keys', function () { 20 | var obj = { foo: 'foo', bar_baz: 'baz' }; 21 | var subject = util.filter(obj, ['baz']); 22 | assert.deepEqual(subject, { foo: 'foo', bar_baz: '[FILTERED]' }); 23 | }); 24 | 25 | it('filters functions', function () { 26 | var obj = { foo: function(){}, bar: 'bar' }; 27 | var subject = util.filter(obj); 28 | assert.deepEqual(subject, { foo: '[FUNC]', bar: 'bar' }); 29 | }); 30 | 31 | it('filters circular objects', function () { 32 | var obj = { foo: 'foo' }; 33 | obj.bar = obj; 34 | var subject = util.filter(obj); 35 | assert.deepEqual(subject, { foo: 'foo', bar: '[CIRCULAR DATA STRUCTURE]' }); 36 | }); 37 | 38 | it('filters circular arrays', function () { 39 | var bar = []; 40 | bar.push(bar); 41 | var obj = { foo: 'foo', bar: bar }; 42 | var subject = util.filter(obj); 43 | assert.deepEqual(subject, { foo: 'foo', bar: ['[CIRCULAR DATA STRUCTURE]'] }); 44 | }); 45 | }); 46 | }); 47 | --------------------------------------------------------------------------------