├── .eslintrc.json ├── .gitignore ├── .jscsrc ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTORS.md ├── LICENSE ├── README.md ├── bin ├── coveralls.sh ├── run-tests.js └── travis.sh ├── getstream.js ├── package-lock.json ├── package.json ├── src ├── FeedManager.js ├── backends │ ├── activity.js │ ├── base.js │ ├── mongoose.js │ └── waterline.js ├── config.default.js ├── config.js └── index.js └── test ├── backend_activity_test.js ├── backends ├── base_test.js ├── mongoose_test.js └── waterline_test.js ├── feed_manager_test.js ├── index_test.js └── utils └── promise.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [], 3 | "extends": ["eslint:recommended"], 4 | "rules": { 5 | "no-console": 0, 6 | "no-mixed-spaces-and-tabs": 1, 7 | "comma-dangle": 0, 8 | "no-unused-vars": 1, 9 | "linebreak-style": [2, "unix"], 10 | "semi": [1, "always"] 11 | }, 12 | "env": { 13 | "es6": false, 14 | "browser": true, 15 | "commonjs": true, 16 | "mocha": true 17 | }, 18 | "globals": { 19 | "process": true 20 | }, 21 | "ecmaFeatures": { 22 | "modules": true 23 | }, 24 | "parserOptions": {} 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | 30 | # DS_Store 31 | .DS_Store 32 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "airbnb", 3 | "requirePaddingNewLinesBeforeLineComments": null, 4 | "disallowQuotedKeysInObjects": false, 5 | "disallowMultipleVarDecl": false, 6 | "requireDotNotation": false, 7 | "safeContextKeyword": null, 8 | "validateIndentation": 4, 9 | } 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | - "10" 5 | - "12" 6 | - "14" 7 | env: 8 | - MONGOOSE_VERSION=4.11.8 STREAM_URL='https://key:secret@us-east.getstream.io/?app_id=42' 9 | matrix: 10 | include: 11 | - node_js: 10 12 | env: MONGOOSE_VERSION=4.0 13 | before_script: 14 | - npm install mongoose@$MONGOOSE_VERSION 15 | script: 16 | - bash ./bin/travis.sh 17 | services: 18 | - mongodb 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 2.0.0 - 13-07-2020 4 | 5 | * Breaking change: Drop support for node v11, v13 and below v10 6 | 7 | 8 | ## 1.0.0 - 25-11-2015 9 | 10 | * Breaking change: enrichActivities and enrichAggregatedActivities no longer accept a callback but return a promise 11 | * Breaking change: No longer register a schema to be an ActivitySchema through activitySchema method but build an ActivitySchema object from ActivitySchemaFactory 12 | - Creating a FeedManager can now also be done with custom settings (not loaded via getstream.json) through the method feedManagerFactory 13 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | Stream-Example-Nodejs 2 | ============================================ 3 | 4 | * **[Mario Delgado](https://github.com/peachepe)** 5 | 6 | * **[Tommaso Barbugli](https://github.com/tbarbugli)** 7 | 8 | * **[Thierry Schellenbach](https://github.com/tschellenbach)** 9 | 10 | * **[Matthisk Heimensen](https://github.com/matthisk)** 11 | 12 | * **[Nick Parsons](https://github.com/nparsons08)** 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Stream.io, Inc 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Stream Node.js 2 | 3 | [![Build Status](https://travis-ci.org/tbarbugli/stream-node.svg)](https://travis-ci.org/tbarbugli/stream-node) 4 | [![npm version](https://badge.fury.io/js/getstream-node.svg)](http://badge.fury.io/js/getstream-node) 5 | [![Coverage Status](https://coveralls.io/repos/github/GetStream/stream-node-orm/badge.svg?branch=refactor-tests)](https://coveralls.io/github/GetStream/stream-node-orm?branch=refactor-tests) 6 | 7 | [![NPM](https://nodei.co/npm/getstream-node.png)](https://nodei.co/npm/getstream-node/) 8 | 9 | [stream-node-orm](https://github.com/GetStream/stream-node-orm) is a Node.js (Mongoose & Waterline) client for [Stream](https://getstream.io/). 10 | 11 | You can sign up for a Stream account at https://getstream.io/get_started. 12 | 13 | Note there is also a lower level [Node.js - Stream integration](https://github.com/getstream/stream-js) library which is suitable for all JavaScript applications. 14 | 15 | ### Build Activity Streams & News Feeds 16 | 17 |

18 | Examples of what you can build 19 |

20 | 21 | You can build: 22 | 23 | * Activity streams such as those seen on Github 24 | * A Twitter style newsfeed 25 | * A feed like Instagram or Pinterest 26 | * Facebook style newsfeeds 27 | * A notification system 28 | 29 | ### Supported ORMs 30 | 31 | Stream node currently supports: 32 | 33 | * Mongoose (full support, both serialization and enrichment) 34 | * Waterline (partial support, enrichment only) 35 | 36 | ### Demo 37 | 38 | You can check out our example app on Github [https://github.com/GetStream/Stream-Example-Nodejs](https://github.com/GetStream/Stream-Example-Nodejs) 39 | 40 | ### Installation 41 | 42 | #### Step 1 - NPM 43 | 44 | Install getstream_node package with npm: 45 | 46 | ```npm install getstream-node --save``` 47 | 48 | #### Step 2 - Config file 49 | 50 | Copy `getstream.js` config file from `node_modules/getstream-node` into the root directory of your application 51 | Make sure you require the getstream-node early on in your application (eg. in app.js) 52 | 53 | #### Step 3 - Get your API key 54 | 55 | Login with Github on [getstream.io](https://getstream.io/) and edit the configuration values for 56 | ```apiKey```, ```apiSecret``` and ```apiAppId``` in your `getstream.js` file (you can find them in the [dashboard](https://getstream.io/dashboard/)). 57 | 58 | ### Model integration 59 | 60 | Stream Node.js can automatically publish new activities to your feeds. To do that you only need to register the models you want to publish with this library. 61 | 62 | ```js 63 | var stream = require('getstream-node'); 64 | 65 | var tweetSchema = Schema({ 66 | text : String, 67 | user : { type: Schema.Types.ObjectId, ref: 'User' } 68 | }); 69 | 70 | tweetSchema.plugin(stream.mongoose.activity); 71 | 72 | // register your mongoose connection with the library 73 | stream.mongoose.setupMongoose(mongoose); 74 | ``` 75 | 76 | Every time a Tweet is created it will be added to the user's feed. Users which follow the given user will also automatically get the new tweet in their feeds. 77 | 78 | #### Activity Fields 79 | 80 | Models are stored in feeds as activities. An activity is composed of at least the following fields: **actor**, **verb**, **object**, **time**. You can also add more custom data if needed. 81 | The Activity mixin will try to set things up automatically: 82 | 83 | **object** is a reference to the model instance 84 | **actor** is a reference to the user attribute of the instance 85 | **verb** is a string representation of the class name 86 | 87 | By default the actor field will look for an attribute called user or actor and a field called created_at to track creation time. 88 | If your user field is called differently you'll need to tell us where to look for it. 89 | Below shows an example how to set things up if your user field is called author. 90 | 91 | ```js 92 | var tweetSchema = Schema({ 93 | text : String, 94 | author : { type: Schema.Types.ObjectId, ref: 'User' } 95 | }); 96 | 97 | tweetSchema.plugin(stream.mongoose.activity); 98 | 99 | tweetSchema.methods.activityActorProp = function() { 100 | return 'author'; 101 | } 102 | ``` 103 | 104 | #### Customizing the Activity 105 | 106 | Sometimes you'll want full control over the activity that's send to getstream.io. 107 | To do that you can overwrite the default createActivity method on the model 108 | 109 | ```js 110 | tweetSchema.methods.createActivity = function() { 111 | // this is the default createActivity code, customize as you see fit. 112 | var activity = {}; 113 | var extra_data = this.activityExtraData(); 114 | for (var key in extra_data) { 115 | activity[key] = extra_data[key]; 116 | } 117 | activity.to = (this.activityNotify() || []).map(function(x){return x.id}); 118 | activity.actor = this.activityActor(); 119 | activity.verb = this.activityVerb(); 120 | activity.object = this.activityObject(); 121 | activity.foreign_id = this.activityForeignId(); 122 | if (this.activityTime()) { 123 | activity.time = this.activityTime(); 124 | } 125 | return activity; 126 | } 127 | ``` 128 | 129 | ### Feed Manager 130 | 131 | This packages comes with a feed_manager class that helps with all common feed operations. 132 | 133 | #### Feeds Bundled with feed_manager 134 | 135 | To get you started the manager has 4 feeds pre-configured. You can add more feeds if your application needs it. 136 | The three feeds are divided in three categories. 137 | 138 | ##### User Feed: 139 | The user feed stores all activities for a user. Think of it as your personal Facebook page. You can easily get this feed from the manager. 140 | ```js 141 | FeedManager.getUserFeed(req.user.id); 142 | ``` 143 | 144 | ##### News Feeds: 145 | The news feeds store the activities from the people you follow. 146 | There is both a flat newsfeed (similar to twitter) and an aggregated newsfeed (like facebook). 147 | 148 | ```js 149 | var flatFeed = FeedManager.getNewsFeeds(foundUser._id)['timeline_flat']; 150 | var aggregatedFeed = FeedManager.getNewsFeeds(req.user.id)['timeline_aggregated']; 151 | ``` 152 | 153 | ##### Notification Feed: 154 | The notification feed can be used to build notification functionality. 155 | 156 |

157 | Notification feed 158 | 159 | Below we show an example of how you can read the notification feed. 160 | ```js 161 | var notificationFeed = FeedManager.getNotificationFeed(req.user.id); 162 | ``` 163 | 164 | By default the notification feed will be empty. You can specify which users to notify when your model gets created. In the case of a retweet you probably want to notify the user of the parent tweet. 165 | 166 | ```js 167 | tweetSchema.methods.activityNotify = function() { 168 | if (this.isRetweet) { 169 | target_feed = FeedManager.getNotificationFeed(this.parent.author.id); 170 | return [target_feed]; 171 | } 172 | }; 173 | ``` 174 | 175 | Another example would be following a user. You would commonly want to notify the user which is being followed. 176 | 177 | ```js 178 | followSchema.methods.activityNotify = function() { 179 | target_feed = FeedManager.getNotificationFeed(this.target._id); 180 | return [target_feed]; 181 | }; 182 | ``` 183 | 184 | #### Follow a Feed 185 | To follow the created newsfeeds you need to notify the system about follow relationships. The manager comes with APIs to let a user's news feeds follow another user's feed. This code lets the current user's flat and aggregated feeds follow the target_user's personal feed. 186 | 187 | ``` 188 | FeedManager.followUser(userId, targetId); 189 | ``` 190 | 191 | ### Showing the Newsfeed 192 | 193 | #### Activity Enrichment 194 | 195 | When you read data from feeds, a like activity will look like this: 196 | 197 | ```js 198 | {'actor': 'User:1', 'verb': 'like', 'object': 'Like:42'} 199 | ``` 200 | 201 | This is far from ready for usage in your template. We call the process of loading the references from the database enrichment. An example is shown below: 202 | 203 | ```js 204 | router.get('/flat', ensureAuthenticated, function(req, res, next){ 205 | var flatFeed = FeedManager.getNewsFeeds(req.user.id)['timeline_flat']; 206 | 207 | flatFeed.get({}) 208 | .then(function (body) { 209 | var activities = body.results; 210 | return StreamBackend.enrichActivities(activities); 211 | }) 212 | .then(function (enrichedActivities) { 213 | return res.render('feed', {location: 'feed', user: req.user, activities: enrichedActivities, path: req.url}); 214 | }) 215 | .catch(next) 216 | }); 217 | }); 218 | ``` 219 | 220 | Promises are used to pipe the asynchronous result of `flatFeed.get` and `StreamBackend.enrichActivities` through our code. 221 | 222 | ### Temporarily Disabling the Model Sync 223 | 224 | Model synchronization can be disabled manually via environment variable. 225 | 226 | ```js 227 | NODE_ENV=test npm test 228 | ``` 229 | 230 | #### Automatically Populate Paths: 231 | 232 | You can automatically populate paths during enrichment via the pathsToPopulate static. 233 | 234 | ```js 235 | tweetSchema.statics.pathsToPopulate = function() { 236 | return ['link']; 237 | }; 238 | ``` 239 | 240 | ### Full Documentation and Low Level APIs Access 241 | 242 | When needed you can also use the [low level JavaScript API](https://github.com/getstream/stream-js) directly. Documentation is available at the [Stream website](https://getstream.io/docs/?language=js). 243 | 244 | ```js 245 | var streamNode = require('getstream-node'); 246 | var client = streamNode.FeedManager.client 247 | // client.addActivity, client.removeActivity etc are all available 248 | ``` 249 | 250 | ### Enrichment 251 | 252 | You can use the enrichment capabilities of this library directly. 253 | 254 | ```js 255 | var streamNode = require('getstream-node'); 256 | var streamMongoose = new streamNode.MongooseBackend() 257 | // or 258 | var streamWaterline = new streamNode.WaterlineBackend() 259 | // now enrich the activities 260 | streamWaterline.enrichActivities(activities).then(function(enrichedActivities) { 261 | res.json({'results': enrichedActivities}) 262 | }).catch(function(err) { 263 | sails.log.error('enrichment failed', err) 264 | return res.serverError('failed to load articles in the feed') 265 | }) 266 | ``` 267 | 268 | ### Customizing Enrichment (since 1.4.0) 269 | 270 | By default the enrichment system assumes that you're referencing items by their id. Sometimes you'll want to customize this behavior. You might for instance use a username instead of an id. Alternatively you might mant to use a caching layer instead of the ORM for loading the data. The example below shows how to customize the lookup for all User entries. 271 | 272 | ```js 273 | // subclass streamMongoose 274 | function streamCustomEnrichment() {}; 275 | streamCustomEnrichment.prototype = { 276 | loadUserFromStorage: function(modelClass, objectsIds, callback) { 277 | var found = {}; 278 | var paths = []; 279 | if (typeof(modelClass.pathsToPopulate) === 'function') { 280 | var paths = modelClass.pathsToPopulate(); 281 | } 282 | // Here's the magic, use a username instead of id 283 | modelClass.find({ 284 | username: { 285 | $in: objectsIds 286 | } 287 | }).populate(paths).exec(function(err, docs) { 288 | for (var i in docs) { 289 | found[docs[i]._id] = docs[i]; 290 | } 291 | callback(err, found); 292 | }); 293 | } 294 | } 295 | util.inherits(streamCustomEnrichment, streamNode.mongoose.Backend); 296 | ``` 297 | 298 | ### Contributing 299 | 300 | Running tests: 301 | 302 | ``` 303 | npm test 304 | ``` 305 | 306 | ### Releasing 307 | 308 | Make sure your working directory is clean and run: 309 | 310 | ``` 311 | npm install 312 | npm version [ major | minor | patch ] 313 | npm publish 314 | ``` 315 | 316 | ### Supported Node.js Versions 317 | ``` 318 | v10.x 319 | v12.x 320 | v14.x 321 | ``` 322 | 323 | ### Copyright and License Information 324 | 325 | Copyright (c) 2015-2017 Stream.io Inc, and individual contributors. All rights reserved. 326 | 327 | See the file "LICENSE" for information on the history of this software, terms & conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. 328 | -------------------------------------------------------------------------------- /bin/coveralls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | istanbul cover ./bin/run-tests.js --report lcov 4 | cat ./coverage/lcov.info | ./node_modules/.bin/coveralls 5 | rm -rf ./coverage 6 | -------------------------------------------------------------------------------- /bin/run-tests.js: -------------------------------------------------------------------------------- 1 | var Mocha = require('mocha'), 2 | glob = require('glob'), 3 | path = require('path'); 4 | 5 | var mocha = new Mocha({}); 6 | 7 | var files = glob.sync('../test/**/*_test.js', { cwd: __dirname }); 8 | 9 | files.forEach(function(file) { 10 | file = path.join(__dirname, file); 11 | mocha.addFile(file); 12 | }); 13 | 14 | /* istanbul ignore next */ 15 | mocha.run(function(failures) { 16 | process.on('exit', function() { 17 | process.exit(failures); 18 | }); 19 | 20 | process.exit(); 21 | }); 22 | -------------------------------------------------------------------------------- /bin/travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | npm test 4 | ./bin/coveralls.sh 5 | -------------------------------------------------------------------------------- /getstream.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | /** 3 | * GetStream.io API key 4 | */ 5 | apiKey: '', 6 | 7 | /** 8 | * GetStream.io API Secret 9 | */ 10 | apiSecret: '', 11 | 12 | /** 13 | * GetStream.io API App ID 14 | */ 15 | apiAppId: '', 16 | 17 | /** 18 | * GetStream.io API Location 19 | */ 20 | apiLocation: '', 21 | 22 | /** 23 | * GetStream.io User Feed slug 24 | */ 25 | userFeed: 'user', 26 | 27 | /** 28 | * GetStream.io Notification Feed slug 29 | */ 30 | notificationFeed: 'notification', 31 | 32 | newsFeeds: { 33 | /** 34 | * GetStream.io Flat Feed slug 35 | */ 36 | flat: 'flat', 37 | 38 | /** 39 | * GetStream.io Aggregated Feed slug 40 | */ 41 | aggregated: 'aggregated', 42 | }, 43 | }; 44 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getstream-node", 3 | "version": "2.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/runtime": { 8 | "version": "7.10.4", 9 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", 10 | "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", 11 | "requires": { 12 | "regenerator-runtime": "^0.13.4" 13 | }, 14 | "dependencies": { 15 | "regenerator-runtime": { 16 | "version": "0.13.5", 17 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", 18 | "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" 19 | } 20 | } 21 | }, 22 | "Base64": { 23 | "version": "1.1.0", 24 | "resolved": "https://registry.npmjs.org/Base64/-/Base64-1.1.0.tgz", 25 | "integrity": "sha512-qeacf8dvGpf+XAT27ESHMh7z84uRzj/ua2pQdJg483m3bEXv/kVFtDnMgvf70BQGqzbZhR9t6BmASzKvqfJf3Q==" 26 | }, 27 | "JSV": { 28 | "version": "4.0.2", 29 | "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", 30 | "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=", 31 | "dev": true 32 | }, 33 | "abbrev": { 34 | "version": "1.0.9", 35 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", 36 | "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", 37 | "dev": true 38 | }, 39 | "acorn": { 40 | "version": "5.7.4", 41 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", 42 | "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", 43 | "dev": true 44 | }, 45 | "acorn-jsx": { 46 | "version": "3.0.1", 47 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 48 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 49 | "dev": true, 50 | "requires": { 51 | "acorn": "^3.0.4" 52 | }, 53 | "dependencies": { 54 | "acorn": { 55 | "version": "3.3.0", 56 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 57 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", 58 | "dev": true 59 | } 60 | } 61 | }, 62 | "ajv": { 63 | "version": "5.5.2", 64 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 65 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 66 | "dev": true, 67 | "requires": { 68 | "co": "^4.6.0", 69 | "fast-deep-equal": "^1.0.0", 70 | "fast-json-stable-stringify": "^2.0.0", 71 | "json-schema-traverse": "^0.3.0" 72 | } 73 | }, 74 | "ajv-keywords": { 75 | "version": "2.1.1", 76 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", 77 | "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", 78 | "dev": true 79 | }, 80 | "align-text": { 81 | "version": "0.1.4", 82 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 83 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 84 | "dev": true, 85 | "optional": true, 86 | "requires": { 87 | "kind-of": "^3.0.2", 88 | "longest": "^1.0.1", 89 | "repeat-string": "^1.5.2" 90 | } 91 | }, 92 | "amdefine": { 93 | "version": "1.0.1", 94 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 95 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", 96 | "dev": true 97 | }, 98 | "ansi-escapes": { 99 | "version": "3.2.0", 100 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 101 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", 102 | "dev": true 103 | }, 104 | "ansi-regex": { 105 | "version": "2.1.1", 106 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 107 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 108 | "dev": true 109 | }, 110 | "ansi-styles": { 111 | "version": "2.2.1", 112 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 113 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 114 | "dev": true 115 | }, 116 | "argparse": { 117 | "version": "1.0.9", 118 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", 119 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", 120 | "dev": true, 121 | "requires": { 122 | "sprintf-js": "~1.0.2" 123 | } 124 | }, 125 | "asap": { 126 | "version": "2.0.6", 127 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 128 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" 129 | }, 130 | "asn1": { 131 | "version": "0.2.3", 132 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 133 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", 134 | "dev": true 135 | }, 136 | "assert-plus": { 137 | "version": "0.2.0", 138 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", 139 | "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", 140 | "dev": true 141 | }, 142 | "async": { 143 | "version": "3.2.0", 144 | "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", 145 | "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" 146 | }, 147 | "asynckit": { 148 | "version": "0.4.0", 149 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 150 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 151 | }, 152 | "aws-sign2": { 153 | "version": "0.6.0", 154 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", 155 | "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", 156 | "dev": true 157 | }, 158 | "aws4": { 159 | "version": "1.6.0", 160 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", 161 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", 162 | "dev": true 163 | }, 164 | "axios": { 165 | "version": "0.19.2", 166 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", 167 | "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", 168 | "requires": { 169 | "follow-redirects": "1.5.10" 170 | } 171 | }, 172 | "babel-code-frame": { 173 | "version": "6.26.0", 174 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 175 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 176 | "dev": true, 177 | "requires": { 178 | "chalk": "^1.1.3", 179 | "esutils": "^2.0.2", 180 | "js-tokens": "^3.0.2" 181 | } 182 | }, 183 | "babel-runtime": { 184 | "version": "6.26.0", 185 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", 186 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", 187 | "dev": true, 188 | "requires": { 189 | "core-js": "^2.4.0", 190 | "regenerator-runtime": "^0.11.0" 191 | } 192 | }, 193 | "babylon": { 194 | "version": "6.18.0", 195 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", 196 | "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", 197 | "dev": true 198 | }, 199 | "balanced-match": { 200 | "version": "1.0.0", 201 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 202 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 203 | "dev": true 204 | }, 205 | "bcrypt-pbkdf": { 206 | "version": "1.0.1", 207 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 208 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", 209 | "dev": true, 210 | "optional": true, 211 | "requires": { 212 | "tweetnacl": "^0.14.3" 213 | } 214 | }, 215 | "better-assert": { 216 | "version": "1.0.2", 217 | "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", 218 | "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", 219 | "dev": true, 220 | "requires": { 221 | "callsite": "1.0.0" 222 | } 223 | }, 224 | "bl": { 225 | "version": "2.2.0", 226 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", 227 | "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", 228 | "requires": { 229 | "readable-stream": "^2.3.5", 230 | "safe-buffer": "^5.1.1" 231 | }, 232 | "dependencies": { 233 | "isarray": { 234 | "version": "1.0.0", 235 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 236 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 237 | }, 238 | "process-nextick-args": { 239 | "version": "2.0.1", 240 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 241 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 242 | }, 243 | "readable-stream": { 244 | "version": "2.3.7", 245 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 246 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 247 | "requires": { 248 | "core-util-is": "~1.0.0", 249 | "inherits": "~2.0.3", 250 | "isarray": "~1.0.0", 251 | "process-nextick-args": "~2.0.0", 252 | "safe-buffer": "~5.1.1", 253 | "string_decoder": "~1.1.1", 254 | "util-deprecate": "~1.0.1" 255 | } 256 | }, 257 | "string_decoder": { 258 | "version": "1.1.1", 259 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 260 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 261 | "requires": { 262 | "safe-buffer": "~5.1.0" 263 | } 264 | } 265 | } 266 | }, 267 | "bluebird": { 268 | "version": "3.5.1", 269 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 270 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 271 | }, 272 | "boom": { 273 | "version": "2.10.1", 274 | "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", 275 | "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", 276 | "dev": true, 277 | "requires": { 278 | "hoek": "2.x.x" 279 | } 280 | }, 281 | "brace-expansion": { 282 | "version": "1.1.8", 283 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 284 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 285 | "dev": true, 286 | "requires": { 287 | "balanced-match": "^1.0.0", 288 | "concat-map": "0.0.1" 289 | } 290 | }, 291 | "browser-stdout": { 292 | "version": "1.3.0", 293 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", 294 | "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", 295 | "dev": true 296 | }, 297 | "bson": { 298 | "version": "1.0.4", 299 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", 300 | "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=", 301 | "dev": true 302 | }, 303 | "buffer-equal-constant-time": { 304 | "version": "1.0.1", 305 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 306 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" 307 | }, 308 | "buffer-from": { 309 | "version": "1.1.1", 310 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 311 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 312 | "dev": true 313 | }, 314 | "buffer-shims": { 315 | "version": "1.0.0", 316 | "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", 317 | "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", 318 | "dev": true 319 | }, 320 | "caller-path": { 321 | "version": "0.1.0", 322 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", 323 | "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", 324 | "dev": true, 325 | "requires": { 326 | "callsites": "^0.2.0" 327 | } 328 | }, 329 | "callsite": { 330 | "version": "1.0.0", 331 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", 332 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", 333 | "dev": true 334 | }, 335 | "callsites": { 336 | "version": "0.2.0", 337 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", 338 | "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", 339 | "dev": true 340 | }, 341 | "camelcase": { 342 | "version": "1.2.1", 343 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 344 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 345 | "dev": true, 346 | "optional": true 347 | }, 348 | "center-align": { 349 | "version": "0.1.3", 350 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 351 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 352 | "dev": true, 353 | "optional": true, 354 | "requires": { 355 | "align-text": "^0.1.3", 356 | "lazy-cache": "^1.0.3" 357 | } 358 | }, 359 | "chalk": { 360 | "version": "1.1.3", 361 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 362 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 363 | "dev": true, 364 | "requires": { 365 | "ansi-styles": "^2.2.1", 366 | "escape-string-regexp": "^1.0.2", 367 | "has-ansi": "^2.0.0", 368 | "strip-ansi": "^3.0.0", 369 | "supports-color": "^2.0.0" 370 | }, 371 | "dependencies": { 372 | "supports-color": { 373 | "version": "2.0.0", 374 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 375 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 376 | "dev": true 377 | } 378 | } 379 | }, 380 | "chardet": { 381 | "version": "0.4.2", 382 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 383 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", 384 | "dev": true 385 | }, 386 | "circular-json": { 387 | "version": "0.3.3", 388 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 389 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", 390 | "dev": true 391 | }, 392 | "cli-cursor": { 393 | "version": "2.1.0", 394 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 395 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 396 | "dev": true, 397 | "requires": { 398 | "restore-cursor": "^2.0.0" 399 | } 400 | }, 401 | "cli-table": { 402 | "version": "0.3.1", 403 | "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", 404 | "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", 405 | "dev": true, 406 | "requires": { 407 | "colors": "1.0.3" 408 | } 409 | }, 410 | "cli-width": { 411 | "version": "2.2.1", 412 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", 413 | "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", 414 | "dev": true 415 | }, 416 | "cliui": { 417 | "version": "2.1.0", 418 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 419 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 420 | "dev": true, 421 | "optional": true, 422 | "requires": { 423 | "center-align": "^0.1.1", 424 | "right-align": "^0.1.1", 425 | "wordwrap": "0.0.2" 426 | }, 427 | "dependencies": { 428 | "wordwrap": { 429 | "version": "0.0.2", 430 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 431 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 432 | "dev": true, 433 | "optional": true 434 | } 435 | } 436 | }, 437 | "co": { 438 | "version": "4.6.0", 439 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 440 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 441 | "dev": true 442 | }, 443 | "color-convert": { 444 | "version": "1.9.3", 445 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 446 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 447 | "dev": true, 448 | "requires": { 449 | "color-name": "1.1.3" 450 | } 451 | }, 452 | "color-name": { 453 | "version": "1.1.3", 454 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 455 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 456 | "dev": true 457 | }, 458 | "colors": { 459 | "version": "1.0.3", 460 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", 461 | "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", 462 | "dev": true 463 | }, 464 | "combined-stream": { 465 | "version": "1.0.5", 466 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", 467 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", 468 | "dev": true, 469 | "requires": { 470 | "delayed-stream": "~1.0.0" 471 | } 472 | }, 473 | "commander": { 474 | "version": "2.9.0", 475 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", 476 | "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", 477 | "dev": true, 478 | "requires": { 479 | "graceful-readlink": ">= 1.0.0" 480 | } 481 | }, 482 | "comment-parser": { 483 | "version": "0.3.2", 484 | "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.3.2.tgz", 485 | "integrity": "sha1-PAPwd2uGo239mgosl8YwfzMggv4=", 486 | "dev": true, 487 | "requires": { 488 | "readable-stream": "^2.0.4" 489 | } 490 | }, 491 | "concat-map": { 492 | "version": "0.0.1", 493 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 494 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 495 | "dev": true 496 | }, 497 | "concat-stream": { 498 | "version": "1.6.2", 499 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 500 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 501 | "dev": true, 502 | "requires": { 503 | "buffer-from": "^1.0.0", 504 | "inherits": "^2.0.3", 505 | "readable-stream": "^2.2.2", 506 | "typedarray": "^0.0.6" 507 | } 508 | }, 509 | "core-js": { 510 | "version": "2.5.0", 511 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.0.tgz", 512 | "integrity": "sha1-VpwFCRi+ZIazg3VSAorgRmtxcIY=", 513 | "dev": true 514 | }, 515 | "core-util-is": { 516 | "version": "1.0.2", 517 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 518 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 519 | }, 520 | "coveralls": { 521 | "version": "2.13.1", 522 | "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.1.tgz", 523 | "integrity": "sha1-1wu5rMGDXsTwY/+drFQjwXsR8Xg=", 524 | "dev": true, 525 | "requires": { 526 | "js-yaml": "3.6.1", 527 | "lcov-parse": "0.0.10", 528 | "log-driver": "1.2.5", 529 | "minimist": "1.2.0", 530 | "request": "2.79.0" 531 | }, 532 | "dependencies": { 533 | "caseless": { 534 | "version": "0.11.0", 535 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", 536 | "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", 537 | "dev": true 538 | }, 539 | "har-validator": { 540 | "version": "2.0.6", 541 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", 542 | "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", 543 | "dev": true, 544 | "requires": { 545 | "chalk": "^1.1.1", 546 | "commander": "^2.9.0", 547 | "is-my-json-valid": "^2.12.4", 548 | "pinkie-promise": "^2.0.0" 549 | } 550 | }, 551 | "js-yaml": { 552 | "version": "3.6.1", 553 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", 554 | "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", 555 | "dev": true, 556 | "requires": { 557 | "argparse": "^1.0.7", 558 | "esprima": "^2.6.0" 559 | } 560 | }, 561 | "minimist": { 562 | "version": "1.2.0", 563 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 564 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 565 | "dev": true 566 | }, 567 | "qs": { 568 | "version": "6.3.2", 569 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", 570 | "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", 571 | "dev": true 572 | }, 573 | "request": { 574 | "version": "2.79.0", 575 | "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", 576 | "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", 577 | "dev": true, 578 | "requires": { 579 | "aws-sign2": "~0.6.0", 580 | "aws4": "^1.2.1", 581 | "caseless": "~0.11.0", 582 | "combined-stream": "~1.0.5", 583 | "extend": "~3.0.0", 584 | "forever-agent": "~0.6.1", 585 | "form-data": "~2.1.1", 586 | "har-validator": "~2.0.6", 587 | "hawk": "~3.1.3", 588 | "http-signature": "~1.1.0", 589 | "is-typedarray": "~1.0.0", 590 | "isstream": "~0.1.2", 591 | "json-stringify-safe": "~5.0.1", 592 | "mime-types": "~2.1.7", 593 | "oauth-sign": "~0.8.1", 594 | "qs": "~6.3.0", 595 | "stringstream": "~0.0.4", 596 | "tough-cookie": "~2.3.0", 597 | "tunnel-agent": "~0.4.1", 598 | "uuid": "^3.0.0" 599 | }, 600 | "dependencies": { 601 | "extend": { 602 | "version": "3.0.1", 603 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 604 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", 605 | "dev": true 606 | } 607 | } 608 | }, 609 | "tunnel-agent": { 610 | "version": "0.4.3", 611 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", 612 | "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", 613 | "dev": true 614 | } 615 | } 616 | }, 617 | "cross-spawn": { 618 | "version": "5.1.0", 619 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 620 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 621 | "dev": true, 622 | "requires": { 623 | "lru-cache": "^4.0.1", 624 | "shebang-command": "^1.2.0", 625 | "which": "^1.2.9" 626 | } 627 | }, 628 | "cryptiles": { 629 | "version": "2.0.5", 630 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", 631 | "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", 632 | "dev": true, 633 | "requires": { 634 | "boom": "2.x.x" 635 | } 636 | }, 637 | "csprng": { 638 | "version": "0.1.2", 639 | "resolved": "https://registry.npmjs.org/csprng/-/csprng-0.1.2.tgz", 640 | "integrity": "sha1-S8aPEvo2jSUqWYQcusqXSxirReI=", 641 | "requires": { 642 | "sequin": "*" 643 | } 644 | }, 645 | "cst": { 646 | "version": "0.4.10", 647 | "resolved": "https://registry.npmjs.org/cst/-/cst-0.4.10.tgz", 648 | "integrity": "sha512-U5ETe1IOjq2h56ZcBE3oe9rT7XryCH6IKgPMv0L7sSk6w29yR3p5egCK0T3BDNHHV95OoUBgXsqiVG+3a900Ag==", 649 | "dev": true, 650 | "requires": { 651 | "babel-runtime": "^6.9.2", 652 | "babylon": "^6.8.1", 653 | "source-map-support": "^0.4.0" 654 | } 655 | }, 656 | "cycle": { 657 | "version": "1.0.3", 658 | "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", 659 | "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", 660 | "dev": true 661 | }, 662 | "dashdash": { 663 | "version": "1.14.1", 664 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 665 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 666 | "dev": true, 667 | "requires": { 668 | "assert-plus": "^1.0.0" 669 | }, 670 | "dependencies": { 671 | "assert-plus": { 672 | "version": "1.0.0", 673 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 674 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 675 | "dev": true 676 | } 677 | } 678 | }, 679 | "debug": { 680 | "version": "2.6.8", 681 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", 682 | "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", 683 | "dev": true, 684 | "requires": { 685 | "ms": "2.0.0" 686 | } 687 | }, 688 | "decamelize": { 689 | "version": "1.2.0", 690 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 691 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 692 | "dev": true, 693 | "optional": true 694 | }, 695 | "deep-equal": { 696 | "version": "1.0.1", 697 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", 698 | "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", 699 | "dev": true 700 | }, 701 | "deep-is": { 702 | "version": "0.1.3", 703 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 704 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 705 | "dev": true 706 | }, 707 | "delayed-stream": { 708 | "version": "1.0.0", 709 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 710 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 711 | }, 712 | "denque": { 713 | "version": "1.4.1", 714 | "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", 715 | "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" 716 | }, 717 | "diff": { 718 | "version": "3.3.0", 719 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.0.tgz", 720 | "integrity": "sha512-w0XZubFWn0Adlsapj9EAWX0FqWdO4tz8kc3RiYdWLh4k/V8PTb6i0SMgXt0vRM3zyKnT8tKO7mUlieRQHIjMNg==", 721 | "dev": true 722 | }, 723 | "doctrine": { 724 | "version": "2.1.0", 725 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 726 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 727 | "dev": true, 728 | "requires": { 729 | "esutils": "^2.0.2" 730 | } 731 | }, 732 | "dom-serializer": { 733 | "version": "0.1.0", 734 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", 735 | "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", 736 | "dev": true, 737 | "requires": { 738 | "domelementtype": "~1.1.1", 739 | "entities": "~1.1.1" 740 | }, 741 | "dependencies": { 742 | "domelementtype": { 743 | "version": "1.1.3", 744 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", 745 | "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", 746 | "dev": true 747 | }, 748 | "entities": { 749 | "version": "1.1.1", 750 | "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", 751 | "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", 752 | "dev": true 753 | } 754 | } 755 | }, 756 | "domelementtype": { 757 | "version": "1.3.0", 758 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", 759 | "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", 760 | "dev": true 761 | }, 762 | "domhandler": { 763 | "version": "2.3.0", 764 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", 765 | "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", 766 | "dev": true, 767 | "requires": { 768 | "domelementtype": "1" 769 | } 770 | }, 771 | "domutils": { 772 | "version": "1.5.1", 773 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", 774 | "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", 775 | "dev": true, 776 | "requires": { 777 | "dom-serializer": "0", 778 | "domelementtype": "1" 779 | } 780 | }, 781 | "ecc-jsbn": { 782 | "version": "0.1.1", 783 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 784 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 785 | "dev": true, 786 | "optional": true, 787 | "requires": { 788 | "jsbn": "~0.1.0" 789 | } 790 | }, 791 | "ecdsa-sig-formatter": { 792 | "version": "1.0.11", 793 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 794 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 795 | "requires": { 796 | "safe-buffer": "^5.0.1" 797 | } 798 | }, 799 | "entities": { 800 | "version": "1.0.0", 801 | "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", 802 | "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", 803 | "dev": true 804 | }, 805 | "escape-string-regexp": { 806 | "version": "1.0.5", 807 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 808 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 809 | "dev": true 810 | }, 811 | "escodegen": { 812 | "version": "1.8.1", 813 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", 814 | "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", 815 | "dev": true, 816 | "requires": { 817 | "esprima": "^2.7.1", 818 | "estraverse": "^1.9.1", 819 | "esutils": "^2.0.2", 820 | "optionator": "^0.8.1", 821 | "source-map": "~0.2.0" 822 | } 823 | }, 824 | "eslint": { 825 | "version": "4.18.2", 826 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", 827 | "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", 828 | "dev": true, 829 | "requires": { 830 | "ajv": "^5.3.0", 831 | "babel-code-frame": "^6.22.0", 832 | "chalk": "^2.1.0", 833 | "concat-stream": "^1.6.0", 834 | "cross-spawn": "^5.1.0", 835 | "debug": "^3.1.0", 836 | "doctrine": "^2.1.0", 837 | "eslint-scope": "^3.7.1", 838 | "eslint-visitor-keys": "^1.0.0", 839 | "espree": "^3.5.2", 840 | "esquery": "^1.0.0", 841 | "esutils": "^2.0.2", 842 | "file-entry-cache": "^2.0.0", 843 | "functional-red-black-tree": "^1.0.1", 844 | "glob": "^7.1.2", 845 | "globals": "^11.0.1", 846 | "ignore": "^3.3.3", 847 | "imurmurhash": "^0.1.4", 848 | "inquirer": "^3.0.6", 849 | "is-resolvable": "^1.0.0", 850 | "js-yaml": "^3.9.1", 851 | "json-stable-stringify-without-jsonify": "^1.0.1", 852 | "levn": "^0.3.0", 853 | "lodash": "^4.17.4", 854 | "minimatch": "^3.0.2", 855 | "mkdirp": "^0.5.1", 856 | "natural-compare": "^1.4.0", 857 | "optionator": "^0.8.2", 858 | "path-is-inside": "^1.0.2", 859 | "pluralize": "^7.0.0", 860 | "progress": "^2.0.0", 861 | "require-uncached": "^1.0.3", 862 | "semver": "^5.3.0", 863 | "strip-ansi": "^4.0.0", 864 | "strip-json-comments": "~2.0.1", 865 | "table": "4.0.2", 866 | "text-table": "~0.2.0" 867 | }, 868 | "dependencies": { 869 | "ansi-regex": { 870 | "version": "3.0.0", 871 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 872 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 873 | "dev": true 874 | }, 875 | "ansi-styles": { 876 | "version": "3.2.1", 877 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 878 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 879 | "dev": true, 880 | "requires": { 881 | "color-convert": "^1.9.0" 882 | } 883 | }, 884 | "chalk": { 885 | "version": "2.4.2", 886 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 887 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 888 | "dev": true, 889 | "requires": { 890 | "ansi-styles": "^3.2.1", 891 | "escape-string-regexp": "^1.0.5", 892 | "supports-color": "^5.3.0" 893 | } 894 | }, 895 | "debug": { 896 | "version": "3.2.6", 897 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 898 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 899 | "dev": true, 900 | "requires": { 901 | "ms": "^2.1.1" 902 | } 903 | }, 904 | "has-flag": { 905 | "version": "3.0.0", 906 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 907 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 908 | "dev": true 909 | }, 910 | "ms": { 911 | "version": "2.1.2", 912 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 913 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 914 | "dev": true 915 | }, 916 | "strip-ansi": { 917 | "version": "4.0.0", 918 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 919 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 920 | "dev": true, 921 | "requires": { 922 | "ansi-regex": "^3.0.0" 923 | } 924 | }, 925 | "strip-json-comments": { 926 | "version": "2.0.1", 927 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 928 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 929 | "dev": true 930 | }, 931 | "supports-color": { 932 | "version": "5.5.0", 933 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 934 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 935 | "dev": true, 936 | "requires": { 937 | "has-flag": "^3.0.0" 938 | } 939 | } 940 | } 941 | }, 942 | "eslint-scope": { 943 | "version": "3.7.3", 944 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", 945 | "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", 946 | "dev": true, 947 | "requires": { 948 | "esrecurse": "^4.1.0", 949 | "estraverse": "^4.1.1" 950 | }, 951 | "dependencies": { 952 | "estraverse": { 953 | "version": "4.3.0", 954 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 955 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 956 | "dev": true 957 | } 958 | } 959 | }, 960 | "eslint-visitor-keys": { 961 | "version": "1.3.0", 962 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 963 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 964 | "dev": true 965 | }, 966 | "espree": { 967 | "version": "3.5.4", 968 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", 969 | "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", 970 | "dev": true, 971 | "requires": { 972 | "acorn": "^5.5.0", 973 | "acorn-jsx": "^3.0.0" 974 | } 975 | }, 976 | "esprima": { 977 | "version": "2.7.3", 978 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 979 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 980 | "dev": true 981 | }, 982 | "esquery": { 983 | "version": "1.3.1", 984 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", 985 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", 986 | "dev": true, 987 | "requires": { 988 | "estraverse": "^5.1.0" 989 | }, 990 | "dependencies": { 991 | "estraverse": { 992 | "version": "5.1.0", 993 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", 994 | "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", 995 | "dev": true 996 | } 997 | } 998 | }, 999 | "esrecurse": { 1000 | "version": "4.2.1", 1001 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 1002 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 1003 | "dev": true, 1004 | "requires": { 1005 | "estraverse": "^4.1.0" 1006 | }, 1007 | "dependencies": { 1008 | "estraverse": { 1009 | "version": "4.3.0", 1010 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 1011 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 1012 | "dev": true 1013 | } 1014 | } 1015 | }, 1016 | "estraverse": { 1017 | "version": "1.9.3", 1018 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", 1019 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", 1020 | "dev": true 1021 | }, 1022 | "esutils": { 1023 | "version": "2.0.2", 1024 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 1025 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 1026 | "dev": true 1027 | }, 1028 | "exit": { 1029 | "version": "0.1.2", 1030 | "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", 1031 | "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", 1032 | "dev": true 1033 | }, 1034 | "expect.js": { 1035 | "version": "0.3.1", 1036 | "resolved": "https://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz", 1037 | "integrity": "sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s=", 1038 | "dev": true 1039 | }, 1040 | "extend": { 1041 | "version": "3.0.2", 1042 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 1043 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 1044 | }, 1045 | "external-editor": { 1046 | "version": "2.2.0", 1047 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 1048 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 1049 | "dev": true, 1050 | "requires": { 1051 | "chardet": "^0.4.0", 1052 | "iconv-lite": "^0.4.17", 1053 | "tmp": "^0.0.33" 1054 | } 1055 | }, 1056 | "extsprintf": { 1057 | "version": "1.3.0", 1058 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 1059 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", 1060 | "dev": true 1061 | }, 1062 | "eyes": { 1063 | "version": "0.1.8", 1064 | "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", 1065 | "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", 1066 | "dev": true 1067 | }, 1068 | "fast-deep-equal": { 1069 | "version": "1.1.0", 1070 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 1071 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", 1072 | "dev": true 1073 | }, 1074 | "fast-json-stable-stringify": { 1075 | "version": "2.1.0", 1076 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1077 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1078 | "dev": true 1079 | }, 1080 | "fast-levenshtein": { 1081 | "version": "2.0.6", 1082 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1083 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 1084 | "dev": true 1085 | }, 1086 | "faye": { 1087 | "version": "1.3.0", 1088 | "resolved": "https://registry.npmjs.org/faye/-/faye-1.3.0.tgz", 1089 | "integrity": "sha512-l+IzAmEsT2OCVeGbLfZBpm8HeHQYVelkqKWNE0LA/k68jhVIT/qzHTXLygURrLpKweqiaTBCtzxxO5JTQ+dnFQ==", 1090 | "requires": { 1091 | "asap": "*", 1092 | "csprng": "*", 1093 | "faye-websocket": ">=0.9.1", 1094 | "safe-buffer": "*", 1095 | "tough-cookie": "*", 1096 | "tunnel-agent": "*" 1097 | } 1098 | }, 1099 | "faye-websocket": { 1100 | "version": "0.11.3", 1101 | "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", 1102 | "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", 1103 | "requires": { 1104 | "websocket-driver": ">=0.5.1" 1105 | } 1106 | }, 1107 | "figures": { 1108 | "version": "2.0.0", 1109 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 1110 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 1111 | "dev": true, 1112 | "requires": { 1113 | "escape-string-regexp": "^1.0.5" 1114 | } 1115 | }, 1116 | "file-entry-cache": { 1117 | "version": "2.0.0", 1118 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 1119 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", 1120 | "dev": true, 1121 | "requires": { 1122 | "flat-cache": "^1.2.1", 1123 | "object-assign": "^4.0.1" 1124 | } 1125 | }, 1126 | "flat-cache": { 1127 | "version": "1.3.4", 1128 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", 1129 | "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", 1130 | "dev": true, 1131 | "requires": { 1132 | "circular-json": "^0.3.1", 1133 | "graceful-fs": "^4.1.2", 1134 | "rimraf": "~2.6.2", 1135 | "write": "^0.2.1" 1136 | }, 1137 | "dependencies": { 1138 | "glob": { 1139 | "version": "7.1.6", 1140 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1141 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1142 | "dev": true, 1143 | "requires": { 1144 | "fs.realpath": "^1.0.0", 1145 | "inflight": "^1.0.4", 1146 | "inherits": "2", 1147 | "minimatch": "^3.0.4", 1148 | "once": "^1.3.0", 1149 | "path-is-absolute": "^1.0.0" 1150 | } 1151 | }, 1152 | "rimraf": { 1153 | "version": "2.6.3", 1154 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1155 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1156 | "dev": true, 1157 | "requires": { 1158 | "glob": "^7.1.3" 1159 | } 1160 | } 1161 | } 1162 | }, 1163 | "follow-redirects": { 1164 | "version": "1.5.10", 1165 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", 1166 | "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", 1167 | "requires": { 1168 | "debug": "=3.1.0" 1169 | }, 1170 | "dependencies": { 1171 | "debug": { 1172 | "version": "3.1.0", 1173 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1174 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1175 | "requires": { 1176 | "ms": "2.0.0" 1177 | } 1178 | } 1179 | } 1180 | }, 1181 | "forever-agent": { 1182 | "version": "0.6.1", 1183 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 1184 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 1185 | "dev": true 1186 | }, 1187 | "form-data": { 1188 | "version": "2.1.4", 1189 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", 1190 | "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", 1191 | "dev": true, 1192 | "requires": { 1193 | "asynckit": "^0.4.0", 1194 | "combined-stream": "^1.0.5", 1195 | "mime-types": "^2.1.12" 1196 | } 1197 | }, 1198 | "formatio": { 1199 | "version": "1.2.0", 1200 | "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", 1201 | "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", 1202 | "dev": true, 1203 | "requires": { 1204 | "samsam": "1.x" 1205 | } 1206 | }, 1207 | "fs.realpath": { 1208 | "version": "1.0.0", 1209 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1210 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1211 | "dev": true 1212 | }, 1213 | "functional-red-black-tree": { 1214 | "version": "1.0.1", 1215 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 1216 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 1217 | "dev": true 1218 | }, 1219 | "generate-function": { 1220 | "version": "2.0.0", 1221 | "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", 1222 | "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", 1223 | "dev": true 1224 | }, 1225 | "generate-object-property": { 1226 | "version": "1.2.0", 1227 | "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", 1228 | "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", 1229 | "dev": true, 1230 | "requires": { 1231 | "is-property": "^1.0.0" 1232 | } 1233 | }, 1234 | "getpass": { 1235 | "version": "0.1.7", 1236 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 1237 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 1238 | "dev": true, 1239 | "requires": { 1240 | "assert-plus": "^1.0.0" 1241 | }, 1242 | "dependencies": { 1243 | "assert-plus": { 1244 | "version": "1.0.0", 1245 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1246 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 1247 | "dev": true 1248 | } 1249 | } 1250 | }, 1251 | "getstream": { 1252 | "version": "5.0.0", 1253 | "resolved": "https://registry.npmjs.org/getstream/-/getstream-5.0.0.tgz", 1254 | "integrity": "sha512-cgVgCWXEXA28XlTF99vor00osppoAFMtln5EJbCglBcne8o4IXf79/fqxTSmj/dg8DG1gHg2QRWYU6wfU46cFQ==", 1255 | "requires": { 1256 | "@babel/runtime": "^7.10.4", 1257 | "Base64": "^1.1.0", 1258 | "axios": "^0.19.2", 1259 | "faye": "^1.3.0", 1260 | "form-data": "^3.0.0", 1261 | "jsonwebtoken": "^8.5.1", 1262 | "jwt-decode": "^2.2.0", 1263 | "qs": "^6.9.4" 1264 | }, 1265 | "dependencies": { 1266 | "combined-stream": { 1267 | "version": "1.0.8", 1268 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 1269 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 1270 | "requires": { 1271 | "delayed-stream": "~1.0.0" 1272 | } 1273 | }, 1274 | "form-data": { 1275 | "version": "3.0.0", 1276 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", 1277 | "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", 1278 | "requires": { 1279 | "asynckit": "^0.4.0", 1280 | "combined-stream": "^1.0.8", 1281 | "mime-types": "^2.1.12" 1282 | } 1283 | } 1284 | } 1285 | }, 1286 | "glob": { 1287 | "version": "7.1.2", 1288 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 1289 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 1290 | "dev": true, 1291 | "requires": { 1292 | "fs.realpath": "^1.0.0", 1293 | "inflight": "^1.0.4", 1294 | "inherits": "2", 1295 | "minimatch": "^3.0.4", 1296 | "once": "^1.3.0", 1297 | "path-is-absolute": "^1.0.0" 1298 | } 1299 | }, 1300 | "globals": { 1301 | "version": "11.12.0", 1302 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 1303 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1304 | "dev": true 1305 | }, 1306 | "graceful-fs": { 1307 | "version": "4.2.4", 1308 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 1309 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", 1310 | "dev": true 1311 | }, 1312 | "graceful-readlink": { 1313 | "version": "1.0.1", 1314 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", 1315 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", 1316 | "dev": true 1317 | }, 1318 | "growl": { 1319 | "version": "1.9.2", 1320 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", 1321 | "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", 1322 | "dev": true 1323 | }, 1324 | "handlebars": { 1325 | "version": "4.0.10", 1326 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", 1327 | "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", 1328 | "dev": true, 1329 | "requires": { 1330 | "async": "^1.4.0", 1331 | "optimist": "^0.6.1", 1332 | "source-map": "^0.4.4", 1333 | "uglify-js": "^2.6" 1334 | }, 1335 | "dependencies": { 1336 | "async": { 1337 | "version": "1.5.2", 1338 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 1339 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 1340 | "dev": true 1341 | }, 1342 | "source-map": { 1343 | "version": "0.4.4", 1344 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", 1345 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", 1346 | "dev": true, 1347 | "requires": { 1348 | "amdefine": ">=0.0.4" 1349 | } 1350 | } 1351 | } 1352 | }, 1353 | "has-ansi": { 1354 | "version": "2.0.0", 1355 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 1356 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 1357 | "dev": true, 1358 | "requires": { 1359 | "ansi-regex": "^2.0.0" 1360 | } 1361 | }, 1362 | "has-color": { 1363 | "version": "0.1.7", 1364 | "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", 1365 | "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", 1366 | "dev": true 1367 | }, 1368 | "has-flag": { 1369 | "version": "1.0.0", 1370 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", 1371 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", 1372 | "dev": true 1373 | }, 1374 | "hawk": { 1375 | "version": "3.1.3", 1376 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", 1377 | "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", 1378 | "dev": true, 1379 | "requires": { 1380 | "boom": "2.x.x", 1381 | "cryptiles": "2.x.x", 1382 | "hoek": "2.x.x", 1383 | "sntp": "1.x.x" 1384 | } 1385 | }, 1386 | "hoek": { 1387 | "version": "2.16.3", 1388 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", 1389 | "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", 1390 | "dev": true 1391 | }, 1392 | "htmlparser2": { 1393 | "version": "3.8.3", 1394 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", 1395 | "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", 1396 | "dev": true, 1397 | "requires": { 1398 | "domelementtype": "1", 1399 | "domhandler": "2.3", 1400 | "domutils": "1.5", 1401 | "entities": "1.0", 1402 | "readable-stream": "1.1" 1403 | }, 1404 | "dependencies": { 1405 | "readable-stream": { 1406 | "version": "1.1.14", 1407 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 1408 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 1409 | "dev": true, 1410 | "requires": { 1411 | "core-util-is": "~1.0.0", 1412 | "inherits": "~2.0.1", 1413 | "isarray": "0.0.1", 1414 | "string_decoder": "~0.10.x" 1415 | } 1416 | }, 1417 | "string_decoder": { 1418 | "version": "0.10.31", 1419 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1420 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", 1421 | "dev": true 1422 | } 1423 | } 1424 | }, 1425 | "http-parser-js": { 1426 | "version": "0.5.2", 1427 | "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz", 1428 | "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==" 1429 | }, 1430 | "http-signature": { 1431 | "version": "1.1.1", 1432 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", 1433 | "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", 1434 | "dev": true, 1435 | "requires": { 1436 | "assert-plus": "^0.2.0", 1437 | "jsprim": "^1.2.2", 1438 | "sshpk": "^1.7.0" 1439 | } 1440 | }, 1441 | "i": { 1442 | "version": "0.3.5", 1443 | "resolved": "https://registry.npmjs.org/i/-/i-0.3.5.tgz", 1444 | "integrity": "sha1-HSuFQVjsgWkRPGy39raAHpniEdU=", 1445 | "dev": true 1446 | }, 1447 | "iconv-lite": { 1448 | "version": "0.4.24", 1449 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1450 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1451 | "dev": true, 1452 | "requires": { 1453 | "safer-buffer": ">= 2.1.2 < 3" 1454 | } 1455 | }, 1456 | "ignore": { 1457 | "version": "3.3.10", 1458 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", 1459 | "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", 1460 | "dev": true 1461 | }, 1462 | "imurmurhash": { 1463 | "version": "0.1.4", 1464 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1465 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1466 | "dev": true 1467 | }, 1468 | "inflight": { 1469 | "version": "1.0.6", 1470 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1471 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1472 | "dev": true, 1473 | "requires": { 1474 | "once": "^1.3.0", 1475 | "wrappy": "1" 1476 | } 1477 | }, 1478 | "inherit": { 1479 | "version": "2.2.6", 1480 | "resolved": "https://registry.npmjs.org/inherit/-/inherit-2.2.6.tgz", 1481 | "integrity": "sha1-8WFLBshUToEo5CKchjR9tzrZeI0=", 1482 | "dev": true 1483 | }, 1484 | "inherits": { 1485 | "version": "2.0.3", 1486 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1487 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 1488 | }, 1489 | "inquirer": { 1490 | "version": "3.3.0", 1491 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 1492 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 1493 | "dev": true, 1494 | "requires": { 1495 | "ansi-escapes": "^3.0.0", 1496 | "chalk": "^2.0.0", 1497 | "cli-cursor": "^2.1.0", 1498 | "cli-width": "^2.0.0", 1499 | "external-editor": "^2.0.4", 1500 | "figures": "^2.0.0", 1501 | "lodash": "^4.3.0", 1502 | "mute-stream": "0.0.7", 1503 | "run-async": "^2.2.0", 1504 | "rx-lite": "^4.0.8", 1505 | "rx-lite-aggregates": "^4.0.8", 1506 | "string-width": "^2.1.0", 1507 | "strip-ansi": "^4.0.0", 1508 | "through": "^2.3.6" 1509 | }, 1510 | "dependencies": { 1511 | "ansi-regex": { 1512 | "version": "3.0.0", 1513 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1514 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 1515 | "dev": true 1516 | }, 1517 | "ansi-styles": { 1518 | "version": "3.2.1", 1519 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 1520 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 1521 | "dev": true, 1522 | "requires": { 1523 | "color-convert": "^1.9.0" 1524 | } 1525 | }, 1526 | "chalk": { 1527 | "version": "2.4.2", 1528 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 1529 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 1530 | "dev": true, 1531 | "requires": { 1532 | "ansi-styles": "^3.2.1", 1533 | "escape-string-regexp": "^1.0.5", 1534 | "supports-color": "^5.3.0" 1535 | } 1536 | }, 1537 | "has-flag": { 1538 | "version": "3.0.0", 1539 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1540 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1541 | "dev": true 1542 | }, 1543 | "mute-stream": { 1544 | "version": "0.0.7", 1545 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 1546 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", 1547 | "dev": true 1548 | }, 1549 | "strip-ansi": { 1550 | "version": "4.0.0", 1551 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1552 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1553 | "dev": true, 1554 | "requires": { 1555 | "ansi-regex": "^3.0.0" 1556 | } 1557 | }, 1558 | "supports-color": { 1559 | "version": "5.5.0", 1560 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1561 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1562 | "dev": true, 1563 | "requires": { 1564 | "has-flag": "^3.0.0" 1565 | } 1566 | } 1567 | } 1568 | }, 1569 | "is-buffer": { 1570 | "version": "1.1.5", 1571 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", 1572 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", 1573 | "dev": true, 1574 | "optional": true 1575 | }, 1576 | "is-fullwidth-code-point": { 1577 | "version": "2.0.0", 1578 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1579 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1580 | "dev": true 1581 | }, 1582 | "is-my-json-valid": { 1583 | "version": "2.16.1", 1584 | "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", 1585 | "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", 1586 | "dev": true, 1587 | "requires": { 1588 | "generate-function": "^2.0.0", 1589 | "generate-object-property": "^1.1.0", 1590 | "jsonpointer": "^4.0.0", 1591 | "xtend": "^4.0.0" 1592 | } 1593 | }, 1594 | "is-property": { 1595 | "version": "1.0.2", 1596 | "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", 1597 | "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", 1598 | "dev": true 1599 | }, 1600 | "is-resolvable": { 1601 | "version": "1.1.0", 1602 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", 1603 | "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", 1604 | "dev": true 1605 | }, 1606 | "is-typedarray": { 1607 | "version": "1.0.0", 1608 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1609 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 1610 | "dev": true 1611 | }, 1612 | "is-utf8": { 1613 | "version": "0.2.1", 1614 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 1615 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", 1616 | "dev": true 1617 | }, 1618 | "isarray": { 1619 | "version": "0.0.1", 1620 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 1621 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 1622 | "dev": true 1623 | }, 1624 | "isexe": { 1625 | "version": "2.0.0", 1626 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1627 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1628 | "dev": true 1629 | }, 1630 | "isstream": { 1631 | "version": "0.1.2", 1632 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 1633 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 1634 | "dev": true 1635 | }, 1636 | "istanbul": { 1637 | "version": "0.4.5", 1638 | "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", 1639 | "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", 1640 | "dev": true, 1641 | "requires": { 1642 | "abbrev": "1.0.x", 1643 | "async": "1.x", 1644 | "escodegen": "1.8.x", 1645 | "esprima": "2.7.x", 1646 | "glob": "^5.0.15", 1647 | "handlebars": "^4.0.1", 1648 | "js-yaml": "3.x", 1649 | "mkdirp": "0.5.x", 1650 | "nopt": "3.x", 1651 | "once": "1.x", 1652 | "resolve": "1.1.x", 1653 | "supports-color": "^3.1.0", 1654 | "which": "^1.1.1", 1655 | "wordwrap": "^1.0.0" 1656 | }, 1657 | "dependencies": { 1658 | "async": { 1659 | "version": "1.5.2", 1660 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 1661 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 1662 | "dev": true 1663 | }, 1664 | "glob": { 1665 | "version": "5.0.15", 1666 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", 1667 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 1668 | "dev": true, 1669 | "requires": { 1670 | "inflight": "^1.0.4", 1671 | "inherits": "2", 1672 | "minimatch": "2 || 3", 1673 | "once": "^1.3.0", 1674 | "path-is-absolute": "^1.0.0" 1675 | } 1676 | } 1677 | } 1678 | }, 1679 | "js-tokens": { 1680 | "version": "3.0.2", 1681 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1682 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 1683 | "dev": true 1684 | }, 1685 | "js-yaml": { 1686 | "version": "3.9.1", 1687 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", 1688 | "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", 1689 | "dev": true, 1690 | "requires": { 1691 | "argparse": "^1.0.7", 1692 | "esprima": "^4.0.0" 1693 | }, 1694 | "dependencies": { 1695 | "esprima": { 1696 | "version": "4.0.0", 1697 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", 1698 | "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", 1699 | "dev": true 1700 | } 1701 | } 1702 | }, 1703 | "jsbn": { 1704 | "version": "0.1.1", 1705 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 1706 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 1707 | "dev": true, 1708 | "optional": true 1709 | }, 1710 | "jscs": { 1711 | "version": "3.0.7", 1712 | "resolved": "https://registry.npmjs.org/jscs/-/jscs-3.0.7.tgz", 1713 | "integrity": "sha1-cUG03/W4bjLQ6Z12S4NnZ8MNIBo=", 1714 | "dev": true, 1715 | "requires": { 1716 | "chalk": "~1.1.0", 1717 | "cli-table": "~0.3.1", 1718 | "commander": "~2.9.0", 1719 | "cst": "^0.4.3", 1720 | "estraverse": "^4.1.0", 1721 | "exit": "~0.1.2", 1722 | "glob": "^5.0.1", 1723 | "htmlparser2": "3.8.3", 1724 | "js-yaml": "~3.4.0", 1725 | "jscs-jsdoc": "^2.0.0", 1726 | "jscs-preset-wikimedia": "~1.0.0", 1727 | "jsonlint": "~1.6.2", 1728 | "lodash": "~3.10.0", 1729 | "minimatch": "~3.0.0", 1730 | "natural-compare": "~1.2.2", 1731 | "pathval": "~0.1.1", 1732 | "prompt": "~0.2.14", 1733 | "reserved-words": "^0.1.1", 1734 | "resolve": "^1.1.6", 1735 | "strip-bom": "^2.0.0", 1736 | "strip-json-comments": "~1.0.2", 1737 | "to-double-quotes": "^2.0.0", 1738 | "to-single-quotes": "^2.0.0", 1739 | "vow": "~0.4.8", 1740 | "vow-fs": "~0.3.4", 1741 | "xmlbuilder": "^3.1.0" 1742 | }, 1743 | "dependencies": { 1744 | "estraverse": { 1745 | "version": "4.2.0", 1746 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 1747 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 1748 | "dev": true 1749 | }, 1750 | "glob": { 1751 | "version": "5.0.15", 1752 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", 1753 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 1754 | "dev": true, 1755 | "requires": { 1756 | "inflight": "^1.0.4", 1757 | "inherits": "2", 1758 | "minimatch": "2 || 3", 1759 | "once": "^1.3.0", 1760 | "path-is-absolute": "^1.0.0" 1761 | } 1762 | }, 1763 | "js-yaml": { 1764 | "version": "3.4.6", 1765 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz", 1766 | "integrity": "sha1-a+GyP2JJ9T0pM3D9TRqqY84bTrA=", 1767 | "dev": true, 1768 | "requires": { 1769 | "argparse": "^1.0.2", 1770 | "esprima": "^2.6.0", 1771 | "inherit": "^2.2.2" 1772 | } 1773 | }, 1774 | "lodash": { 1775 | "version": "3.10.1", 1776 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", 1777 | "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", 1778 | "dev": true 1779 | }, 1780 | "natural-compare": { 1781 | "version": "1.2.2", 1782 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.2.2.tgz", 1783 | "integrity": "sha1-H5bWDjFBysG20FZTzg2urHY69qo=", 1784 | "dev": true 1785 | }, 1786 | "strip-bom": { 1787 | "version": "2.0.0", 1788 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 1789 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 1790 | "dev": true, 1791 | "requires": { 1792 | "is-utf8": "^0.2.0" 1793 | } 1794 | } 1795 | } 1796 | }, 1797 | "jscs-jsdoc": { 1798 | "version": "2.0.0", 1799 | "resolved": "https://registry.npmjs.org/jscs-jsdoc/-/jscs-jsdoc-2.0.0.tgz", 1800 | "integrity": "sha1-9T684CmqMSW9iCkLpQ1k1FEKSHE=", 1801 | "dev": true, 1802 | "requires": { 1803 | "comment-parser": "^0.3.1", 1804 | "jsdoctypeparser": "~1.2.0" 1805 | } 1806 | }, 1807 | "jscs-preset-wikimedia": { 1808 | "version": "1.0.0", 1809 | "resolved": "https://registry.npmjs.org/jscs-preset-wikimedia/-/jscs-preset-wikimedia-1.0.0.tgz", 1810 | "integrity": "sha1-//VjNCA4/C6IJre7cwnDrjQG/H4=", 1811 | "dev": true 1812 | }, 1813 | "jsdoctypeparser": { 1814 | "version": "1.2.0", 1815 | "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-1.2.0.tgz", 1816 | "integrity": "sha1-597cFToRhJ/8UUEUSuhqfvDCU5I=", 1817 | "dev": true, 1818 | "requires": { 1819 | "lodash": "^3.7.0" 1820 | }, 1821 | "dependencies": { 1822 | "lodash": { 1823 | "version": "3.10.1", 1824 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", 1825 | "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", 1826 | "dev": true 1827 | } 1828 | } 1829 | }, 1830 | "json-schema": { 1831 | "version": "0.2.3", 1832 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 1833 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 1834 | "dev": true 1835 | }, 1836 | "json-schema-traverse": { 1837 | "version": "0.3.1", 1838 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 1839 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", 1840 | "dev": true 1841 | }, 1842 | "json-stable-stringify-without-jsonify": { 1843 | "version": "1.0.1", 1844 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1845 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1846 | "dev": true 1847 | }, 1848 | "json-stringify-safe": { 1849 | "version": "5.0.1", 1850 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 1851 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 1852 | "dev": true 1853 | }, 1854 | "json3": { 1855 | "version": "3.3.2", 1856 | "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", 1857 | "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", 1858 | "dev": true 1859 | }, 1860 | "jsonlint": { 1861 | "version": "1.6.2", 1862 | "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.2.tgz", 1863 | "integrity": "sha1-VzcEUIX1XrRVxosf9OvAG9UOiDA=", 1864 | "dev": true, 1865 | "requires": { 1866 | "JSV": ">= 4.0.x", 1867 | "nomnom": ">= 1.5.x" 1868 | } 1869 | }, 1870 | "jsonpointer": { 1871 | "version": "4.0.1", 1872 | "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", 1873 | "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", 1874 | "dev": true 1875 | }, 1876 | "jsonwebtoken": { 1877 | "version": "8.5.1", 1878 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", 1879 | "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", 1880 | "requires": { 1881 | "jws": "^3.2.2", 1882 | "lodash.includes": "^4.3.0", 1883 | "lodash.isboolean": "^3.0.3", 1884 | "lodash.isinteger": "^4.0.4", 1885 | "lodash.isnumber": "^3.0.3", 1886 | "lodash.isplainobject": "^4.0.6", 1887 | "lodash.isstring": "^4.0.1", 1888 | "lodash.once": "^4.0.0", 1889 | "ms": "^2.1.1", 1890 | "semver": "^5.6.0" 1891 | }, 1892 | "dependencies": { 1893 | "ms": { 1894 | "version": "2.1.2", 1895 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1896 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1897 | }, 1898 | "semver": { 1899 | "version": "5.7.1", 1900 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1901 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 1902 | } 1903 | } 1904 | }, 1905 | "jsprim": { 1906 | "version": "1.4.1", 1907 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 1908 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 1909 | "dev": true, 1910 | "requires": { 1911 | "assert-plus": "1.0.0", 1912 | "extsprintf": "1.3.0", 1913 | "json-schema": "0.2.3", 1914 | "verror": "1.10.0" 1915 | }, 1916 | "dependencies": { 1917 | "assert-plus": { 1918 | "version": "1.0.0", 1919 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1920 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 1921 | "dev": true 1922 | } 1923 | } 1924 | }, 1925 | "just-extend": { 1926 | "version": "1.1.22", 1927 | "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.22.tgz", 1928 | "integrity": "sha1-MzCvdWyralQnAMZLLk5KoGLVL/8=", 1929 | "dev": true 1930 | }, 1931 | "jwa": { 1932 | "version": "1.4.1", 1933 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 1934 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 1935 | "requires": { 1936 | "buffer-equal-constant-time": "1.0.1", 1937 | "ecdsa-sig-formatter": "1.0.11", 1938 | "safe-buffer": "^5.0.1" 1939 | } 1940 | }, 1941 | "jws": { 1942 | "version": "3.2.2", 1943 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 1944 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 1945 | "requires": { 1946 | "jwa": "^1.4.1", 1947 | "safe-buffer": "^5.0.1" 1948 | } 1949 | }, 1950 | "jwt-decode": { 1951 | "version": "2.2.0", 1952 | "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", 1953 | "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" 1954 | }, 1955 | "kareem": { 1956 | "version": "2.3.1", 1957 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", 1958 | "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw==" 1959 | }, 1960 | "kind-of": { 1961 | "version": "3.2.2", 1962 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1963 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1964 | "dev": true, 1965 | "optional": true, 1966 | "requires": { 1967 | "is-buffer": "^1.1.5" 1968 | } 1969 | }, 1970 | "lazy-cache": { 1971 | "version": "1.0.4", 1972 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 1973 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 1974 | "dev": true, 1975 | "optional": true 1976 | }, 1977 | "lcov-parse": { 1978 | "version": "0.0.10", 1979 | "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", 1980 | "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", 1981 | "dev": true 1982 | }, 1983 | "levn": { 1984 | "version": "0.3.0", 1985 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1986 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1987 | "dev": true, 1988 | "requires": { 1989 | "prelude-ls": "~1.1.2", 1990 | "type-check": "~0.3.2" 1991 | } 1992 | }, 1993 | "lodash": { 1994 | "version": "4.17.19", 1995 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", 1996 | "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", 1997 | "dev": true 1998 | }, 1999 | "lodash._baseassign": { 2000 | "version": "3.2.0", 2001 | "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", 2002 | "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", 2003 | "dev": true, 2004 | "requires": { 2005 | "lodash._basecopy": "^3.0.0", 2006 | "lodash.keys": "^3.0.0" 2007 | } 2008 | }, 2009 | "lodash._basecopy": { 2010 | "version": "3.0.1", 2011 | "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", 2012 | "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", 2013 | "dev": true 2014 | }, 2015 | "lodash._basecreate": { 2016 | "version": "3.0.3", 2017 | "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", 2018 | "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", 2019 | "dev": true 2020 | }, 2021 | "lodash._getnative": { 2022 | "version": "3.9.1", 2023 | "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", 2024 | "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", 2025 | "dev": true 2026 | }, 2027 | "lodash._isiterateecall": { 2028 | "version": "3.0.9", 2029 | "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", 2030 | "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", 2031 | "dev": true 2032 | }, 2033 | "lodash.create": { 2034 | "version": "3.1.1", 2035 | "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", 2036 | "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", 2037 | "dev": true, 2038 | "requires": { 2039 | "lodash._baseassign": "^3.0.0", 2040 | "lodash._basecreate": "^3.0.0", 2041 | "lodash._isiterateecall": "^3.0.0" 2042 | } 2043 | }, 2044 | "lodash.includes": { 2045 | "version": "4.3.0", 2046 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 2047 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" 2048 | }, 2049 | "lodash.isarguments": { 2050 | "version": "3.1.0", 2051 | "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", 2052 | "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", 2053 | "dev": true 2054 | }, 2055 | "lodash.isarray": { 2056 | "version": "3.0.4", 2057 | "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", 2058 | "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", 2059 | "dev": true 2060 | }, 2061 | "lodash.isboolean": { 2062 | "version": "3.0.3", 2063 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 2064 | "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" 2065 | }, 2066 | "lodash.isinteger": { 2067 | "version": "4.0.4", 2068 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 2069 | "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" 2070 | }, 2071 | "lodash.isnumber": { 2072 | "version": "3.0.3", 2073 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 2074 | "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" 2075 | }, 2076 | "lodash.isplainobject": { 2077 | "version": "4.0.6", 2078 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 2079 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" 2080 | }, 2081 | "lodash.isstring": { 2082 | "version": "4.0.1", 2083 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 2084 | "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" 2085 | }, 2086 | "lodash.keys": { 2087 | "version": "3.1.2", 2088 | "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", 2089 | "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", 2090 | "dev": true, 2091 | "requires": { 2092 | "lodash._getnative": "^3.0.0", 2093 | "lodash.isarguments": "^3.0.0", 2094 | "lodash.isarray": "^3.0.0" 2095 | } 2096 | }, 2097 | "lodash.once": { 2098 | "version": "4.1.1", 2099 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 2100 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" 2101 | }, 2102 | "log-driver": { 2103 | "version": "1.2.5", 2104 | "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", 2105 | "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=", 2106 | "dev": true 2107 | }, 2108 | "lolex": { 2109 | "version": "2.1.2", 2110 | "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.1.2.tgz", 2111 | "integrity": "sha1-JpS5U8nqTQE+W4v7qJHJkQJbJik=", 2112 | "dev": true 2113 | }, 2114 | "longest": { 2115 | "version": "1.0.1", 2116 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 2117 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 2118 | "dev": true, 2119 | "optional": true 2120 | }, 2121 | "lru-cache": { 2122 | "version": "4.1.5", 2123 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 2124 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 2125 | "dev": true, 2126 | "requires": { 2127 | "pseudomap": "^1.0.2", 2128 | "yallist": "^2.1.2" 2129 | } 2130 | }, 2131 | "memory-pager": { 2132 | "version": "1.5.0", 2133 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 2134 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", 2135 | "optional": true 2136 | }, 2137 | "mime-db": { 2138 | "version": "1.29.0", 2139 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz", 2140 | "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=" 2141 | }, 2142 | "mime-types": { 2143 | "version": "2.1.16", 2144 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz", 2145 | "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", 2146 | "requires": { 2147 | "mime-db": "~1.29.0" 2148 | } 2149 | }, 2150 | "mimic-fn": { 2151 | "version": "1.2.0", 2152 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 2153 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 2154 | "dev": true 2155 | }, 2156 | "minimatch": { 2157 | "version": "3.0.4", 2158 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 2159 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 2160 | "dev": true, 2161 | "requires": { 2162 | "brace-expansion": "^1.1.7" 2163 | } 2164 | }, 2165 | "minimist": { 2166 | "version": "0.0.10", 2167 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", 2168 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", 2169 | "dev": true 2170 | }, 2171 | "mkdirp": { 2172 | "version": "0.5.1", 2173 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 2174 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 2175 | "dev": true, 2176 | "requires": { 2177 | "minimist": "0.0.8" 2178 | }, 2179 | "dependencies": { 2180 | "minimist": { 2181 | "version": "0.0.8", 2182 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 2183 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 2184 | "dev": true 2185 | } 2186 | } 2187 | }, 2188 | "mocha": { 2189 | "version": "3.5.0", 2190 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz", 2191 | "integrity": "sha512-pIU2PJjrPYvYRqVpjXzj76qltO9uBYI7woYAMoxbSefsa+vqAfptjoeevd6bUgwD0mPIO+hv9f7ltvsNreL2PA==", 2192 | "dev": true, 2193 | "requires": { 2194 | "browser-stdout": "1.3.0", 2195 | "commander": "2.9.0", 2196 | "debug": "2.6.8", 2197 | "diff": "3.2.0", 2198 | "escape-string-regexp": "1.0.5", 2199 | "glob": "7.1.1", 2200 | "growl": "1.9.2", 2201 | "json3": "3.3.2", 2202 | "lodash.create": "3.1.1", 2203 | "mkdirp": "0.5.1", 2204 | "supports-color": "3.1.2" 2205 | }, 2206 | "dependencies": { 2207 | "diff": { 2208 | "version": "3.2.0", 2209 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", 2210 | "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", 2211 | "dev": true 2212 | }, 2213 | "glob": { 2214 | "version": "7.1.1", 2215 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", 2216 | "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", 2217 | "dev": true, 2218 | "requires": { 2219 | "fs.realpath": "^1.0.0", 2220 | "inflight": "^1.0.4", 2221 | "inherits": "2", 2222 | "minimatch": "^3.0.2", 2223 | "once": "^1.3.0", 2224 | "path-is-absolute": "^1.0.0" 2225 | } 2226 | }, 2227 | "supports-color": { 2228 | "version": "3.1.2", 2229 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", 2230 | "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", 2231 | "dev": true, 2232 | "requires": { 2233 | "has-flag": "^1.0.0" 2234 | } 2235 | } 2236 | } 2237 | }, 2238 | "mock-fs": { 2239 | "version": "4.4.1", 2240 | "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.4.1.tgz", 2241 | "integrity": "sha512-C8aapOvl77Bs18WCkejdLuX2kX8DaqaJ7ZmqUmX9U6HD2g31Pd0tZfNBAEVulmJWKyzUIyutrtxiIoNdXLAYsw==", 2242 | "dev": true 2243 | }, 2244 | "mockery": { 2245 | "version": "2.1.0", 2246 | "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", 2247 | "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==", 2248 | "dev": true 2249 | }, 2250 | "mongodb": { 2251 | "version": "3.5.9", 2252 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.9.tgz", 2253 | "integrity": "sha512-vXHBY1CsGYcEPoVWhwgxIBeWqP3dSu9RuRDsoLRPTITrcrgm1f0Ubu1xqF9ozMwv53agmEiZm0YGo+7WL3Nbug==", 2254 | "requires": { 2255 | "bl": "^2.2.0", 2256 | "bson": "^1.1.4", 2257 | "denque": "^1.4.1", 2258 | "require_optional": "^1.0.1", 2259 | "safe-buffer": "^5.1.2", 2260 | "saslprep": "^1.0.0" 2261 | }, 2262 | "dependencies": { 2263 | "bson": { 2264 | "version": "1.1.4", 2265 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz", 2266 | "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==" 2267 | }, 2268 | "safe-buffer": { 2269 | "version": "5.2.1", 2270 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 2271 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 2272 | } 2273 | } 2274 | }, 2275 | "mongoose": { 2276 | "version": "5.9.23", 2277 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.9.23.tgz", 2278 | "integrity": "sha512-fMYlMRJz0T6Ax2K2P0jt+kxXd4qaRxyfZCha1YBMczmA2EBlT5SnBlcDyJ4YQa4/z+GoDh06uH090w7BfBcdWg==", 2279 | "requires": { 2280 | "bson": "^1.1.4", 2281 | "kareem": "2.3.1", 2282 | "mongodb": "3.5.9", 2283 | "mongoose-legacy-pluralize": "1.0.2", 2284 | "mpath": "0.7.0", 2285 | "mquery": "3.2.2", 2286 | "ms": "2.1.2", 2287 | "regexp-clone": "1.0.0", 2288 | "safe-buffer": "5.2.1", 2289 | "sift": "7.0.1", 2290 | "sliced": "1.0.1" 2291 | }, 2292 | "dependencies": { 2293 | "bson": { 2294 | "version": "1.1.4", 2295 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz", 2296 | "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==" 2297 | }, 2298 | "ms": { 2299 | "version": "2.1.2", 2300 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2301 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 2302 | }, 2303 | "safe-buffer": { 2304 | "version": "5.2.1", 2305 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 2306 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 2307 | } 2308 | } 2309 | }, 2310 | "mongoose-legacy-pluralize": { 2311 | "version": "1.0.2", 2312 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", 2313 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" 2314 | }, 2315 | "mpath": { 2316 | "version": "0.7.0", 2317 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz", 2318 | "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==" 2319 | }, 2320 | "mquery": { 2321 | "version": "3.2.2", 2322 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz", 2323 | "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==", 2324 | "requires": { 2325 | "bluebird": "3.5.1", 2326 | "debug": "3.1.0", 2327 | "regexp-clone": "^1.0.0", 2328 | "safe-buffer": "5.1.2", 2329 | "sliced": "1.0.1" 2330 | }, 2331 | "dependencies": { 2332 | "debug": { 2333 | "version": "3.1.0", 2334 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 2335 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 2336 | "requires": { 2337 | "ms": "2.0.0" 2338 | } 2339 | }, 2340 | "safe-buffer": { 2341 | "version": "5.1.2", 2342 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2343 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 2344 | } 2345 | } 2346 | }, 2347 | "ms": { 2348 | "version": "2.0.0", 2349 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2350 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 2351 | }, 2352 | "mute-stream": { 2353 | "version": "0.0.5", 2354 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", 2355 | "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", 2356 | "dev": true 2357 | }, 2358 | "native-promise-only": { 2359 | "version": "0.8.1", 2360 | "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", 2361 | "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", 2362 | "dev": true 2363 | }, 2364 | "natural-compare": { 2365 | "version": "1.4.0", 2366 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2367 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 2368 | "dev": true 2369 | }, 2370 | "ncp": { 2371 | "version": "0.4.2", 2372 | "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", 2373 | "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", 2374 | "dev": true 2375 | }, 2376 | "nise": { 2377 | "version": "1.0.1", 2378 | "resolved": "https://registry.npmjs.org/nise/-/nise-1.0.1.tgz", 2379 | "integrity": "sha1-DakrEKhU6XwPSW9sKEWjASgLPu8=", 2380 | "dev": true, 2381 | "requires": { 2382 | "formatio": "^1.2.0", 2383 | "just-extend": "^1.1.22", 2384 | "lolex": "^1.6.0", 2385 | "path-to-regexp": "^1.7.0" 2386 | }, 2387 | "dependencies": { 2388 | "lolex": { 2389 | "version": "1.6.0", 2390 | "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", 2391 | "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", 2392 | "dev": true 2393 | } 2394 | } 2395 | }, 2396 | "nomnom": { 2397 | "version": "1.8.1", 2398 | "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", 2399 | "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", 2400 | "dev": true, 2401 | "requires": { 2402 | "chalk": "~0.4.0", 2403 | "underscore": "~1.6.0" 2404 | }, 2405 | "dependencies": { 2406 | "ansi-styles": { 2407 | "version": "1.0.0", 2408 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", 2409 | "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", 2410 | "dev": true 2411 | }, 2412 | "chalk": { 2413 | "version": "0.4.0", 2414 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", 2415 | "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", 2416 | "dev": true, 2417 | "requires": { 2418 | "ansi-styles": "~1.0.0", 2419 | "has-color": "~0.1.0", 2420 | "strip-ansi": "~0.1.0" 2421 | } 2422 | }, 2423 | "strip-ansi": { 2424 | "version": "0.1.1", 2425 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", 2426 | "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", 2427 | "dev": true 2428 | } 2429 | } 2430 | }, 2431 | "nopt": { 2432 | "version": "3.0.6", 2433 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", 2434 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 2435 | "dev": true, 2436 | "requires": { 2437 | "abbrev": "1" 2438 | } 2439 | }, 2440 | "oauth-sign": { 2441 | "version": "0.8.2", 2442 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 2443 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", 2444 | "dev": true 2445 | }, 2446 | "object-assign": { 2447 | "version": "4.1.1", 2448 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 2449 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 2450 | "dev": true 2451 | }, 2452 | "once": { 2453 | "version": "1.4.0", 2454 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2455 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2456 | "dev": true, 2457 | "requires": { 2458 | "wrappy": "1" 2459 | } 2460 | }, 2461 | "onetime": { 2462 | "version": "2.0.1", 2463 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 2464 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 2465 | "dev": true, 2466 | "requires": { 2467 | "mimic-fn": "^1.0.0" 2468 | } 2469 | }, 2470 | "optimist": { 2471 | "version": "0.6.1", 2472 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 2473 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 2474 | "dev": true, 2475 | "requires": { 2476 | "minimist": "~0.0.1", 2477 | "wordwrap": "~0.0.2" 2478 | }, 2479 | "dependencies": { 2480 | "wordwrap": { 2481 | "version": "0.0.3", 2482 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 2483 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 2484 | "dev": true 2485 | } 2486 | } 2487 | }, 2488 | "optionator": { 2489 | "version": "0.8.2", 2490 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 2491 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 2492 | "dev": true, 2493 | "requires": { 2494 | "deep-is": "~0.1.3", 2495 | "fast-levenshtein": "~2.0.4", 2496 | "levn": "~0.3.0", 2497 | "prelude-ls": "~1.1.2", 2498 | "type-check": "~0.3.2", 2499 | "wordwrap": "~1.0.0" 2500 | } 2501 | }, 2502 | "os-tmpdir": { 2503 | "version": "1.0.2", 2504 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 2505 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 2506 | "dev": true 2507 | }, 2508 | "path-is-absolute": { 2509 | "version": "1.0.1", 2510 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2511 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 2512 | "dev": true 2513 | }, 2514 | "path-is-inside": { 2515 | "version": "1.0.2", 2516 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 2517 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 2518 | "dev": true 2519 | }, 2520 | "path-to-regexp": { 2521 | "version": "1.7.0", 2522 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", 2523 | "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", 2524 | "dev": true, 2525 | "requires": { 2526 | "isarray": "0.0.1" 2527 | } 2528 | }, 2529 | "pathval": { 2530 | "version": "0.1.1", 2531 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-0.1.1.tgz", 2532 | "integrity": "sha1-CPkRzcqczllCiA2ngXvAtyO2bYI=", 2533 | "dev": true 2534 | }, 2535 | "pinkie": { 2536 | "version": "2.0.4", 2537 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 2538 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 2539 | "dev": true 2540 | }, 2541 | "pinkie-promise": { 2542 | "version": "2.0.1", 2543 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 2544 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 2545 | "dev": true, 2546 | "requires": { 2547 | "pinkie": "^2.0.0" 2548 | } 2549 | }, 2550 | "pkginfo": { 2551 | "version": "0.4.1", 2552 | "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", 2553 | "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=", 2554 | "dev": true 2555 | }, 2556 | "pluralize": { 2557 | "version": "7.0.0", 2558 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", 2559 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", 2560 | "dev": true 2561 | }, 2562 | "pmock": { 2563 | "version": "0.2.3", 2564 | "resolved": "https://registry.npmjs.org/pmock/-/pmock-0.2.3.tgz", 2565 | "integrity": "sha1-wSsMlamh+PJspUFQcZPB2nqdFbY=", 2566 | "dev": true, 2567 | "requires": { 2568 | "extend": "^3.0.0" 2569 | }, 2570 | "dependencies": { 2571 | "extend": { 2572 | "version": "3.0.1", 2573 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 2574 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", 2575 | "dev": true 2576 | } 2577 | } 2578 | }, 2579 | "prelude-ls": { 2580 | "version": "1.1.2", 2581 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 2582 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 2583 | "dev": true 2584 | }, 2585 | "process-nextick-args": { 2586 | "version": "1.0.7", 2587 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 2588 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", 2589 | "dev": true 2590 | }, 2591 | "progress": { 2592 | "version": "2.0.3", 2593 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 2594 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 2595 | "dev": true 2596 | }, 2597 | "promise": { 2598 | "version": "8.1.0", 2599 | "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", 2600 | "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", 2601 | "requires": { 2602 | "asap": "~2.0.6" 2603 | } 2604 | }, 2605 | "prompt": { 2606 | "version": "0.2.14", 2607 | "resolved": "https://registry.npmjs.org/prompt/-/prompt-0.2.14.tgz", 2608 | "integrity": "sha1-V3VPZPVD/XsIRXB8gY7OYY8F/9w=", 2609 | "dev": true, 2610 | "requires": { 2611 | "pkginfo": "0.x.x", 2612 | "read": "1.0.x", 2613 | "revalidator": "0.1.x", 2614 | "utile": "0.2.x", 2615 | "winston": "0.8.x" 2616 | } 2617 | }, 2618 | "pseudomap": { 2619 | "version": "1.0.2", 2620 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 2621 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 2622 | "dev": true 2623 | }, 2624 | "punycode": { 2625 | "version": "1.4.1", 2626 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 2627 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 2628 | }, 2629 | "qs": { 2630 | "version": "6.9.4", 2631 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", 2632 | "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" 2633 | }, 2634 | "read": { 2635 | "version": "1.0.7", 2636 | "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", 2637 | "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", 2638 | "dev": true, 2639 | "requires": { 2640 | "mute-stream": "~0.0.4" 2641 | } 2642 | }, 2643 | "readable-stream": { 2644 | "version": "2.2.7", 2645 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", 2646 | "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", 2647 | "dev": true, 2648 | "requires": { 2649 | "buffer-shims": "~1.0.0", 2650 | "core-util-is": "~1.0.0", 2651 | "inherits": "~2.0.1", 2652 | "isarray": "~1.0.0", 2653 | "process-nextick-args": "~1.0.6", 2654 | "string_decoder": "~1.0.0", 2655 | "util-deprecate": "~1.0.1" 2656 | }, 2657 | "dependencies": { 2658 | "isarray": { 2659 | "version": "1.0.0", 2660 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 2661 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 2662 | "dev": true 2663 | } 2664 | } 2665 | }, 2666 | "regenerator-runtime": { 2667 | "version": "0.11.0", 2668 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", 2669 | "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", 2670 | "dev": true 2671 | }, 2672 | "regexp-clone": { 2673 | "version": "1.0.0", 2674 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", 2675 | "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" 2676 | }, 2677 | "repeat-string": { 2678 | "version": "1.6.1", 2679 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 2680 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", 2681 | "dev": true, 2682 | "optional": true 2683 | }, 2684 | "require-uncached": { 2685 | "version": "1.0.3", 2686 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", 2687 | "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", 2688 | "dev": true, 2689 | "requires": { 2690 | "caller-path": "^0.1.0", 2691 | "resolve-from": "^1.0.0" 2692 | }, 2693 | "dependencies": { 2694 | "resolve-from": { 2695 | "version": "1.0.1", 2696 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", 2697 | "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", 2698 | "dev": true 2699 | } 2700 | } 2701 | }, 2702 | "require_optional": { 2703 | "version": "1.0.1", 2704 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 2705 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 2706 | "requires": { 2707 | "resolve-from": "^2.0.0", 2708 | "semver": "^5.1.0" 2709 | } 2710 | }, 2711 | "reserved-words": { 2712 | "version": "0.1.2", 2713 | "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", 2714 | "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", 2715 | "dev": true 2716 | }, 2717 | "resolve": { 2718 | "version": "1.1.7", 2719 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", 2720 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", 2721 | "dev": true 2722 | }, 2723 | "resolve-from": { 2724 | "version": "2.0.0", 2725 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 2726 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 2727 | }, 2728 | "restore-cursor": { 2729 | "version": "2.0.0", 2730 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 2731 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 2732 | "dev": true, 2733 | "requires": { 2734 | "onetime": "^2.0.0", 2735 | "signal-exit": "^3.0.2" 2736 | } 2737 | }, 2738 | "revalidator": { 2739 | "version": "0.1.8", 2740 | "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", 2741 | "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=", 2742 | "dev": true 2743 | }, 2744 | "rewire": { 2745 | "version": "2.5.2", 2746 | "resolved": "https://registry.npmjs.org/rewire/-/rewire-2.5.2.tgz", 2747 | "integrity": "sha1-ZCfee3/u+n02QBUH62SlOFvFjcc=", 2748 | "dev": true 2749 | }, 2750 | "right-align": { 2751 | "version": "0.1.3", 2752 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 2753 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 2754 | "dev": true, 2755 | "optional": true, 2756 | "requires": { 2757 | "align-text": "^0.1.1" 2758 | } 2759 | }, 2760 | "rimraf": { 2761 | "version": "2.6.1", 2762 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", 2763 | "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", 2764 | "dev": true, 2765 | "requires": { 2766 | "glob": "^7.0.5" 2767 | } 2768 | }, 2769 | "run-async": { 2770 | "version": "2.4.1", 2771 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", 2772 | "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", 2773 | "dev": true 2774 | }, 2775 | "rx-lite": { 2776 | "version": "4.0.8", 2777 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 2778 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", 2779 | "dev": true 2780 | }, 2781 | "rx-lite-aggregates": { 2782 | "version": "4.0.8", 2783 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 2784 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", 2785 | "dev": true, 2786 | "requires": { 2787 | "rx-lite": "*" 2788 | } 2789 | }, 2790 | "safe-buffer": { 2791 | "version": "5.1.1", 2792 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 2793 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 2794 | }, 2795 | "safer-buffer": { 2796 | "version": "2.1.2", 2797 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2798 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 2799 | "dev": true 2800 | }, 2801 | "samsam": { 2802 | "version": "1.2.1", 2803 | "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", 2804 | "integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=", 2805 | "dev": true 2806 | }, 2807 | "saslprep": { 2808 | "version": "1.0.3", 2809 | "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", 2810 | "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", 2811 | "optional": true, 2812 | "requires": { 2813 | "sparse-bitfield": "^3.0.3" 2814 | } 2815 | }, 2816 | "semver": { 2817 | "version": "5.4.1", 2818 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", 2819 | "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" 2820 | }, 2821 | "sequin": { 2822 | "version": "0.1.1", 2823 | "resolved": "https://registry.npmjs.org/sequin/-/sequin-0.1.1.tgz", 2824 | "integrity": "sha1-XC04nWajg3NOqvvEXt6ywcsb5wE=" 2825 | }, 2826 | "shebang-command": { 2827 | "version": "1.2.0", 2828 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 2829 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 2830 | "dev": true, 2831 | "requires": { 2832 | "shebang-regex": "^1.0.0" 2833 | } 2834 | }, 2835 | "shebang-regex": { 2836 | "version": "1.0.0", 2837 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 2838 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 2839 | "dev": true 2840 | }, 2841 | "should": { 2842 | "version": "11.2.1", 2843 | "resolved": "https://registry.npmjs.org/should/-/should-11.2.1.tgz", 2844 | "integrity": "sha1-kPVRRVUtAc/CAGZuToGKHJZw7aI=", 2845 | "dev": true, 2846 | "requires": { 2847 | "should-equal": "^1.0.0", 2848 | "should-format": "^3.0.2", 2849 | "should-type": "^1.4.0", 2850 | "should-type-adaptors": "^1.0.1", 2851 | "should-util": "^1.0.0" 2852 | } 2853 | }, 2854 | "should-equal": { 2855 | "version": "1.0.1", 2856 | "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz", 2857 | "integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=", 2858 | "dev": true, 2859 | "requires": { 2860 | "should-type": "^1.0.0" 2861 | } 2862 | }, 2863 | "should-format": { 2864 | "version": "3.0.3", 2865 | "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", 2866 | "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", 2867 | "dev": true, 2868 | "requires": { 2869 | "should-type": "^1.3.0", 2870 | "should-type-adaptors": "^1.0.1" 2871 | } 2872 | }, 2873 | "should-type": { 2874 | "version": "1.4.0", 2875 | "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", 2876 | "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", 2877 | "dev": true 2878 | }, 2879 | "should-type-adaptors": { 2880 | "version": "1.0.1", 2881 | "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz", 2882 | "integrity": "sha1-7+VVPN9oz/ZuXF9RtxLcNRx3vqo=", 2883 | "dev": true, 2884 | "requires": { 2885 | "should-type": "^1.3.0", 2886 | "should-util": "^1.0.0" 2887 | } 2888 | }, 2889 | "should-util": { 2890 | "version": "1.0.0", 2891 | "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", 2892 | "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", 2893 | "dev": true 2894 | }, 2895 | "sift": { 2896 | "version": "7.0.1", 2897 | "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", 2898 | "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" 2899 | }, 2900 | "signal-exit": { 2901 | "version": "3.0.3", 2902 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 2903 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", 2904 | "dev": true 2905 | }, 2906 | "sinon": { 2907 | "version": "3.2.1", 2908 | "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", 2909 | "integrity": "sha512-KY3OLOWpek/I4NGAMHetuutVgS2aRgMR5g5/1LSYvPJ3qo2BopIvk3esFztPxF40RWf/NNNJzdFPriSkXUVK3A==", 2910 | "dev": true, 2911 | "requires": { 2912 | "diff": "^3.1.0", 2913 | "formatio": "1.2.0", 2914 | "lolex": "^2.1.2", 2915 | "native-promise-only": "^0.8.1", 2916 | "nise": "^1.0.1", 2917 | "path-to-regexp": "^1.7.0", 2918 | "samsam": "^1.1.3", 2919 | "text-encoding": "0.6.4", 2920 | "type-detect": "^4.0.0" 2921 | } 2922 | }, 2923 | "slice-ansi": { 2924 | "version": "1.0.0", 2925 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", 2926 | "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", 2927 | "dev": true, 2928 | "requires": { 2929 | "is-fullwidth-code-point": "^2.0.0" 2930 | } 2931 | }, 2932 | "sliced": { 2933 | "version": "1.0.1", 2934 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", 2935 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 2936 | }, 2937 | "sntp": { 2938 | "version": "1.0.9", 2939 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", 2940 | "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", 2941 | "dev": true, 2942 | "requires": { 2943 | "hoek": "2.x.x" 2944 | } 2945 | }, 2946 | "source-map": { 2947 | "version": "0.2.0", 2948 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", 2949 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", 2950 | "dev": true, 2951 | "optional": true, 2952 | "requires": { 2953 | "amdefine": ">=0.0.4" 2954 | } 2955 | }, 2956 | "source-map-support": { 2957 | "version": "0.4.16", 2958 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.16.tgz", 2959 | "integrity": "sha512-A6vlydY7H/ljr4L2UOhDSajQdZQ6dMD7cLH0pzwcmwLyc9u8PNI4WGtnfDDzX7uzGL6c/T+ORL97Zlh+S4iOrg==", 2960 | "dev": true, 2961 | "requires": { 2962 | "source-map": "^0.5.6" 2963 | }, 2964 | "dependencies": { 2965 | "source-map": { 2966 | "version": "0.5.7", 2967 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 2968 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 2969 | "dev": true 2970 | } 2971 | } 2972 | }, 2973 | "sparse-bitfield": { 2974 | "version": "3.0.3", 2975 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 2976 | "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", 2977 | "optional": true, 2978 | "requires": { 2979 | "memory-pager": "^1.0.2" 2980 | } 2981 | }, 2982 | "sprintf-js": { 2983 | "version": "1.0.3", 2984 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2985 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 2986 | "dev": true 2987 | }, 2988 | "sshpk": { 2989 | "version": "1.13.1", 2990 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", 2991 | "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", 2992 | "dev": true, 2993 | "requires": { 2994 | "asn1": "~0.2.3", 2995 | "assert-plus": "^1.0.0", 2996 | "bcrypt-pbkdf": "^1.0.0", 2997 | "dashdash": "^1.12.0", 2998 | "ecc-jsbn": "~0.1.1", 2999 | "getpass": "^0.1.1", 3000 | "jsbn": "~0.1.0", 3001 | "tweetnacl": "~0.14.0" 3002 | }, 3003 | "dependencies": { 3004 | "assert-plus": { 3005 | "version": "1.0.0", 3006 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 3007 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 3008 | "dev": true 3009 | } 3010 | } 3011 | }, 3012 | "stack-trace": { 3013 | "version": "0.0.10", 3014 | "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", 3015 | "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", 3016 | "dev": true 3017 | }, 3018 | "string-width": { 3019 | "version": "2.1.1", 3020 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 3021 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 3022 | "dev": true, 3023 | "requires": { 3024 | "is-fullwidth-code-point": "^2.0.0", 3025 | "strip-ansi": "^4.0.0" 3026 | }, 3027 | "dependencies": { 3028 | "ansi-regex": { 3029 | "version": "3.0.0", 3030 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 3031 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 3032 | "dev": true 3033 | }, 3034 | "strip-ansi": { 3035 | "version": "4.0.0", 3036 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 3037 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 3038 | "dev": true, 3039 | "requires": { 3040 | "ansi-regex": "^3.0.0" 3041 | } 3042 | } 3043 | } 3044 | }, 3045 | "string_decoder": { 3046 | "version": "1.0.3", 3047 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 3048 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 3049 | "dev": true, 3050 | "requires": { 3051 | "safe-buffer": "~5.1.0" 3052 | } 3053 | }, 3054 | "stringstream": { 3055 | "version": "0.0.5", 3056 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", 3057 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", 3058 | "dev": true 3059 | }, 3060 | "strip-ansi": { 3061 | "version": "3.0.1", 3062 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 3063 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 3064 | "dev": true, 3065 | "requires": { 3066 | "ansi-regex": "^2.0.0" 3067 | } 3068 | }, 3069 | "strip-json-comments": { 3070 | "version": "1.0.4", 3071 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", 3072 | "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", 3073 | "dev": true 3074 | }, 3075 | "supports-color": { 3076 | "version": "3.2.3", 3077 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", 3078 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 3079 | "dev": true, 3080 | "requires": { 3081 | "has-flag": "^1.0.0" 3082 | } 3083 | }, 3084 | "table": { 3085 | "version": "4.0.2", 3086 | "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", 3087 | "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", 3088 | "dev": true, 3089 | "requires": { 3090 | "ajv": "^5.2.3", 3091 | "ajv-keywords": "^2.1.0", 3092 | "chalk": "^2.1.0", 3093 | "lodash": "^4.17.4", 3094 | "slice-ansi": "1.0.0", 3095 | "string-width": "^2.1.1" 3096 | }, 3097 | "dependencies": { 3098 | "ansi-styles": { 3099 | "version": "3.2.1", 3100 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 3101 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 3102 | "dev": true, 3103 | "requires": { 3104 | "color-convert": "^1.9.0" 3105 | } 3106 | }, 3107 | "chalk": { 3108 | "version": "2.4.2", 3109 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 3110 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 3111 | "dev": true, 3112 | "requires": { 3113 | "ansi-styles": "^3.2.1", 3114 | "escape-string-regexp": "^1.0.5", 3115 | "supports-color": "^5.3.0" 3116 | } 3117 | }, 3118 | "has-flag": { 3119 | "version": "3.0.0", 3120 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 3121 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 3122 | "dev": true 3123 | }, 3124 | "supports-color": { 3125 | "version": "5.5.0", 3126 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 3127 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 3128 | "dev": true, 3129 | "requires": { 3130 | "has-flag": "^3.0.0" 3131 | } 3132 | } 3133 | } 3134 | }, 3135 | "text-encoding": { 3136 | "version": "0.6.4", 3137 | "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", 3138 | "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", 3139 | "dev": true 3140 | }, 3141 | "text-table": { 3142 | "version": "0.2.0", 3143 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 3144 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 3145 | "dev": true 3146 | }, 3147 | "through": { 3148 | "version": "2.3.8", 3149 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 3150 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 3151 | "dev": true 3152 | }, 3153 | "tmp": { 3154 | "version": "0.0.33", 3155 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 3156 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 3157 | "dev": true, 3158 | "requires": { 3159 | "os-tmpdir": "~1.0.2" 3160 | } 3161 | }, 3162 | "to-double-quotes": { 3163 | "version": "2.0.0", 3164 | "resolved": "https://registry.npmjs.org/to-double-quotes/-/to-double-quotes-2.0.0.tgz", 3165 | "integrity": "sha1-qvIx1vqUiUn4GTAburRITYWI5Kc=", 3166 | "dev": true 3167 | }, 3168 | "to-single-quotes": { 3169 | "version": "2.0.1", 3170 | "resolved": "https://registry.npmjs.org/to-single-quotes/-/to-single-quotes-2.0.1.tgz", 3171 | "integrity": "sha1-fMKRUfD18sQZRvEZ9ZMv5VQXASU=", 3172 | "dev": true 3173 | }, 3174 | "tough-cookie": { 3175 | "version": "2.3.2", 3176 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", 3177 | "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", 3178 | "requires": { 3179 | "punycode": "^1.4.1" 3180 | } 3181 | }, 3182 | "tunnel-agent": { 3183 | "version": "0.6.0", 3184 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 3185 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 3186 | "requires": { 3187 | "safe-buffer": "^5.0.1" 3188 | } 3189 | }, 3190 | "tweetnacl": { 3191 | "version": "0.14.5", 3192 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 3193 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 3194 | "dev": true, 3195 | "optional": true 3196 | }, 3197 | "type-check": { 3198 | "version": "0.3.2", 3199 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 3200 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 3201 | "dev": true, 3202 | "requires": { 3203 | "prelude-ls": "~1.1.2" 3204 | } 3205 | }, 3206 | "type-detect": { 3207 | "version": "4.0.3", 3208 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", 3209 | "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", 3210 | "dev": true 3211 | }, 3212 | "typedarray": { 3213 | "version": "0.0.6", 3214 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 3215 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 3216 | "dev": true 3217 | }, 3218 | "uglify-js": { 3219 | "version": "2.8.29", 3220 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 3221 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 3222 | "dev": true, 3223 | "optional": true, 3224 | "requires": { 3225 | "source-map": "~0.5.1", 3226 | "uglify-to-browserify": "~1.0.0", 3227 | "yargs": "~3.10.0" 3228 | }, 3229 | "dependencies": { 3230 | "source-map": { 3231 | "version": "0.5.7", 3232 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 3233 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 3234 | "dev": true, 3235 | "optional": true 3236 | } 3237 | } 3238 | }, 3239 | "uglify-to-browserify": { 3240 | "version": "1.0.2", 3241 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 3242 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 3243 | "dev": true, 3244 | "optional": true 3245 | }, 3246 | "underscore": { 3247 | "version": "1.6.0", 3248 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", 3249 | "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", 3250 | "dev": true 3251 | }, 3252 | "util-deprecate": { 3253 | "version": "1.0.2", 3254 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 3255 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 3256 | }, 3257 | "utile": { 3258 | "version": "0.2.1", 3259 | "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz", 3260 | "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=", 3261 | "dev": true, 3262 | "requires": { 3263 | "async": "~0.2.9", 3264 | "deep-equal": "*", 3265 | "i": "0.3.x", 3266 | "mkdirp": "0.x.x", 3267 | "ncp": "0.4.x", 3268 | "rimraf": "2.x.x" 3269 | }, 3270 | "dependencies": { 3271 | "async": { 3272 | "version": "0.2.10", 3273 | "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", 3274 | "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", 3275 | "dev": true 3276 | } 3277 | } 3278 | }, 3279 | "uuid": { 3280 | "version": "3.1.0", 3281 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", 3282 | "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", 3283 | "dev": true 3284 | }, 3285 | "verror": { 3286 | "version": "1.10.0", 3287 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 3288 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 3289 | "dev": true, 3290 | "requires": { 3291 | "assert-plus": "^1.0.0", 3292 | "core-util-is": "1.0.2", 3293 | "extsprintf": "^1.2.0" 3294 | }, 3295 | "dependencies": { 3296 | "assert-plus": { 3297 | "version": "1.0.0", 3298 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 3299 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 3300 | "dev": true 3301 | } 3302 | } 3303 | }, 3304 | "vow": { 3305 | "version": "0.4.16", 3306 | "resolved": "https://registry.npmjs.org/vow/-/vow-0.4.16.tgz", 3307 | "integrity": "sha1-u51U2TjV+AUg1linQOeoleMP7us=", 3308 | "dev": true 3309 | }, 3310 | "vow-fs": { 3311 | "version": "0.3.6", 3312 | "resolved": "https://registry.npmjs.org/vow-fs/-/vow-fs-0.3.6.tgz", 3313 | "integrity": "sha1-LUxZviLivyYY3fWXq0uqkjvnIA0=", 3314 | "dev": true, 3315 | "requires": { 3316 | "glob": "^7.0.5", 3317 | "uuid": "^2.0.2", 3318 | "vow": "^0.4.7", 3319 | "vow-queue": "^0.4.1" 3320 | }, 3321 | "dependencies": { 3322 | "uuid": { 3323 | "version": "2.0.3", 3324 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", 3325 | "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", 3326 | "dev": true 3327 | } 3328 | } 3329 | }, 3330 | "vow-queue": { 3331 | "version": "0.4.2", 3332 | "resolved": "https://registry.npmjs.org/vow-queue/-/vow-queue-0.4.2.tgz", 3333 | "integrity": "sha1-5/4XFg4Vx8QYTRtmapvGThjjAYQ=", 3334 | "dev": true, 3335 | "requires": { 3336 | "vow": "~0.4.0" 3337 | } 3338 | }, 3339 | "websocket-driver": { 3340 | "version": "0.7.4", 3341 | "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", 3342 | "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", 3343 | "requires": { 3344 | "http-parser-js": ">=0.5.1", 3345 | "safe-buffer": ">=5.1.0", 3346 | "websocket-extensions": ">=0.1.1" 3347 | } 3348 | }, 3349 | "websocket-extensions": { 3350 | "version": "0.1.4", 3351 | "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", 3352 | "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" 3353 | }, 3354 | "which": { 3355 | "version": "1.3.0", 3356 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", 3357 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", 3358 | "dev": true, 3359 | "requires": { 3360 | "isexe": "^2.0.0" 3361 | } 3362 | }, 3363 | "window-size": { 3364 | "version": "0.1.0", 3365 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 3366 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 3367 | "dev": true, 3368 | "optional": true 3369 | }, 3370 | "winston": { 3371 | "version": "0.8.3", 3372 | "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz", 3373 | "integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=", 3374 | "dev": true, 3375 | "requires": { 3376 | "async": "0.2.x", 3377 | "colors": "0.6.x", 3378 | "cycle": "1.0.x", 3379 | "eyes": "0.1.x", 3380 | "isstream": "0.1.x", 3381 | "pkginfo": "0.3.x", 3382 | "stack-trace": "0.0.x" 3383 | }, 3384 | "dependencies": { 3385 | "async": { 3386 | "version": "0.2.10", 3387 | "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", 3388 | "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", 3389 | "dev": true 3390 | }, 3391 | "colors": { 3392 | "version": "0.6.2", 3393 | "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", 3394 | "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", 3395 | "dev": true 3396 | }, 3397 | "pkginfo": { 3398 | "version": "0.3.1", 3399 | "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", 3400 | "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=", 3401 | "dev": true 3402 | } 3403 | } 3404 | }, 3405 | "wordwrap": { 3406 | "version": "1.0.0", 3407 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 3408 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 3409 | "dev": true 3410 | }, 3411 | "wrappy": { 3412 | "version": "1.0.2", 3413 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 3414 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 3415 | "dev": true 3416 | }, 3417 | "write": { 3418 | "version": "0.2.1", 3419 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 3420 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", 3421 | "dev": true, 3422 | "requires": { 3423 | "mkdirp": "^0.5.1" 3424 | } 3425 | }, 3426 | "xmlbuilder": { 3427 | "version": "3.1.0", 3428 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-3.1.0.tgz", 3429 | "integrity": "sha1-LIaIjy1OrehQ+jjKf3Ij9yCVFuE=", 3430 | "dev": true, 3431 | "requires": { 3432 | "lodash": "^3.5.0" 3433 | }, 3434 | "dependencies": { 3435 | "lodash": { 3436 | "version": "3.10.1", 3437 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", 3438 | "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", 3439 | "dev": true 3440 | } 3441 | } 3442 | }, 3443 | "xtend": { 3444 | "version": "4.0.1", 3445 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 3446 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", 3447 | "dev": true 3448 | }, 3449 | "yallist": { 3450 | "version": "2.1.2", 3451 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 3452 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 3453 | "dev": true 3454 | }, 3455 | "yargs": { 3456 | "version": "3.10.0", 3457 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 3458 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 3459 | "dev": true, 3460 | "optional": true, 3461 | "requires": { 3462 | "camelcase": "^1.0.2", 3463 | "cliui": "^2.1.0", 3464 | "decamelize": "^1.0.0", 3465 | "window-size": "0.1.0" 3466 | } 3467 | } 3468 | } 3469 | } 3470 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getstream-node", 3 | "version": "2.0.0", 4 | "description": "Build newsfeeds and activity feeds on node.js using getstream.io", 5 | "author": "getstream.io (https://getstream.io/)", 6 | "email": "support@getstream.io", 7 | "company": "Stream.io INC", 8 | "contributors": [ 9 | { 10 | "name": "Mario Delgado", 11 | "email": "mariodel@gmail.com" 12 | }, 13 | { 14 | "name": "Thierry Schellenbach", 15 | "email": "thierry@getstream.io" 16 | }, 17 | { 18 | "name": "Tommaso Barbugli", 19 | "email": "tommaso@getstream.io" 20 | }, 21 | { 22 | "name": "Matthisk Heimensen", 23 | "email": "matthisk@getstream.io" 24 | }, 25 | { 26 | "name": "Nick Parsons", 27 | "email": "nparsons08@gmail.com" 28 | } 29 | ], 30 | "license": "BSD-3-Clause", 31 | "main": "./src/index.js", 32 | "dependencies": { 33 | "async": "^3.2.0", 34 | "extend": "^3.0.2", 35 | "getstream": "^5.0.0", 36 | "mongoose": "^5.9.23", 37 | "promise": "^8.1.0" 38 | }, 39 | "devDependencies": { 40 | "better-assert": "~1.0.2", 41 | "bson": "~1.0.4", 42 | "coveralls": "~2.13.1", 43 | "eslint": "~4.18.2", 44 | "expect.js": "~0.3.1", 45 | "glob": "~7.1.2", 46 | "istanbul": "^0.4.5", 47 | "jscs": "~3.0.7", 48 | "mocha": "~3.5.0", 49 | "mock-fs": "~4.4.1", 50 | "mockery": "^2.1.0", 51 | "pmock": "~0.2.3", 52 | "rewire": "~2.5.2", 53 | "should": "~11.2.1", 54 | "sinon": "^3.2.1" 55 | }, 56 | "scripts": { 57 | "test": "STREAM_URL='https://key:secret@us-east.getstream.io/?app_id=42' NODE_ENV=test ./node_modules/.bin/mocha --timeout 30000 test test/**/*_test.js", 58 | "coverage": "STREAM_URL='https://key:secret@us-east.getstream.io/?app_id=42' ./node_modules/.bin/istanbul cover bin/run-tests.js", 59 | "preversion": "npm test", 60 | "postversion": "git push && git push --tags" 61 | }, 62 | "engines": { 63 | "node": "10 || 12 || >=14" 64 | }, 65 | "homepage": "http://getstream.io" 66 | } 67 | -------------------------------------------------------------------------------- /src/FeedManager.js: -------------------------------------------------------------------------------- 1 | var stream = require('getstream').default, 2 | Promise = require('promise'); 3 | var FeedManager = function() { 4 | this.initialize.apply(this, arguments); 5 | }; 6 | 7 | FeedManager.prototype = { 8 | initialize: function(settings) { 9 | this.settings = settings; 10 | 11 | var options = {}; 12 | 13 | if (this.settings.apiLocation != '') { 14 | options.location = this.settings.apiLocation; 15 | } 16 | 17 | if (typeof process !== 'undefined' && process.env.STREAM_URL) { 18 | this.client = stream.connect(); 19 | } else { 20 | this.client = stream.connect(this.settings.apiKey, this.settings.apiSecret, this.settings.apiAppId, options); 21 | } 22 | }, 23 | 24 | trackingEnabled: function(instance) { 25 | return process.env.NODE_ENV === 'test' ? false : true; 26 | }, 27 | 28 | getUserFeed: function(userId) { 29 | return this.client.feed(this.settings.userFeed, userId); 30 | }, 31 | 32 | getNotificationFeed: function(userId) { 33 | return this.client.feed(this.settings.notificationFeed, userId); 34 | }, 35 | 36 | getNewsFeeds: function(userId) { 37 | var feeds = []; 38 | var newsFeeds = this.settings.newsFeeds; 39 | 40 | for (var key in newsFeeds) { 41 | var slug = newsFeeds[key]; 42 | feeds[slug] = this.client.feed(slug, userId); 43 | } 44 | 45 | return feeds; 46 | }, 47 | 48 | followUser: function(userId, targetUserId) { 49 | var newsFeeds = this.getNewsFeeds(userId); 50 | var ps = []; 51 | 52 | for (var slug in newsFeeds) { 53 | var p = newsFeeds[slug].follow(this.settings.userFeed, targetUserId); 54 | ps.push(p); 55 | } 56 | 57 | return Promise.all(ps); 58 | }, 59 | 60 | unfollowUser: function(userId, targetUserId) { 61 | var newsFeeds = this.getNewsFeeds(userId); 62 | var ps = []; 63 | 64 | for (var slug in newsFeeds) { 65 | var p = newsFeeds[slug].unfollow(this.settings.userFeed, targetUserId); 66 | ps.push(p); 67 | } 68 | 69 | return Promise.all(ps); 70 | }, 71 | 72 | getFeed: function(slug, userId) { 73 | return this.client.feed(slug, userId); 74 | }, 75 | 76 | activityCreated: function(instance) { 77 | if (this.trackingEnabled(instance)) { 78 | var activity = instance.createActivity(); 79 | var backend = instance.getStreamBackend(); 80 | 81 | backend.serializeActivities([activity]); 82 | 83 | var feedType = 84 | instance.activityActorFeed() || this.settings.userFeed; 85 | var userId = backend.getIdFromRef(activity.actor); 86 | var feed = this.getFeed(feedType, userId); 87 | 88 | return feed.addActivity(activity); 89 | } 90 | }, 91 | 92 | activityDeleted: function(instance) { 93 | if (this.trackingEnabled(instance)) { 94 | var activity = instance.createActivity(); 95 | var backend = instance.getStreamBackend(); 96 | 97 | backend.serializeActivities([activity]); 98 | 99 | var feedType = 100 | instance.activityActorFeed() || this.settings.userFeed; 101 | var userId = backend.getIdFromRef(activity.actor); 102 | var feed = this.getFeed(feedType, userId); 103 | 104 | return feed.removeActivity({ foreignId: activity.foreign_id }); 105 | } 106 | }, 107 | }; 108 | 109 | module.exports = FeedManager; 110 | -------------------------------------------------------------------------------- /src/backends/activity.js: -------------------------------------------------------------------------------- 1 | module.exports = function(schema, options) { 2 | // Common proto functions 3 | schema.methods.activityActorFeed = function() { 4 | return null; 5 | }; 6 | 7 | schema.methods.activityGetActor = function() { 8 | var actor = this[this.activityActorProp()]; 9 | if (typeof actor === 'undefined') { 10 | throw new Error('Actor prop ' + this.activityActorProp() + ' not found on model instance'); 11 | } 12 | 13 | return actor; 14 | }; 15 | 16 | schema.methods.activityActor = function() { 17 | var actor = this.activityGetActor(); 18 | return actor; 19 | }; 20 | 21 | schema.methods.activityObject = function() { 22 | return this; 23 | }; 24 | 25 | schema.methods.activityForeignId = function() { 26 | return this; 27 | }; 28 | 29 | schema.methods.createActivity = function() { 30 | var activity = {}; 31 | var extra_data = this.activityExtraData(); 32 | for (var key in extra_data) { 33 | activity[key] = extra_data[key]; 34 | } 35 | 36 | activity.to = (this.activityNotify() || []).map(function(x) { 37 | return x.id; 38 | }); 39 | 40 | activity.actor = this.activityActor(); 41 | activity.verb = this.activityVerb(); 42 | activity.object = this.activityObject(); 43 | activity.foreign_id = this.activityForeignId(); 44 | if (this.activityTime()) { 45 | activity.time = this.activityTime(); 46 | } 47 | 48 | return activity; 49 | }; 50 | 51 | // User specific proto functions (with decent defaults) 52 | schema.methods.getStreamBackend = function() { 53 | throw new Error('Not implemented'); 54 | }; 55 | 56 | schema.methods.activityActorProp = function() { 57 | return 'user'; 58 | }; 59 | 60 | schema.methods.activityVerb = function() { 61 | return this.constructor.name; 62 | }; 63 | 64 | schema.methods.activityExtraData = function() { 65 | return {}; 66 | }; 67 | 68 | schema.methods.activityTime = function() {}; 69 | 70 | schema.methods.activityNotify = function() {}; 71 | }; 72 | -------------------------------------------------------------------------------- /src/backends/base.js: -------------------------------------------------------------------------------- 1 | var async = require('async'); 2 | var Promise = require('promise'); 3 | 4 | var BaseBackend = function() {}; 5 | 6 | function capitalizeFirstLetter(string) { 7 | return string.charAt(0).toUpperCase() + string.slice(1); 8 | } 9 | 10 | BaseBackend.prototype = { 11 | isReference: function(field, value) { 12 | if (field === 'origin' || field === 'foreign_id') { 13 | return false; 14 | } 15 | 16 | return typeof value === 'string' && value.split(':').length == 2; 17 | }, 18 | 19 | iterActivityFields: function(activities, filter, fn) { 20 | for (var i in activities) { 21 | var activity = activities[i]; 22 | for (var field in activity) { 23 | if (!filter(field, activity[field])) continue; 24 | var args = { 25 | activity: activity, 26 | field: field 27 | }; 28 | fn(args); 29 | } 30 | } 31 | }, 32 | 33 | iterActivityFieldsWithObjects: function(activities, fn) { 34 | this.iterActivityFields(activities, function(field, value) { 35 | return value !== null && typeof value === 'object'; 36 | }, fn); 37 | }, 38 | 39 | iterActivityFieldsWithReferences: function(activities, fn) { 40 | this.iterActivityFields(activities, this.isReference, function(args) { 41 | var field = args['field']; 42 | args['modelRef'] = args['activity'][field].split(':')[0]; 43 | args['instanceRef'] = args['activity'][field].split(':')[1]; 44 | fn(args); 45 | }); 46 | }, 47 | 48 | collectReferences: function(activities) { 49 | var modelReferences = {}; 50 | this.iterActivityFieldsWithReferences(activities, function(args) { 51 | if (modelReferences[args.modelRef]) { 52 | modelReferences[args.modelRef].push(args.instanceRef); 53 | } else { 54 | modelReferences[args.modelRef] = [args.instanceRef]; 55 | } 56 | }); 57 | 58 | return modelReferences; 59 | }, 60 | 61 | retreiveObjects: function(references, callback) { 62 | var objects = {}; 63 | var self = this; 64 | async.each( 65 | Object.keys(references), 66 | function(modelRef, done) { 67 | var refs = references[modelRef]; 68 | var modelClass = self.getClassFromRef(modelRef); 69 | if (typeof modelClass === 'undefined') return done(); 70 | if (typeof objects[modelRef] === 'undefined') 71 | objects[modelRef] = {}; 72 | self.loadFromStorageOrCustom(modelRef, modelClass, refs, function(err, objectsIds) { 73 | for (var k in objectsIds) { 74 | objects[modelRef][k] = objectsIds[k]; 75 | } 76 | done(err); 77 | }); 78 | }, 79 | function(err) { 80 | callback(err, objects); 81 | } 82 | ); 83 | }, 84 | 85 | enrichActivities: function(activities) { 86 | // Return a Promise instead of using node style callbacks (_enrichActivities accepts one argument + callback) 87 | return Promise.denodeify(this._enrichActivities, 1).call(this, activities); 88 | }, 89 | 90 | _enrichActivities: function(activities, callback) { 91 | var self = this; 92 | var references = this.collectReferences(activities); 93 | this.retreiveObjects(references, function(err, objects) { 94 | self.iterActivityFieldsWithReferences(activities, function(args) { 95 | if ( 96 | objects[args.modelRef] && 97 | objects[args.modelRef][args.instanceRef] && 98 | args.field !== 'foreign_id' 99 | ) { 100 | args.activity[args.field] = 101 | objects[args.modelRef][args.instanceRef]; 102 | } 103 | }); 104 | 105 | callback(err, activities); 106 | }); 107 | }, 108 | 109 | enrichAggregatedActivities: function(aggregatedActivities) { 110 | // Return a Promise instead of using node style callbacks (_enrichAggregatedActivities accepts one argument + callback) 111 | return Promise.denodeify(this._enrichAggregatedActivities, 1).call(this, aggregatedActivities); 112 | }, 113 | 114 | _enrichAggregatedActivities: function(aggregatedActivities, callback) { 115 | var references = {}; 116 | var enrichments = []; 117 | var self = this; 118 | for (var i in aggregatedActivities) { 119 | enrichments.push( 120 | (function(aggregated) { 121 | return function(done) { 122 | self 123 | .enrichActivities(aggregated['activities']) 124 | .then(done.bind(this, null), done); 125 | }; 126 | })(aggregatedActivities[i]) 127 | ); 128 | } 129 | 130 | async.parallel(enrichments, function(err) { 131 | callback(err, aggregatedActivities); 132 | }); 133 | }, 134 | 135 | serializeActivities: function(activities) { 136 | var self = this; 137 | this.iterActivityFieldsWithObjects(activities, function(args) { 138 | var value = args.activity[args.field]; 139 | args.activity[args.field] = self.serializeValue(value); 140 | }); 141 | }, 142 | 143 | serializeActivity: function(activity) { 144 | this.serializeActivities([activity]); 145 | }, 146 | 147 | loadFromStorageOrCustom: function(modelRef, modelClass, refs, callback) { 148 | var ref = capitalizeFirstLetter(modelRef.toLowerCase()); 149 | var customLoader = 'load' + ref + 'FromStorage'; 150 | if (this[customLoader]) { 151 | return this[customLoader](modelClass, refs, callback); 152 | } else { 153 | return this.loadFromStorage(modelClass, refs, callback); 154 | } 155 | }, 156 | // Backend specific functions 157 | loadFromStorage: function(modelClass, refs, callback) {}, 158 | 159 | serializeValue: function(value) { 160 | return value; 161 | }, 162 | 163 | getClassFromRef: function(ref) {}, 164 | }; 165 | 166 | module.exports = BaseBackend; 167 | -------------------------------------------------------------------------------- /src/backends/mongoose.js: -------------------------------------------------------------------------------- 1 | var baseActivitySchemaPlugin = require('./activity.js'); 2 | var util = require('util'); 3 | var baseBackend = require('./base'); 4 | var mongoose = require('mongoose'); 5 | var stream = require('../index.js'); 6 | 7 | function Backend() {} 8 | 9 | function setupMongoose(m) { 10 | Backend.prototype.getMongoose = function() { 11 | return m; 12 | }; 13 | } 14 | 15 | util.inherits(Backend, baseBackend); 16 | 17 | Backend.prototype.serializeValue = function(value) { 18 | if (typeof value._id != 'undefined') { 19 | return value.constructor.modelName + ':' + value._id; 20 | } else { 21 | return value; 22 | } 23 | }; 24 | 25 | (Backend.prototype.collectReferences = function(activities) { 26 | var modelReferences = {}; 27 | this.iterActivityFieldsWithReferences(activities, function(args) { 28 | if (modelReferences[args.modelRef]) { 29 | modelReferences[args.modelRef].push(args.instanceRef); 30 | } else { 31 | modelReferences[args.modelRef] = [args.instanceRef]; 32 | } 33 | }); 34 | 35 | return modelReferences; 36 | }), (Backend.prototype.loadFromStorage = function(modelClass, objectsIds, callback) { 37 | var found = {}; 38 | var paths = []; 39 | if (typeof modelClass.pathsToPopulate === 'function') { 40 | var paths = modelClass.pathsToPopulate(); 41 | } 42 | 43 | // filter out invalid object ids 44 | var validObjectIds = []; 45 | objectsIds.forEach(function(objectId) { 46 | try { 47 | new mongoose.Types.ObjectId(objectId); 48 | validObjectIds.push(objectId); 49 | } catch (e) { 50 | // skip invalid ids 51 | return; 52 | } 53 | }); 54 | 55 | modelClass 56 | .find({ _id: { $in: validObjectIds } }) 57 | .populate(paths) 58 | .exec(function(err, docs) { 59 | for (var i in docs) { 60 | found[docs[i]._id] = docs[i]; 61 | } 62 | 63 | callback(err, found); 64 | }); 65 | }); 66 | 67 | Backend.prototype.getClassFromRef = function(ref) { 68 | // TODO: raise error if this.getMongoose returns undefined 69 | // it means user forgot to call setupMongoose 70 | var mongoose = this.getMongoose(); 71 | var mongooseModel; 72 | try { 73 | var mongooseModel = mongoose.model(ref); 74 | } catch (e) { 75 | // fail silently 76 | } 77 | 78 | return mongooseModel; 79 | }; 80 | 81 | Backend.prototype.getIdFromRef = function(ref) { 82 | return ref.split(':')[1]; 83 | }; 84 | 85 | function getReferencePaths(paths) { 86 | var names = []; 87 | for (var k in paths) { 88 | if (paths[k].instance === 'ObjectID' && k !== '_id') { 89 | names.push(paths[k].path); 90 | } 91 | } 92 | 93 | return names.join(' '); 94 | } 95 | 96 | var mongooseActivitySchemaPlugin = function(schema, options) { 97 | schema.pre('save', function(next) { 98 | this.wasNew = this.isNew; 99 | next(); 100 | }); 101 | 102 | schema.post('save', function(doc) { 103 | var paths = getReferencePaths(doc.schema.paths); 104 | doc.populate(paths, function(err, docP) { 105 | if (docP.wasNew) { 106 | stream.FeedManager.activityCreated(docP); 107 | } 108 | }); 109 | }); 110 | 111 | schema.post('remove', function(doc) { 112 | var paths = getReferencePaths(doc.schema.paths); 113 | doc.populate(paths, function(err, docP) { 114 | stream.FeedManager.activityDeleted(docP); 115 | }); 116 | }); 117 | 118 | // add Mongoose specific proto functions 119 | schema.methods.referencesPaths = function() { 120 | return this; 121 | }; 122 | 123 | schema.methods.getStreamBackend = function() { 124 | return new Backend(); 125 | }; 126 | 127 | schema.statics.activityModelReference = function() { 128 | return this.modelName; 129 | }; 130 | 131 | schema.methods.activityVerb = function() { 132 | return this.constructor.modelName; 133 | }; 134 | 135 | schema.statics.pathsToPopulate = function() { 136 | return []; 137 | }; 138 | }; 139 | 140 | module.exports.activity = function(schema, options) { 141 | schema.plugin(baseActivitySchemaPlugin); 142 | schema.plugin(mongooseActivitySchemaPlugin); 143 | }; 144 | 145 | module.exports.Backend = Backend; 146 | module.exports.setupMongoose = setupMongoose; 147 | -------------------------------------------------------------------------------- /src/backends/waterline.js: -------------------------------------------------------------------------------- 1 | var baseActivitySchemaPlugin = require('./activity.js'); 2 | var util = require('util'); 3 | var baseBackend = require('./base'); 4 | 5 | function Backend() {} 6 | 7 | /* 8 | * instance.id -> 57e1836a45c973081a8aedfd 9 | * instance.identity -> undefined 10 | * model.identity -> 'passport' 11 | */ 12 | 13 | util.inherits(Backend, baseBackend); 14 | 15 | Backend.prototype.serializeValue = function(value) { 16 | throw new Error('Cant serialize for waterline since model.identity is not accessible from the instance'); 17 | }; 18 | 19 | (Backend.prototype.collectReferences = function(activities) { 20 | var modelReferences = {}; 21 | this.iterActivityFieldsWithReferences(activities, function(args) { 22 | if (modelReferences[args.modelRef]) { 23 | modelReferences[args.modelRef].push(args.instanceRef); 24 | } else { 25 | modelReferences[args.modelRef] = [args.instanceRef]; 26 | } 27 | }); 28 | 29 | return modelReferences; 30 | }), (Backend.prototype.loadFromStorage = function(modelClass, objectIds, callback) { 31 | var found = {}; 32 | var paths = []; 33 | if (typeof modelClass.pathsToPopulate === 'function') { 34 | var paths = modelClass.pathsToPopulate(); 35 | } 36 | 37 | modelClass.find({ id: objectIds }).exec(function(err, docs) { 38 | for (var i in docs) { 39 | found[docs[i].id] = docs[i]; 40 | } 41 | 42 | callback(err, found); 43 | }); 44 | }); 45 | 46 | Backend.prototype.getClassFromRef = function(ref) { 47 | // takes string user, return User model 48 | try { 49 | var modelClass = sails.models[ref]; 50 | } catch (e) { 51 | // fail silently 52 | } 53 | 54 | return modelClass; 55 | }; 56 | 57 | Backend.prototype.getIdFromRef = function(ref) { 58 | return ref.split(':')[1]; 59 | }; 60 | 61 | module.exports.Backend = Backend; 62 | -------------------------------------------------------------------------------- /src/config.default.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | /** 3 | * GetStream.io API key 4 | */ 5 | apiKey: '', 6 | 7 | /** 8 | * GetStream.io API Secret 9 | */ 10 | apiSecret: '', 11 | 12 | /** 13 | * GetStream.io API App ID 14 | */ 15 | apiAppId: '', 16 | 17 | /** 18 | * GetStream.io API Location 19 | */ 20 | apiLocation: '', 21 | 22 | /** 23 | * GetStream.io User Feed slug 24 | */ 25 | userFeed: 'user', 26 | 27 | /** 28 | * GetStream.io Notification Feed slug 29 | */ 30 | notificationFeed: 'notification', 31 | 32 | newsFeeds: { 33 | /** 34 | * GetStream.io Flat Feed slug 35 | */ 36 | flat: 'flat', 37 | 38 | /** 39 | * GetStream.io Aggregated Feed slug 40 | */ 41 | aggregated: 'aggregated', 42 | }, 43 | }; 44 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'), 2 | fs = require('fs'), 3 | exists = fs.existsSync || path.existsSync; 4 | 5 | function _loadFile(path) { 6 | var settings = {}; 7 | 8 | var config = JSON.parse(JSON.stringify(require(path).config)); 9 | 10 | Object.keys(config).forEach(function(key) { 11 | settings[key] = config[key]; 12 | }); 13 | 14 | return settings; 15 | } 16 | 17 | var Config = function() { 18 | var settings = {}, 19 | config_file = ''; 20 | // load config from defaults or config file 21 | 22 | if (typeof process != 'undefined' && process.env.STREAM_NODE_CONFIG_DIR) { 23 | config_file = process.env.STREAM_NODE_CONFIG_DIR + '/getstream.js'; 24 | } else { 25 | config_file = process.cwd() + '/getstream.js'; 26 | } 27 | 28 | var default_config_file = path.join(__dirname, 'config.default.js'); 29 | 30 | console.log('exists', exists(config_file)); 31 | 32 | /* istanbul skip else */ 33 | if (exists(config_file)) { 34 | settings = _loadFile(config_file); 35 | } else { 36 | settings = _loadFile(default_config_file); 37 | } 38 | 39 | return settings; 40 | }; 41 | 42 | module.exports = Config; 43 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var FeedManager = require('./FeedManager.js'); 2 | var config = require('./config.js'); 3 | var settings = config(); 4 | var extend = require('util')._extend; 5 | var waterline = require('./backends/waterline'); 6 | var mongoose = require('./backends/mongoose.js'); 7 | 8 | module.exports.FeedManager = new FeedManager(settings); 9 | module.exports.feedManagerFactory = function(options) { 10 | var withSettings = extend({}, settings); 11 | options = options || {}; 12 | 13 | for (var key in withSettings) { 14 | if (withSettings.hasOwnProperty(key) && options.hasOwnProperty(key)) { 15 | withSettings[key] = options[key]; 16 | } 17 | } 18 | 19 | return new FeedManager(withSettings); 20 | }; 21 | 22 | module.exports.mongoose = mongoose; 23 | module.exports.settings = settings; 24 | module.exports.WaterlineBackend = waterline.Backend; 25 | module.exports.MongooseBackend = mongoose.Backend; 26 | -------------------------------------------------------------------------------- /test/backend_activity_test.js: -------------------------------------------------------------------------------- 1 | var Activity = require('../src/backends/activity'), 2 | expect = require('expect.js'); 3 | 4 | describe('Activity', function() { 5 | var activity; 6 | var schema; 7 | 8 | before(function() {}); 9 | 10 | beforeEach(function() { 11 | schema = { methods: {} }; 12 | activity = Activity(schema, {}); 13 | }); 14 | 15 | it('#getStreamBackend', function() { 16 | expect(function() { 17 | schema.methods.getStreamBackend(); 18 | }).to.throwError(); 19 | }); 20 | 21 | it('#activityActorProp', function() { 22 | var prop = schema.methods.activityActorProp(); 23 | 24 | expect(prop).to.be('user'); 25 | }); 26 | 27 | it('#activityVerb', function() { 28 | var prop = schema.methods.activityVerb(); 29 | 30 | expect(prop).to.be('Object'); 31 | }); 32 | 33 | it('#activityExtraData', function() { 34 | var prop = schema.methods.activityExtraData(); 35 | 36 | expect(prop).to.eql({}); 37 | }); 38 | 39 | it('#activityNotify', function() { 40 | schema.methods.activityNotify(); 41 | }); 42 | 43 | after(function() {}); 44 | }); 45 | -------------------------------------------------------------------------------- /test/backends/base_test.js: -------------------------------------------------------------------------------- 1 | var Backend = require('../../src/backends/base'), 2 | expect = require('expect.js'); 3 | 4 | describe('Base Backend', function() { 5 | var backend; 6 | 7 | beforeEach(function() { 8 | backend = new Backend(); 9 | }); 10 | 11 | describe('#collectReferences', function() { 12 | it('(1) default', function() { 13 | var refs = backend.collectReferences([ 14 | { 15 | actor: 'User:123456', 16 | object: 'Tweet:00001', 17 | other: 'something' 18 | } 19 | ]); 20 | 21 | expect(refs).to.eql({ 22 | User: ['123456'], 23 | Tweet: ['00001'] 24 | }); 25 | }); 26 | 27 | it('(2) origin field', function() { 28 | var refs = backend.collectReferences([ 29 | { 30 | actor: 'User:123456', 31 | object: 'Tweet:00001', 32 | origin: 'Tweet:00002' 33 | } 34 | ]); 35 | 36 | expect(refs).to.eql({ 37 | User: ['123456'], 38 | Tweet: ['00001'] 39 | }); 40 | }); 41 | 42 | it('(3) multiple', function() { 43 | var refs = backend.collectReferences([ 44 | { 45 | actor: 'User:123456', 46 | object: 'Tweet:00001', 47 | other: 'Tweet:00002' 48 | } 49 | ]); 50 | 51 | expect(refs).to.eql({ 52 | User: ['123456'], 53 | Tweet: ['00001', '00002'] 54 | }); 55 | }); 56 | }); 57 | 58 | it('#serializeActivity', function() { 59 | expect(backend.serializeActivity).to.be.a(Function); 60 | 61 | var activity = { 62 | actor: 'User:123456', 63 | object: 'Tweet:1', 64 | other: 'matthisk' 65 | }; 66 | 67 | backend.serializeActivity(activity); 68 | 69 | expect(activity).to.eql({ 70 | actor: 'User:123456', 71 | object: 'Tweet:1', 72 | other: 'matthisk' 73 | }); 74 | }); 75 | 76 | it('#loadFromStorage', function() { 77 | expect(backend.loadFromStorage).to.be.a(Function); 78 | 79 | backend.loadFromStorage(); 80 | }); 81 | 82 | it('#getClassFromRef', function() { 83 | expect(backend.getClassFromRef).to.be.a(Function); 84 | 85 | backend.getClassFromRef(); 86 | }); 87 | 88 | it('#serializeValue', function() { 89 | expect(backend.serializeValue).to.be.a(Function); 90 | 91 | var v = backend.serializeValue(1); 92 | 93 | expect(v).to.be(1); 94 | }); 95 | }); 96 | -------------------------------------------------------------------------------- /test/backends/mongoose_test.js: -------------------------------------------------------------------------------- 1 | var should = require('should'), 2 | StreamMongoose = require('../../src/backends/mongoose.js'), 3 | mongoose = require('mongoose'), 4 | Schema = mongoose.Schema, 5 | stream = require('../../src/index.js'), 6 | Promise = require('promise'), 7 | sinon = require('sinon'), 8 | mockery = require('mockery'); 9 | 10 | require('../utils/promise'); 11 | 12 | mongoose.Promise = global.Promise; 13 | 14 | mongoose.connect('mongodb://localhost/test', { useMongoClient: true }); 15 | 16 | var userSchema = new Schema({ 17 | name: String, 18 | }); 19 | 20 | var linkSchema = new Schema({ 21 | href: String, 22 | }); 23 | 24 | var tweetSchema = new Schema({ 25 | text: String, 26 | actor: { type: Schema.Types.ObjectId, ref: 'User' }, 27 | bg: String, 28 | link: { type: Schema.Types.ObjectId, ref: 'Link' } 29 | }); 30 | 31 | tweetSchema.plugin(StreamMongoose.activity); 32 | 33 | tweetSchema.statics.pathsToPopulate = function() { 34 | return ['actor', 'link']; 35 | }; 36 | 37 | tweetSchema.methods.activityNotify = function() { 38 | return [ 39 | stream.FeedManager.getFeed('notification', '1'), 40 | stream.FeedManager.getFeed('notification', '2') 41 | ]; 42 | }; 43 | 44 | tweetSchema.methods.activityExtraData = function() { 45 | return { bg: this.bg, link: this.link }; 46 | }; 47 | 48 | tweetSchema.methods.activityActorProp = function() { 49 | return 'actor'; 50 | }; 51 | 52 | StreamMongoose.setupMongoose(mongoose); 53 | 54 | var Tweet = mongoose.model('Tweet', tweetSchema); 55 | var User = mongoose.model('User', userSchema); 56 | var Link = mongoose.model('Link', linkSchema); 57 | var backend = new StreamMongoose.Backend(); 58 | 59 | describe('Backend', function() { 60 | var requestStub; 61 | 62 | before(function(done) { 63 | var actor = new User({ name: 'actor1' }); 64 | var link; 65 | 66 | var save = Promise.denodeify(actor.save); 67 | 68 | save 69 | .call(actor) 70 | .then( 71 | function() { 72 | this.actor = actor; 73 | link = new Link({ href: 'https://getstream.io' }); 74 | var linkSave = Promise.denodeify(link.save); 75 | return linkSave.call(link); 76 | }.bind(this), 77 | done 78 | ) 79 | .then( 80 | function() { 81 | this.link = link; 82 | done(); 83 | }.bind(this), 84 | done 85 | ); 86 | 87 | // replace the module `request` with a stub object 88 | mockery.enable({}); 89 | requestStub = sinon.stub(); 90 | mockery.registerMock('request', requestStub); 91 | }); 92 | 93 | after(function() { 94 | mockery.disable(); 95 | }); 96 | 97 | it('serialise null', function(done) { 98 | var activity = { object: null }; 99 | backend.serializeActivities([activity]); 100 | backend 101 | .enrichActivities([activity]) 102 | .then(function(enriched) { 103 | enriched.should.length(1); 104 | enriched[0].should.have.property('object', null); 105 | done(); 106 | }) 107 | .catch(done); 108 | }); 109 | 110 | it('dont enrich origin field', function(done) { 111 | var activity = { origin: 'user:42' }; 112 | backend 113 | .enrichActivities([activity]) 114 | .then(function(enriched) { 115 | enriched.should.length(1); 116 | enriched[0].should.have.property('origin', 'user:42'); 117 | done(); 118 | }) 119 | .catch(done); 120 | }); 121 | 122 | it('enrich aggregated activity complex mix', function(done) { 123 | var self = this; 124 | var tweet1 = new Tweet(); 125 | var tweet2 = new Tweet(); 126 | tweet1.text = 'tweet1'; 127 | tweet1.actor = this.actor; 128 | tweet2.text = 'tweet2'; 129 | tweet2.actor = this.actor; 130 | var tweets = [tweet1, tweet2]; 131 | Tweet.create(tweets, function(err) { 132 | should.not.exist(err); 133 | var activities = [tweet1.createActivity()]; 134 | var activities2 = [tweet2.createActivity()]; 135 | backend.serializeActivities(activities); 136 | backend.serializeActivities(activities2); 137 | var aggregatedActivities = [ 138 | { actor_count: 1, activities: activities }, 139 | { actor_count: 1, activities: activities2 } 140 | ]; 141 | backend 142 | .enrichAggregatedActivities(aggregatedActivities) 143 | .then(function(enriched) { 144 | enriched.should.length(2); 145 | var firstAggregation = enriched[0]; 146 | var secondAggregation = enriched[1]; 147 | firstAggregation.should.have 148 | .property('activities') 149 | .with.lengthOf(1); 150 | firstAggregation['activities'][0].should.have.property('actor'); 151 | firstAggregation['activities'][0].should.have.property('object'); 152 | firstAggregation['activities'][0].object.should.have.property('_id'); 153 | firstAggregation['activities'][0].should.have.property('verb'); 154 | secondAggregation['activities'][0].should.have.property('actor'); 155 | secondAggregation['activities'][0].should.have.property('object'); 156 | secondAggregation['activities'][0].object.should.have.property('_id'); 157 | secondAggregation['activities'][0].should.have.property('verb'); 158 | firstAggregation['activities'][0].object._id.should.not.equal(secondAggregation['activities'][0].object._id); 159 | done(); 160 | }) 161 | .catch(done); 162 | }); 163 | }); 164 | 165 | it('enrich aggregated activity', function(done) { 166 | var self = this; 167 | var tweet = new Tweet(); 168 | tweet.text = 'test'; 169 | tweet.actor = this.actor; 170 | tweet.save(function(err) { 171 | should.not.exist(err); 172 | var activity = tweet.createActivity(); 173 | backend.serializeActivities([activity]); 174 | var aggregatedActivities = [ 175 | { actor_count: 1, activities: [activity] } 176 | ]; 177 | backend 178 | .enrichAggregatedActivities(aggregatedActivities) 179 | .then(function(enriched) { 180 | enriched.should.length(1); 181 | enriched[0].should.have 182 | .property('activities') 183 | .with.lengthOf(1); 184 | enriched[0]['activities'][0].should.have.property('actor'); 185 | enriched[0]['activities'][0].should.have.property('object'); 186 | enriched[0]['activities'][0].should.have.property('verb'); 187 | done(); 188 | }) 189 | .catch(done); 190 | }); 191 | }); 192 | 193 | it('enrich aggregated activity with 2 groups', function(done) { 194 | var self = this; 195 | var tweet = new Tweet(); 196 | tweet.text = 'test'; 197 | tweet.actor = this.actor; 198 | tweet.save(function(err) { 199 | should.not.exist(err); 200 | var activity = tweet.createActivity(); 201 | backend.serializeActivities([activity]); 202 | var aggregatedActivities = [ 203 | { actor_count: 1, activities: [activity] }, 204 | { actor_count: 1, activities: [activity, activity] } 205 | ]; 206 | backend 207 | .enrichAggregatedActivities(aggregatedActivities) 208 | .then(function(enriched) { 209 | enriched.should.length(2); 210 | enriched[0].should.have 211 | .property('activities') 212 | .with.lengthOf(1); 213 | enriched[0]['activities'][0].should.have.property('actor'); 214 | enriched[0]['activities'][0].should.have.property('object'); 215 | enriched[0]['activities'][0].should.have.property('verb'); 216 | 217 | enriched[1].should.have 218 | .property('activities') 219 | .with.lengthOf(2); 220 | enriched[1]['activities'][0].should.have.property('actor'); 221 | enriched[1]['activities'][0].should.have.property('object'); 222 | enriched[1]['activities'][0].should.have.property('verb'); 223 | done(); 224 | }) 225 | .catch(done); 226 | }); 227 | }); 228 | 229 | it('delete activity', function(done) { 230 | var tweet = new Tweet(); 231 | tweet.text = 'test'; 232 | tweet.actor = this.actor; 233 | tweet.save(function(err) { 234 | if (err) return done(err); 235 | tweet.remove(done); 236 | }); 237 | }); 238 | 239 | it('enrich one activity', function() { 240 | var self = this; 241 | var tweet = new Tweet(); 242 | tweet.text = 'test'; 243 | tweet.actor = this.actor; 244 | 245 | return tweet.save 246 | .promisify(tweet) 247 | .then(function() { 248 | return tweet.populate.promisify(tweet, 'actor'); 249 | }) 250 | .then(function(tweet) { 251 | var activity = tweet.createActivity(); 252 | 253 | backend.serializeActivities([activity]); 254 | activity = JSON.parse(JSON.stringify(activity)); 255 | 256 | return backend.enrichActivities([activity]); 257 | }) 258 | .then(function(enriched) { 259 | enriched.should.length(1); 260 | enriched[0].should.have.property('actor'); 261 | enriched[0]['actor'].should.have.property('_id', self.actor._id); 262 | enriched[0].should.have.property('foreign_id', 'Tweet:' + tweet._id); 263 | }); 264 | }); 265 | 266 | it('custom fields enrichment', function() { 267 | var self = this; 268 | var tweet = new Tweet(); 269 | tweet.text = 'test'; 270 | tweet.bg = 'bgvalue'; 271 | tweet.actor = this.actor; 272 | tweet.link = this.link; 273 | 274 | return tweet.save 275 | .promisify(tweet) 276 | .then(function() { 277 | return tweet.populate.promisify(tweet, ['actor', 'link']); 278 | }) 279 | .then(function(tweet) { 280 | var activity = tweet.createActivity(); 281 | 282 | return backend.enrichActivities([activity]); 283 | }) 284 | .then(function(enriched) { 285 | enriched.should.length(1); 286 | enriched[0].should.have.property('actor'); 287 | enriched[0]['actor'].should.have.property('_id', self.actor._id); 288 | enriched[0].should.have.property('object'); 289 | enriched[0]['object'].should.have.property('_id', tweet._id); 290 | enriched[0]['object'].should.have.property('text', tweet.text); 291 | enriched[0].should.have.property('bg', 'bgvalue'); 292 | enriched[0].should.have.property('link'); 293 | enriched[0]['link'].should.have.property('_id', self.link._id); 294 | }); 295 | }); 296 | 297 | it('custom fields serialisation', function() { 298 | var tweet = new Tweet(); 299 | tweet.text = 'test'; 300 | tweet.bg = 'bgvalue'; 301 | tweet.actor = this.actor; 302 | tweet.link = this.link; 303 | 304 | return tweet.save 305 | .promisify(tweet) 306 | .then(function() { 307 | return tweet.populate.promisify(tweet, ['actor', 'link']); 308 | }) 309 | .then(function(tweet) { 310 | var activity = tweet.createActivity(); 311 | tweet.getStreamBackend().serializeActivities([activity]); 312 | activity.should.have.property('actor', 'User:' + tweet.actor._id); 313 | activity.should.have.property('link', 'Link:' + tweet.link._id); 314 | activity.should.have.property('bg', 'bgvalue'); 315 | activity.should.have.property('object', 'Tweet:' + tweet._id); 316 | }); 317 | }); 318 | 319 | it('serialise objects into refs', function() { 320 | var tweet = new Tweet(); 321 | tweet.text = 'test'; 322 | tweet.actor = this.actor; 323 | 324 | return tweet.save 325 | .promisify(tweet) 326 | .then(function() { 327 | return tweet.populate.promisify(tweet, 'actor'); 328 | }) 329 | .then(function() { 330 | var activity = tweet.createActivity(); 331 | tweet.getStreamBackend().serializeActivities([activity]); 332 | 333 | activity.should.have.property('actor', 'User:' + tweet.actor._id); 334 | activity.should.have.property('object', 'Tweet:' + tweet._id); 335 | }); 336 | }); 337 | 338 | it('enrich two activity', function() { 339 | var tweet1 = new Tweet(); 340 | tweet1.text = 'test1'; 341 | tweet1.actor = this.actor; 342 | 343 | var tweet2 = new Tweet(); 344 | tweet2.text = 'test2'; 345 | tweet2.actor = this.actor; 346 | 347 | return Promise.all([ 348 | tweet1.save.promisify(tweet1), 349 | tweet2.save.promisify(tweet2) 350 | ]) 351 | .then(function() { 352 | var activities = [ 353 | tweet1.createActivity(), 354 | tweet2.createActivity() 355 | ]; 356 | 357 | return backend.enrichActivities(activities); 358 | }) 359 | .then(function(enriched) { 360 | enriched.should.length(2); 361 | enriched[0].should.have.property('foreign_id'); 362 | enriched[1].should.have.property('foreign_id'); 363 | enriched[0]['foreign_id'].should.not.equal(enriched[1]['foreign_id']); 364 | }); 365 | }); 366 | }); 367 | 368 | describe('Tweet', function() { 369 | before(function(done) { 370 | var actor = new User({ name: 'actor1' }); 371 | actor.save(); 372 | this.actor = actor; 373 | done(); 374 | }); 375 | 376 | it('should follow model reference naming convention', function() { 377 | Tweet.activityModelReference().should.be.exactly('Tweet'); 378 | }); 379 | 380 | it('check to target field', function() { 381 | var tweet = new Tweet({}); 382 | tweet.actor = this.actor; 383 | tweet.save(); 384 | var activity = tweet.createActivity(); 385 | activity.should.have.property('to', [ 386 | 'notification:1', 387 | 'notification:2' 388 | ]); 389 | }); 390 | 391 | it('should be able to serialise to ref', function() { 392 | var tweet = new Tweet({}); 393 | var ref = tweet.getStreamBackend().serializeValue(tweet); 394 | ref.should.be.exactly('Tweet:' + tweet._id); 395 | }); 396 | 397 | it('#createActivity().activityVerb', function() { 398 | var tweet = new Tweet({}); 399 | tweet.actor = this.actor; 400 | tweet.save(); 401 | var activity = tweet.createActivity(); 402 | activity.should.have.property('verb', 'Tweet'); 403 | }); 404 | 405 | it('#createActivity.activityObject', function() { 406 | var tweet = new Tweet({}); 407 | tweet.actor = this.actor; 408 | tweet.save(); 409 | var activity = tweet.createActivity(); 410 | activity.should.have.property('object'); 411 | }); 412 | 413 | it('#createActivity.activityActor', function() { 414 | var tweet = new Tweet({}); 415 | tweet.actor = this.actor; 416 | tweet.save(); 417 | var activity = tweet.createActivity(); 418 | activity.should.have.property('actor'); 419 | }); 420 | }); 421 | -------------------------------------------------------------------------------- /test/backends/waterline_test.js: -------------------------------------------------------------------------------- 1 | var Backend = require('../../src/backends/waterline').Backend, 2 | sinon = require('sinon'), 3 | extend = require('util')._extend, 4 | expect = require('expect.js'); 5 | 6 | describe('Waterline Backend', function() { 7 | var backend; 8 | 9 | beforeEach(function() { 10 | backend = new Backend(); 11 | }); 12 | 13 | it('#serializeValue', function() { 14 | expect(function() { 15 | backend.serializeValue('value'); 16 | }).to.throwException(); 17 | }); 18 | 19 | describe('#collectReferences', function() { 20 | it('(1) default', function() { 21 | var refs = backend.collectReferences([ 22 | { 23 | actor: 'User:123456', 24 | object: 'Tweet:00001', 25 | other: 'something' 26 | }, 27 | ]); 28 | 29 | expect(refs).to.eql({ 30 | User: ['123456'], 31 | Tweet: ['00001'] 32 | }); 33 | }); 34 | 35 | it('(2) origin field', function() { 36 | var refs = backend.collectReferences([ 37 | { 38 | actor: 'User:123456', 39 | object: 'Tweet:00001', 40 | origin: 'Tweet:00002' 41 | }, 42 | ]); 43 | 44 | expect(refs).to.eql({ 45 | User: ['123456'], 46 | Tweet: ['00001'] 47 | }); 48 | }); 49 | 50 | it('(3) multiple', function() { 51 | var refs = backend.collectReferences([ 52 | { 53 | actor: 'User:123456', 54 | object: 'Tweet:00001', 55 | other: 'Tweet:00002' 56 | } 57 | ]); 58 | 59 | expect(refs).to.eql({ 60 | User: ['123456'], 61 | Tweet: ['00001', '00002'] 62 | }); 63 | }); 64 | }); 65 | 66 | it('#getIdFromRef', function() { 67 | expect(backend.getIdFromRef).to.be.a(Function); 68 | 69 | var ref = backend.getIdFromRef('User:1234'); 70 | 71 | expect(ref).to.be('1234'); 72 | }); 73 | 74 | it('#getClassFromRef', function() { 75 | expect(backend.getClassFromRef).to.be.a(Function); 76 | 77 | var mc = backend.getClassFromRef('user'); 78 | 79 | expect(mc).to.be(undefined); 80 | }); 81 | 82 | describe('#loadFromStorage', function() { 83 | var modelClass = { 84 | find: function(ids) { 85 | expect(ids).to.eql({ id: [0, 1, 2] }); 86 | 87 | return { 88 | exec: function(cb) { 89 | cb(null, [{ id: 0 }, { id: 1 }, { id: 2 }]); 90 | } 91 | }; 92 | }, 93 | }; 94 | 95 | it('#loadFromStorage', function(done) { 96 | expect(backend.loadFromStorage).to.be.a(Function); 97 | 98 | function cb(err, found) { 99 | done(); 100 | } 101 | 102 | backend.loadFromStorage(modelClass, [0, 1, 2], cb); 103 | }); 104 | 105 | it('#loadFromStorage', function(done) { 106 | expect(backend.loadFromStorage).to.be.a(Function); 107 | 108 | modelClass = extend({}, modelClass); 109 | modelClass['pathsToPopulate'] = function() {}; 110 | 111 | function cb(err, found) { 112 | done(); 113 | } 114 | 115 | backend.loadFromStorage(modelClass, [0, 1, 2], cb); 116 | }); 117 | }); 118 | }); 119 | -------------------------------------------------------------------------------- /test/feed_manager_test.js: -------------------------------------------------------------------------------- 1 | var FeedManager = require('../src/FeedManager'), 2 | pmock = require('pmock'), 3 | mockery = require('mockery'), 4 | sinon = require('sinon'), 5 | expect = require('expect.js'); 6 | 7 | describe('FeedManager', function() { 8 | var fm; 9 | 10 | before(function() { 11 | // replace the module `request` with a stub object 12 | mockery.enable({}); 13 | var requestStub = sinon.stub(); 14 | mockery.registerMock('request', requestStub); 15 | 16 | this.env = pmock.env({ 17 | STREAM_URL: null, 18 | }); 19 | }); 20 | 21 | beforeEach(function() { 22 | fm = new FeedManager({ 23 | apiKey: 12345, 24 | apiSecret: 'abcdefg', 25 | apiAppId: 1000, 26 | apiLocation: 'qa', 27 | userFeed: 'user', 28 | notificationFeed: 'notification', 29 | newsFeeds: { 30 | flat: 'timeline', 31 | aggregated: 'timeline_aggregated', 32 | }, 33 | }); 34 | }); 35 | 36 | it('#settings', function() { 37 | expect(fm.client.options.location).to.be('qa'); 38 | expect(fm.client.apiKey).to.be(12345); 39 | expect(fm.client.apiSecret).to.be('abcdefg'); 40 | expect(fm.client.appId).to.be(1000); 41 | }); 42 | 43 | it('#getUserFeed', function() { 44 | var feed = fm.getUserFeed('matthisk'); 45 | 46 | expect(feed.id).to.be('user:matthisk'); 47 | }); 48 | 49 | it('#getNotificationFeed', function() { 50 | var feed = fm.getNotificationFeed('matthisk'); 51 | 52 | expect(feed.id).to.be('notification:matthisk'); 53 | }); 54 | 55 | it('#getNewsFeeds', function() { 56 | var feeds = fm.getNewsFeeds('matthisk'); 57 | 58 | expect(feeds['timeline'].id).to.be('timeline:matthisk'); 59 | expect(feeds['timeline_aggregated'].id).to.be( 60 | 'timeline_aggregated:matthisk' 61 | ); 62 | }); 63 | 64 | it('#followUser', function() { 65 | var p = fm.followUser('harry', 'matthisk'); 66 | 67 | expect(p.then).to.be.a(Function); 68 | }); 69 | 70 | it('#unfollowUser', function() { 71 | var p = fm.unfollowUser('matthisk', 'harry'); 72 | 73 | expect(p.then).to.be.a(Function); 74 | }); 75 | 76 | after(function() { 77 | this.env.reset(); 78 | }); 79 | }); 80 | -------------------------------------------------------------------------------- /test/index_test.js: -------------------------------------------------------------------------------- 1 | var expect = require('expect.js'), 2 | mockery = require('mockery'), 3 | path = require('path'), 4 | pmock = require('pmock'), 5 | Config = require('../src/config'), 6 | BaseBackend = require('../src/backends/base.js'), 7 | FeedManager = require('../src/FeedManager'), 8 | main = require('../src/index'); 9 | 10 | describe('StreamBackend', function() { 11 | it('should have right properties', function() { 12 | new BaseBackend().should.have.property('collectReferences'); 13 | new BaseBackend().should.have.property('enrichActivities'); 14 | new BaseBackend().should.have.property('enrichAggregatedActivities'); 15 | }); 16 | 17 | it('#collectReferences()', function() {}); 18 | 19 | it('#retreiveObjects()', function() {}); 20 | 21 | it('#enrichActivities()', function() {}); 22 | 23 | it('#enrichAggregatedActivities()', function() {}); 24 | }); 25 | 26 | describe('feedManagerFactory', function() { 27 | it('should return a FeedManager instance', function() { 28 | var fm = main.feedManagerFactory({}); 29 | 30 | expect(fm).to.be.a(FeedManager); 31 | }); 32 | 33 | it('should ignore unkown settings', function() { 34 | var fm = main.feedManagerFactory({ 35 | unknown: 'abcdefg', 36 | }); 37 | 38 | expect(fm).to.be.a(FeedManager); 39 | expect(fm.settings.unknown).to.be.undefined; 40 | }); 41 | 42 | it('should override known settings', function() { 43 | var fm = main.feedManagerFactory({ 44 | apiKey: 'abcdefg', 45 | }); 46 | 47 | expect(fm).to.be.a(FeedManager); 48 | expect(fm.settings.apiKey).to.be('abcdefg'); 49 | }); 50 | }); 51 | 52 | describe('Config', function() { 53 | it('default config', function() { 54 | var settings = main.FeedManager.settings; 55 | 56 | var expected = require('../getstream.js').config; 57 | expect(settings).to.eql(expected); 58 | }); 59 | }); 60 | 61 | describe.skip('Config Env Var', function() { 62 | var configDir = path.join(__dirname, './tmp'); 63 | var configFile = path.join(configDir, 'getstream.js'); 64 | 65 | before(function() { 66 | this.env = pmock.env({ 67 | STREAM_NODE_CONFIG_DIR: configDir, 68 | }); 69 | 70 | mockery.enable({ 71 | warnOnUnregistered: false, 72 | useCleanCache: true, 73 | }); 74 | mockery.registerMock('fs', { 75 | existsSync: function() { 76 | return true; 77 | }, 78 | }); 79 | mockery.registerMock(configFile, { config: { apiKey: 12345 } }); 80 | }); 81 | 82 | after(function() { 83 | mockery.disable(); 84 | this.env.reset(); 85 | }); 86 | 87 | /** 88 | * Mockery doesn't work correctly here 89 | * SKip this test until we fix that 90 | */ 91 | it.skip('env var config dir', function() { 92 | var settings = Config(); 93 | 94 | expect(settings.apiKey).to.be(12345); 95 | }); 96 | }); 97 | 98 | describe('Config Default', function() { 99 | before(function() { 100 | this.cwd = pmock.cwd('/tmp'); 101 | }); 102 | 103 | after(function() { 104 | this.cwd.reset(); 105 | }); 106 | 107 | it('env var config dir', function() { 108 | var settings = Config(); 109 | 110 | var expected = require('../src/config.default.js').config; 111 | 112 | expect(settings).to.eql(expected); 113 | }); 114 | }); 115 | -------------------------------------------------------------------------------- /test/utils/promise.js: -------------------------------------------------------------------------------- 1 | var Promise = require('promise'); 2 | 3 | /** 4 | * Use this monkey patch to enable promises on 5 | * mongoose methods 6 | */ 7 | Function.prototype.promisify = function(ctx) { 8 | var args = Array.prototype.slice.call(arguments, 1); 9 | 10 | var fn = Promise.denodeify(this); 11 | return fn.apply(ctx, args); 12 | }; 13 | --------------------------------------------------------------------------------