From 50645bb8cc5ab096d29437abdb39c587c1632a7b Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Thu, 29 Aug 2019 14:02:34 +0100 Subject: [PATCH 01/23] updated travis and test --- package.json | 145 ++++++++++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 78 deletions(-) diff --git a/package.json b/package.json index 0f97b65..6d3cebc 100755 --- a/package.json +++ b/package.json @@ -1,80 +1,69 @@ { - "name": "archangel_barefoot_nomad", - "version": "1.0.0", - "description": "An application for company global travels and accommodation", - "main": "index.js", - "scripts": { - "build": "babel -d ./build ./src -s", - "prod": "set NODE_ENV=production&& node build/index.js", - "start": "set NODE_ENV=development&& babel-node src/index.js", - "dev": "set DEBUG=web-app && set NODE_ENV=development&& nodemon src/index.js --exec babel-node", - "test": "set NODE_ENV=test&& sequelize db:migrate:undo:all && sequelize db:migrate && sequelize db:seed:all && mocha --timeout 0 ./src/tests/*.js --require @babel/register --reporter spec --exec babel-node --exit", - "generate-lcov": "nyc report --reporter=text-lcov >lcov.info", - "coveralls-coverage": "coveralls < lcov.info", - "coverage": "nyc npm test && npm run generate-lcov && npm run coveralls-coverage", - "coveralls": "nyc --reporter=lcov --reporter=text-lcov npm test", - "create:db": "set NODE_ENV=development&& sequelize db:create", - "drop:db": "set NODE_ENV=development&& sequelize db:drop", - "undo:db": "sequelize db:migrate:undo:all", - "create:tables": "set NODE_ENV=development&& sequelize db:migrate && sequelize db:seed:all" - }, - "author": "Andela Simulations Programme", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.5.5", - "@sendgrid/mail": "^6.4.0", - "bcryptjs": "^2.4.3", - "chai": "^4.2.0", - "chai-http": "^4.3.0", - "core-js": "^3.2.1", - "cors": "^2.8.4", - "coveralls": "^3.0.3", - "crypto-random-string": "^3.0.1", - "debug": "^4.1.1", - "dotenv": "^6.2.0", - "ejs": "^2.6.1", - "errorhandler": "^1.5.0", - "express": "^4.17.1", - "express-jwt": "^5.3.1", - "express-session": "^1.15.6", - "express-validator": "^6.1.1", - "jsonwebtoken": "^8.3.0", - "method-override": "^2.3.10", - "methods": "^1.1.2", - "morgan": "^1.9.1", - "nodemailer": "^6.3.0", - "passport": "^0.4.0", - "passport-facebook": "^3.0.0", - "passport-google-oauth20": "^2.0.0", - "passport-local": "^1.0.0", - "path": "^0.12.7", - "pg": "^7.12.1", - "pg-hstore": "^2.3.3", - "regenerator-runtime": "^0.13.3", - "request": "^2.87.0", - "sendgrid": "^5.2.3", - "sequelize": "^5.15.2", - "sequelize-cli": "^5.5.0", - "underscore": "^1.9.1" - }, - "devDependencies": { - "@babel/cli": "^7.5.5", - "@babel/core": "^7.5.5", - "@babel/node": "^7.5.5", - "@babel/plugin-transform-runtime": "^7.5.5", - "@babel/preset-env": "^7.5.5", - "@babel/register": "^7.5.5", - "babel-eslint": "^10.0.3", - "babel-register": "^6.26.0", - "cross-env": "^5.2.0", - "eslint": "^6.1.0", - "eslint-config-airbnb": "^18.0.1", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.14.3", - "eslint-plugin-react-hooks": "^1.7.0", - "mocha": "^6.2.0", - "mocha-lcov-reporter": "^1.3.0", - "nodemon": "^1.19.1" - } + "name": "express-authorshaven", + "version": "1.0.0", + "description": "A Social platform for the creative at heart", + "main": "index.js", + "scripts": { + "build": "babel -d ./build ./src -s", + "prod": "set NODE_ENV=production&& node build/index.js", + "start": "set NODE_ENV=development&& babel-node src/index.js", + "dev": "set DEBUG=web-app && set NODE_ENV=development&& nodemon src/index.js --exec babel-node", + "test": "set NODE_ENV=test&& sequelize db:migrate:undo:all && sequelize db:migrate && mocha --timeout 0 ./src/tests/*.js --require @babel/register --reporter spec --exec babel-node --exit", + "coverage": "nyc report --reporter=text-lcov | coveralls", + "coveralls": "nyc --reporter=lcov --reporter=text-lcov npm test", + "create:db": "set NODE_ENV=development&& sequelize db:create", + "drop:db": "set NODE_ENV=development&& sequelize db:drop", + "undo:db": "sequelize db:migrate:undo:all", + "create:tables": "set NODE_ENV=development&& sequelize db:migrate && sequelize db:seed:all" + }, + "author": "Andela Simulations Programme", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "bcrypt": "^3.0.6", + "chai": "^4.2.0", + "chai-http": "^4.3.0", + "core-js": "^3.2.1", + "cors": "^2.8.4", + "coveralls": "^3.0.3", + "debug": "^4.1.1", + "dotenv": "^6.2.0", + "ejs": "^2.6.1", + "errorhandler": "^1.5.0", + "express": "^4.17.1", + "express-jwt": "^5.3.1", + "express-session": "^1.15.6", + "jsonwebtoken": "^8.3.0", + "method-override": "^2.3.10", + "methods": "^1.1.2", + "morgan": "^1.9.1", + "passport": "^0.4.0", + "passport-local": "^1.0.0", + "path": "^0.12.7", + "pg": "^7.12.1", + "pg-hstore": "^2.3.3", + "regenerator-runtime": "^0.13.3", + "request": "^2.87.0", + "sequelize": "^5.15.2", + "sequelize-cli": "^5.5.0", + "underscore": "^1.9.1" + }, + "devDependencies": { + "@babel/cli": "^7.5.5", + "@babel/core": "^7.5.5", + "@babel/node": "^7.5.5", + "@babel/plugin-transform-runtime": "^7.5.5", + "@babel/preset-env": "^7.5.5", + "@babel/register": "^7.5.5", + "babel-register": "^6.26.0", + "cross-env": "^5.2.0", + "eslint": "^6.1.0", + "eslint-config-airbnb": "^18.0.1", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-react": "^7.14.3", + "eslint-plugin-react-hooks": "^1.7.0", + "mocha": "^6.2.0", + "nodemon": "^1.19.1" + } } From 5d295749d47f2d6a914b599b1d261fa5c51bc904 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Wed, 4 Sep 2019 04:10:19 +0100 Subject: [PATCH 02/23] feature(notify-request): notify manager of travel request - Create a table - Install dependencies and [Start #167730641] --- .env.sample | 2 + package-lock.json | 16706 ++++++++-------- package.json | 14 +- .../20190904023213-create-notifications.js | 29 + src/database/models/notifications.js | 13 + .../seeders/20190904024301-notifications.js | 23 + 6 files changed, 8562 insertions(+), 8225 deletions(-) create mode 100644 src/database/migrations/20190904023213-create-notifications.js create mode 100644 src/database/models/notifications.js create mode 100644 src/database/seeders/20190904024301-notifications.js diff --git a/.env.sample b/.env.sample index aa63113..de391d5 100644 --- a/.env.sample +++ b/.env.sample @@ -13,6 +13,8 @@ FACEBOOK_CLIENT_ID FACEBOOK_CLIENT_SECRET FACEBOOK_CALLBACK_URL +EMAIL_ADD: +EMAIL_PASS: GOOGLE_CONSUMER_KEY GOOGLE_CONSUMER_SECRET diff --git a/package-lock.json b/package-lock.json index 964617e..3a33748 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8419 +1,8681 @@ { - "name": "archangel_barefoot_nomad", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/cli": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.5.5.tgz", - "integrity": "sha512-UHI+7pHv/tk9g6WXQKYz+kmXTI77YtuY3vqC59KIqcoWEjsJJSG6rAxKaLsgj3LDyadsPrCB929gVOKM6Hui0w==", - "dev": true, - "requires": { - "chokidar": "^2.0.4", - "commander": "^2.8.1", - "convert-source-map": "^1.1.0", - "fs-readdir-recursive": "^1.1.0", - "glob": "^7.0.0", - "lodash": "^4.17.13", - "mkdirp": "^0.5.1", - "output-file-sync": "^2.0.0", - "slash": "^2.0.0", - "source-map": "^0.5.0" - } - }, - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", - "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.5.5", - "@babel/helpers": "^7.5.5", - "@babel/parser": "^7.5.5", - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5", - "convert-source-map": "^1.1.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", - "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", - "dev": true, - "requires": { - "@babel/types": "^7.5.5", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", - "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", - "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-call-delegate": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", - "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/traverse": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-define-map": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", - "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/types": "^7.5.5", - "lodash": "^4.17.13" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", - "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", - "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", - "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", - "dev": true, - "requires": { - "@babel/types": "^7.5.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", - "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/template": "^7.4.4", - "@babel/types": "^7.5.5", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", - "dev": true - }, - "@babel/helper-regex": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", - "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", - "dev": true, - "requires": { - "lodash": "^4.17.13" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", - "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-wrap-function": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-replace-supers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", - "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" - } - }, - "@babel/helper-simple-access": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", - "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", - "dev": true, - "requires": { - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-wrap-function": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", - "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/template": "^7.1.0", - "@babel/traverse": "^7.1.0", - "@babel/types": "^7.2.0" - } - }, - "@babel/helpers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", - "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", - "dev": true, - "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/node": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.5.5.tgz", - "integrity": "sha512-xsW6il+yY+lzXMsQuvIJNA7tU8ix/f4G6bDt4DrnCkVpsR6clk9XgEbp7QF+xGNDdoD7M7QYokCH83pm+UjD0w==", - "dev": true, - "requires": { - "@babel/polyfill": "^7.0.0", - "@babel/register": "^7.5.5", - "commander": "^2.8.1", - "lodash": "^4.17.13", - "node-environment-flags": "^1.0.5", - "v8flags": "^3.1.1" - } - }, - "@babel/parser": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", - "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", - "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0", - "@babel/plugin-syntax-async-generators": "^7.2.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", - "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", - "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.2.0" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", - "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", - "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", - "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", - "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", - "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", - "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", - "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", - "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.1.0" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", - "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", - "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", - "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-define-map": "^7.5.5", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5", - "@babel/helper-split-export-declaration": "^7.4.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", - "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", - "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", - "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", - "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", - "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", - "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", - "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", - "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", - "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", - "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", - "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.1.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", - "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.4.4", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", - "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.1.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", - "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", - "dev": true, - "requires": { - "regexp-tree": "^0.1.6" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", - "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", - "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", - "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.4.4", - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", - "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", - "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", - "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz", - "integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "resolve": "^1.8.1", - "semver": "^5.5.1" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", - "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", - "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", - "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", - "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", - "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", - "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" - } - }, - "@babel/polyfill": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", - "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", - "dev": true, - "requires": { - "core-js": "^2.6.5", - "regenerator-runtime": "^0.13.2" - }, - "dependencies": { - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", - "dev": true - } - } - }, - "@babel/preset-env": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", - "integrity": "sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", - "@babel/plugin-proposal-dynamic-import": "^7.5.0", - "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-syntax-async-generators": "^7.2.0", - "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/plugin-syntax-json-strings": "^7.2.0", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", - "@babel/plugin-transform-arrow-functions": "^7.2.0", - "@babel/plugin-transform-async-to-generator": "^7.5.0", - "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.5.5", - "@babel/plugin-transform-classes": "^7.5.5", - "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.5.0", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/plugin-transform-duplicate-keys": "^7.5.0", - "@babel/plugin-transform-exponentiation-operator": "^7.2.0", - "@babel/plugin-transform-for-of": "^7.4.4", - "@babel/plugin-transform-function-name": "^7.4.4", - "@babel/plugin-transform-literals": "^7.2.0", - "@babel/plugin-transform-member-expression-literals": "^7.2.0", - "@babel/plugin-transform-modules-amd": "^7.5.0", - "@babel/plugin-transform-modules-commonjs": "^7.5.0", - "@babel/plugin-transform-modules-systemjs": "^7.5.0", - "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", - "@babel/plugin-transform-new-target": "^7.4.4", - "@babel/plugin-transform-object-super": "^7.5.5", - "@babel/plugin-transform-parameters": "^7.4.4", - "@babel/plugin-transform-property-literals": "^7.2.0", - "@babel/plugin-transform-regenerator": "^7.4.5", - "@babel/plugin-transform-reserved-words": "^7.2.0", - "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", - "@babel/plugin-transform-sticky-regex": "^7.2.0", - "@babel/plugin-transform-template-literals": "^7.4.4", - "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.4.4", - "@babel/types": "^7.5.5", - "browserslist": "^4.6.0", - "core-js-compat": "^3.1.1", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" - } - }, - "@babel/register": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.5.5.tgz", - "integrity": "sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ==", - "dev": true, - "requires": { - "core-js": "^3.0.0", - "find-cache-dir": "^2.0.0", - "lodash": "^4.17.13", - "mkdirp": "^0.5.1", - "pirates": "^4.0.0", - "source-map-support": "^0.5.9" - } - }, - "@babel/runtime": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", - "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/traverse": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", - "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.5.5", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.5.5", - "@babel/types": "^7.5.5", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", - "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@sendgrid/client": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-6.4.0.tgz", - "integrity": "sha512-GcO+hKXMQiwN0xMGfPITArlj4Nab1vZsrsRLmsJlcXGZV1V1zQC6XuAWJv6MGDd0hr/jKaXmCJ1XMYkxIRQHFw==", - "requires": { - "@sendgrid/helpers": "^6.4.0", - "@types/request": "^2.0.3", - "request": "^2.88.0" - } - }, - "@sendgrid/helpers": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-6.4.0.tgz", - "integrity": "sha512-1dDDXauArHyxwTKFFfWvQpsijmwalyLgwoQJ3FRCssFq1RfqYDgFhRg0Xs3v/IXS2jkKWePSWiPORSR4Sysdpw==", - "requires": { - "chalk": "^2.0.1", - "deepmerge": "^2.1.1" - } - }, - "@sendgrid/mail": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-6.4.0.tgz", - "integrity": "sha512-pVzbqbxhZ4FUN6iSIksRLtyXRPurrcee1i0noPDStDCLlHVwUR+TofeeKIFWGpIvbbk5UR6S6iV/U5ie8Kdblw==", - "requires": { - "@sendgrid/client": "^6.4.0", - "@sendgrid/helpers": "^6.4.0" - } - }, - "@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" - }, - "@types/chai": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.1.tgz", - "integrity": "sha512-LDKlQW/V8bQr5p9aoHye9p7x9faxq0GVeWAkn/Zgyyn848LIAzuR1sHQjGmUBFUpINuGWDG2NTM/ofA2aLMIew==" - }, - "@types/cookiejar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.1.tgz", - "integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==" - }, - "@types/node": { - "version": "12.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.4.tgz", - "integrity": "sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ==" - }, - "@types/request": { - "version": "2.48.2", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.2.tgz", - "integrity": "sha512-gP+PSFXAXMrd5PcD7SqHeUjdGshAI8vKQ3+AvpQr3ht9iQea+59LOKvKITcQI+Lg+1EIkDP6AFSBUJPWG8GDyA==", - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "@types/superagent": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-3.8.7.tgz", - "integrity": "sha512-9KhCkyXv268A2nZ1Wvu7rQWM+BmdYUVkycFeNnYrUL5Zwu7o8wPQ3wBfW59dDP+wuoxw0ww8YKgTNv8j/cgscA==", - "requires": { - "@types/cookiejar": "*", - "@types/node": "*" - } - }, - "@types/tough-cookie": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", - "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", - "dev": true - }, - "addressparser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", - "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=" - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", - "dev": true, - "requires": { - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "name": "archangel_barefoot_nomad", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/cli": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.5.5.tgz", + "integrity": "sha512-UHI+7pHv/tk9g6WXQKYz+kmXTI77YtuY3vqC59KIqcoWEjsJJSG6rAxKaLsgj3LDyadsPrCB929gVOKM6Hui0w==", + "dev": true, + "requires": { + "chokidar": "^2.0.4", + "commander": "^2.8.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "lodash": "^4.17.13", + "mkdirp": "^0.5.1", + "output-file-sync": "^2.0.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async.ensureasync": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.ensureasync/-/async.ensureasync-0.5.2.tgz", - "integrity": "sha1-w8fkpOmzHZaHXVa4UEWYRG4eMF0=", - "requires": { - "async.util.ensureasync": "0.5.2" - } - }, - "async.queue": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.queue/-/async.queue-0.5.2.tgz", - "integrity": "sha1-jV2QgS4UgQZrwJBOjMFxKxfDvXw=", - "requires": { - "async.util.queue": "0.5.2" - } - }, - "async.util.arrayeach": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz", - "integrity": "sha1-WMTpgCjVXWm/sFrrOvROClVagpw=" - }, - "async.util.ensureasync": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.ensureasync/-/async.util.ensureasync-0.5.2.tgz", - "integrity": "sha1-EJB/LL0GegYfma5tIuCM7TDbDWg=", - "requires": { - "async.util.restparam": "0.5.2", - "async.util.setimmediate": "0.5.2" - } - }, - "async.util.isarray": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", - "integrity": "sha1-5i2sjyY29lh13PdSHC0k0N+yu98=" - }, - "async.util.map": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.map/-/async.util.map-0.5.2.tgz", - "integrity": "sha1-5YjvhuCzq18CfZevTWg10FXKadY=" - }, - "async.util.noop": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", - "integrity": "sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk=" - }, - "async.util.onlyonce": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", - "integrity": "sha1-uOb8AErckjFk154y8oE+5GXCT/I=" - }, - "async.util.queue": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.queue/-/async.util.queue-0.5.2.tgz", - "integrity": "sha1-V/Zavho83yc9MavSirlUJfgiLuU=", - "requires": { - "async.util.arrayeach": "0.5.2", - "async.util.isarray": "0.5.2", - "async.util.map": "0.5.2", - "async.util.noop": "0.5.2", - "async.util.onlyonce": "0.5.2", - "async.util.setimmediate": "0.5.2" - } - }, - "async.util.restparam": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz", - "integrity": "sha1-A+/r88Ane5ciDlJaunUPXgT8gM0=" - }, - "async.util.setimmediate": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz", - "integrity": "sha1-KBLrq/KlgCd1jUvHeT0cz68QJV8=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "axobject-query": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7" - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "@babel/generator": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", + "dev": true, + "requires": { + "@babel/types": "^7.5.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@babel/helper-call-delegate": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", + "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + "@babel/helper-define-map": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", + "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - } - } - }, - "babel-eslint": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", - "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - } - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", - "dev": true + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - } - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@babel/helper-hoist-variables": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", + "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true + "@babel/helper-member-expression-to-functions": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", + "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", + "dev": true, + "requires": { + "@babel/types": "^7.5.5" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "@babel/helper-module-transforms": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", + "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" + } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } - } - }, - "bottleneck": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-1.16.0.tgz", - "integrity": "sha1-1s4TgIUnr8gLaQkvFWBmVeWyHxo=" - }, - "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "@babel/helper-replace-supers": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", + "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.5.5", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + } }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserslist": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz", - "integrity": "sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000989", - "electron-to-chromium": "^1.3.247", - "node-releases": "^1.1.29" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-writer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-lite": { - "version": "1.0.30000989", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", - "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==", - "dev": true - }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chai-http": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-4.3.0.tgz", - "integrity": "sha512-zFTxlN7HLMv+7+SPXZdkd5wUlK+KxH6Q7bIEMiEx0FK3zuuMqL7cwICAQ0V1+yYRozBburYuxN1qZstgHpFZQg==", - "requires": { - "@types/chai": "4", - "@types/superagent": "^3.8.3", - "cookiejar": "^2.1.1", - "is-ip": "^2.0.0", - "methods": "^1.1.2", - "qs": "^6.5.1", - "superagent": "^3.7.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "cli-color": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.4.0.tgz", - "integrity": "sha512-xu6RvQqqrWEo6MPR1eixqGPywhYBHRs653F9jfXB2Hx4jdM/3WxiNE1vppRmxtMIfl16SFYTpYlrnqH/HsK/2w==", - "requires": { - "ansi-regex": "^2.1.1", - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.14", - "timers-ext": "^0.1.5" - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "@babel/helpers": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", + "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", + "dev": true, + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } + "@babel/node": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.5.5.tgz", + "integrity": "sha512-xsW6il+yY+lzXMsQuvIJNA7tU8ix/f4G6bDt4DrnCkVpsR6clk9XgEbp7QF+xGNDdoD7M7QYokCH83pm+UjD0w==", + "dev": true, + "requires": { + "@babel/polyfill": "^7.0.0", + "@babel/register": "^7.5.5", + "commander": "^2.8.1", + "lodash": "^4.17.13", + "node-environment-flags": "^1.0.5", + "v8flags": "^3.1.1" + } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "cls-bluebird": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", - "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", - "requires": { - "is-bluebird": "^1.0.2", - "shimmer": "^1.1.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", - "dev": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "dependencies": { - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } + "@babel/parser": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "confusing-browser-globals": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz", - "integrity": "sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg==", - "dev": true - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz", - "integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==" - }, - "core-js-compat": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz", - "integrity": "sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==", - "dev": true, - "requires": { - "browserslist": "^4.6.6", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "coveralls": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.6.tgz", - "integrity": "sha512-Pgh4v3gCI4T/9VijVrm8Ym5v0OgjvGLKj3zTUwkvsCiwqae/p6VLzpsFNjQS2i6ewV7ef+DjFJ5TSKxYt/mCrA==", - "requires": { - "growl": "~> 1.10.0", - "js-yaml": "^3.13.1", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.86.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, - "cross-env": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz", - "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.5" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-random-string": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-3.0.1.tgz", - "integrity": "sha512-dUL0cJ4PBLanJGJQBHQUkvZ3C4q13MXzl54oRqAIiJGiNkOZ4JDwkg/SBo7daGghzlJv16yW1p/4lIQukmbedA==", - "requires": { - "type-fest": "^0.5.2" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "damerau-levenshtein": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", - "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deepmerge": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", - "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "@babel/plugin-proposal-dynamic-import": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", + "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0" + } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" + } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "dotenv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", - "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" - }, - "dottie": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz", - "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "requires": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "ejs": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.1.tgz", - "integrity": "sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==" - }, - "electron-to-chromium": { - "version": "1.3.252", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.252.tgz", - "integrity": "sha512-NWJ5TztDnjExFISZHFwpoJjMbLUifsNBnx7u2JI0gCw6SbKyQYYWWtBHasO/jPtHym69F4EZuTpRNGN11MT/jg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "errorhandler": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", - "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", - "requires": { - "accepts": "~1.3.7", - "escape-html": "~1.0.3" - } - }, - "es-abstract": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.1.tgz", - "integrity": "sha512-cp/Tb1oA/rh2X7vqeSOvM+TSo3UkJLX70eNihgVEvnzwAgikjkTFr/QVgRCaxjm0knCNQzNoxxxcw2zO2LJdZA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.0.0", - "string.prototype.trimright": "^2.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.51", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.51.tgz", - "integrity": "sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "^1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.2.tgz", - "integrity": "sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==", - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.51" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.2", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", + "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", + "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - } - } - }, - "eslint-config-airbnb": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.0.1.tgz", - "integrity": "sha512-hLb/ccvW4grVhvd6CT83bECacc+s4Z3/AEyWQdIT2KeTsG9dR7nx1gs7Iw4tDmGKozCNHFn4yZmRm3Tgy+XxyQ==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^14.0.0", - "object.assign": "^4.1.0", - "object.entries": "^1.1.0" - } - }, - "eslint-config-airbnb-base": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", - "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.7", - "object.assign": "^4.1.0", - "object.entries": "^1.1.0" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", - "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } + "@babel/plugin-transform-async-to-generator": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", + "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "@babel/plugin-transform-block-scoping": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", + "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.13" + } }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.18.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", - "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.11.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@babel/plugin-transform-classes": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", + "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.5.5", + "@babel/helper-split-export-declaration": "^7.4.4", + "globals": "^11.1.0" + } }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", - "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.5", - "aria-query": "^3.0.0", - "array-includes": "^3.0.3", - "ast-types-flow": "^0.0.7", - "axobject-query": "^2.0.2", - "damerau-levenshtein": "^1.0.4", - "emoji-regex": "^7.0.2", - "has": "^1.0.3", - "jsx-ast-utils": "^2.2.1" - } - }, - "eslint-plugin-react": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", - "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.1.0", - "object.entries": "^1.1.0", - "object.fromentries": "^2.0.0", - "object.values": "^1.1.0", - "prop-types": "^15.7.2", - "resolve": "^1.10.1" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } - } - }, - "eslint-plugin-react-hooks": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", - "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==", - "dev": true - }, - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.0.0" - } - }, - "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true - }, - "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", - "dev": true, - "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", - "eslint-visitor-keys": "^1.1.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@babel/plugin-transform-destructuring": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", + "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } + "@babel/plugin-transform-dotall-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", + "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "@babel/plugin-transform-duplicate-keys": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", + "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "@babel/plugin-transform-for-of": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } - } - }, - "express-jwt": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.1.tgz", - "integrity": "sha512-1C9RNq0wMp/JvsH/qZMlg3SIPvKu14YkZ4YYv7gJQ1Vq+Dv8LH9tLKenS5vMNth45gTlEUGx+ycp9IHIlaHP/g==", - "requires": { - "async": "^1.5.0", - "express-unless": "^0.3.0", - "jsonwebtoken": "^8.1.0", - "lodash.set": "^4.0.0" - } - }, - "express-session": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.2.tgz", - "integrity": "sha512-oy0sRsdw6n93E9wpCNWKRnSsxYnSDX9Dnr9mhZgqUEEorzcq5nshGYSZ4ZReHFhKQ80WI5iVUUSPW7u3GaKauw==", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.1.2", - "uid-safe": "~2.1.5" - }, - "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "@babel/plugin-transform-function-name": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", + "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "@babel/plugin-transform-member-expression-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", + "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "express-unless": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", - "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" - }, - "express-validator": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.2.0.tgz", - "integrity": "sha512-892cPistoSPzMuoG2p1W+2ZxBi0bAvPaaYgXK1E1C8/QncLo2d1HbiDDWkXUtTthjGEzEmwiELLJHu1Ez2hOEg==", - "requires": { - "lodash": "^4.17.15", - "validator": "^11.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } + "@babel/plugin-transform-modules-amd": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", + "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "@babel/plugin-transform-modules-commonjs": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", + "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "@babel/plugin-transform-modules-systemjs": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", + "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", + "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", + "dev": true, + "requires": { + "regexp-tree": "^0.1.6" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", - "dev": true - } - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "formidable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", - "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-new-target": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", + "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-object-super": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", + "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.5.5" + } }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-parameters": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.4.4", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } + "@babel/plugin-transform-property-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", + "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-regenerator": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", + "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.0" + } }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "@babel/plugin-transform-reserved-words": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", + "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz", + "integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-template-literals": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true + "@babel/polyfill": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", + "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "dev": true + } + } }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true + "@babel/preset-env": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", + "integrity": "sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-dynamic-import": "^7.5.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.5.0", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.5.5", + "@babel/plugin-transform-classes": "^7.5.5", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/plugin-transform-duplicate-keys": "^7.5.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.4.4", + "@babel/plugin-transform-function-name": "^7.4.4", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-member-expression-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.5.0", + "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "@babel/plugin-transform-modules-systemjs": "^7.5.0", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", + "@babel/plugin-transform-new-target": "^7.4.4", + "@babel/plugin-transform-object-super": "^7.5.5", + "@babel/plugin-transform-parameters": "^7.4.4", + "@babel/plugin-transform-property-literals": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.4.5", + "@babel/plugin-transform-reserved-words": "^7.2.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.4.4", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.4.4", + "@babel/types": "^7.5.5", + "browserslist": "^4.6.0", + "core-js-compat": "^3.1.1", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.5.0" + } }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } + "@babel/register": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.5.5.tgz", + "integrity": "sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ==", + "dev": true, + "requires": { + "core-js": "^3.0.0", + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.13", + "mkdirp": "^0.5.1", + "pirates": "^4.0.0", + "source-map-support": "^0.5.9" + } }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true + "@babel/runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + } }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } + "@babel/traverse": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } + "@types/chai": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.1.tgz", + "integrity": "sha512-LDKlQW/V8bQr5p9aoHye9p7x9faxq0GVeWAkn/Zgyyn848LIAzuR1sHQjGmUBFUpINuGWDG2NTM/ofA2aLMIew==" + }, + "@types/cookiejar": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.1.tgz", + "integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==" + }, + "@types/node": { + "version": "12.7.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.4.tgz", + "integrity": "sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ==" + }, + "@types/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-f8JzJNWVhKtc9dg/dyDNfliTKNOJSLa7Oht/ElZdF/UbMUmAH3rLmAk3ODNjw0mZajDEgatA03tRjB4+Dp/tzA==" + }, + "@types/react": { + "version": "16.9.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.2.tgz", + "integrity": "sha512-jYP2LWwlh+FTqGd9v7ynUKZzjj98T8x7Yclz479QdRhHfuW9yQ+0jjnD31eXSXutmBpppj5PYNLYLRfnZJvcfg==", + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } + "@types/superagent": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-3.8.7.tgz", + "integrity": "sha512-9KhCkyXv268A2nZ1Wvu7rQWM+BmdYUVkycFeNnYrUL5Zwu7o8wPQ3wBfW59dDP+wuoxw0ww8YKgTNv8j/cgscA==", + "requires": { + "@types/cookiejar": "*", + "@types/node": "*" + } }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "auto-bind": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-2.1.0.tgz", + "integrity": "sha512-qZuFvkes1eh9lB2mg8/HG18C+5GIO51r+RrCSst/lh+i5B1CtVlkhTE488M805Nr3dKl0sM/pIFKSKUIlg3zUg==", + "requires": { + "@types/react": "^16.8.12" + } }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7" + } }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + } + } }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + } + } }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + } + } }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true + "bcrypt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-3.0.6.tgz", + "integrity": "sha512-taA5bCTfXe7FUjKroKky9EXpdhkVvhE5owfxfLYodbrAR1Ul3juLmIQmIQBK4L9a5BuUcE6cqmwT+Da20lF9tg==", + "requires": { + "nan": "2.13.2", + "node-pre-gyp": "0.12.0" + } }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserslist": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz", + "integrity": "sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000989", + "electron-to-chromium": "^1.3.247", + "node-releases": "^1.1.29" + } }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", - "dev": true, - "requires": { - "ini": "^1.3.4" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "dev": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", - "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "import-fresh": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", - "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflection": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", - "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "caniuse-lite": { + "version": "1.0.30000989", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", + "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==", + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "chai-http": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-4.3.0.tgz", + "integrity": "sha512-zFTxlN7HLMv+7+SPXZdkd5wUlK+KxH6Q7bIEMiEx0FK3zuuMqL7cwICAQ0V1+yYRozBburYuxN1qZstgHpFZQg==", + "requires": { + "@types/chai": "4", + "@types/superagent": "^3.8.3", + "cookiejar": "^2.1.1", + "is-ip": "^2.0.0", + "methods": "^1.1.2", + "qs": "^6.5.1", + "superagent": "^3.7.0" + } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } - } - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" - }, - "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-bluebird": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", - "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, - "requires": { - "ci-info": "^1.5.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", - "dev": true, - "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - } - }, - "is-ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz", - "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=", - "requires": { - "ip-regex": "^2.0.0" - } - }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-beautify": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.10.2.tgz", - "integrity": "sha512-ZtBYyNUYJIsBWERnQP0rPN9KjkrDfJcMjuVGcvXOUJrD1zmOGwhRwQ4msG+HJ+Ni/FA7+sRQEMYVzdTQDvnzvQ==", - "requires": { - "config-chain": "^1.1.12", - "editorconfig": "^0.15.3", - "glob": "^7.1.3", - "mkdirp": "~0.5.1", - "nopt": "~4.0.1" - } - }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jsx-ast-utils": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", - "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "object.assign": "^4.1.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", - "dev": true, - "requires": { - "package-json": "^4.0.0" - } - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=" - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "lodash.chunk": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", - "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - }, - "dependencies": { - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", - "requires": { - "es5-ext": "~0.10.2" - } - }, - "mailparser": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.6.2.tgz", - "integrity": "sha1-A8SGA5vfTfbNO2rcqqxBB9/bwGg=", - "requires": { - "encoding": "^0.1.12", - "mime": "^1.3.4", - "mimelib": "^0.3.0", - "uue": "^3.1.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - } - } - }, - "memoizee": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", - "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", - "requires": { - "d": "1", - "es5-ext": "^0.10.45", - "es6-weak-map": "^2.0.2", - "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.5" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "method-override": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.10.tgz", - "integrity": "sha1-49r41d7hDdLc59SuiNYrvud0drQ=", - "requires": { - "debug": "2.6.9", - "methods": "~1.1.2", - "parseurl": "~1.3.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "mimelib": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz", - "integrity": "sha1-eHrdJBXYJ6yzr27EvKHqlZZBiFM=", - "requires": { - "addressparser": "~1.0.1", - "encoding": "~0.1.12" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz", - "integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.2.2", - "yargs-parser": "13.0.0", - "yargs-unparser": "1.5.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "chownr": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, + "cli-color": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.4.0.tgz", + "integrity": "sha512-xu6RvQqqrWEo6MPR1eixqGPywhYBHRs653F9jfXB2Hx4jdM/3WxiNE1vppRmxtMIfl16SFYTpYlrnqH/HsK/2w==", + "requires": { + "ansi-regex": "^2.1.1", + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.14", + "timers-ext": "^0.1.5" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - } - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "cls-bluebird": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", + "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", + "requires": { + "is-bluebird": "^1.0.2", + "shimmer": "^1.1.0" + } }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } } - } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } + "confusing-browser-globals": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz", + "integrity": "sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg==", + "dev": true }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" } - } }, - "yargs": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", - "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.0.0" - } + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true }, - "yargs-parser": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", - "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "mocha-lcov-reporter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mocha-lcov-reporter/-/mocha-lcov-reporter-1.3.0.tgz", - "integrity": "sha1-Rpve9PivyaEWBW8HnfYYLQr7A4Q=", - "dev": true - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "moment-timezone": { - "version": "0.5.26", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz", - "integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==", - "requires": { - "moment": ">= 2.9.0" - } - }, - "morgan": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", - "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", - "requires": { - "basic-auth": "~2.0.0", - "debug": "2.6.9", - "depd": "~1.1.2", - "on-finished": "~2.3.0", - "on-headers": "~1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "core-js": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz", + "integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==" + }, + "core-js-compat": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz", + "integrity": "sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==", + "dev": true, + "requires": { + "browserslist": "^4.6.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "node-releases": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.29.tgz", - "integrity": "sha512-R5bDhzh6I+tpi/9i2hrrvGJ3yKPYzlVOORDkXhnZuwi5D3q1I5w4vYy24PJXTcLk9Q0kws9TO77T75bcK8/ysQ==", - "dev": true, - "requires": { - "semver": "^5.3.0" - } - }, - "nodemailer": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.3.0.tgz", - "integrity": "sha512-TEHBNBPHv7Ie/0o3HXnb7xrPSSQmH1dXwQKRaMKDBGt/ZN54lvDVujP6hKkO/vjkIYL9rK8kHSG11+G42Nhxuw==" - }, - "nodemon": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", - "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", - "dev": true, - "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^2.5.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", - "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.entries": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", - "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "object.fromentries": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", - "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.11.0", - "function-bind": "^1.1.1", - "has": "^1.0.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", - "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "output-file-sync": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz", - "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "is-plain-obj": "^1.1.0", - "mkdirp": "^0.5.1" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", - "dev": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - } - }, - "packet-reader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "passport": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", - "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", - "requires": { - "passport-strategy": "1.x.x", - "pause": "0.0.1" - } - }, - "passport-facebook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-3.0.0.tgz", - "integrity": "sha512-K/qNzuFsFISYAyC1Nma4qgY/12V3RSLFdFVsPKXiKZt434wOvthFW1p7zKa1iQihQMRhaWorVE1o3Vi1o+ZgeQ==", - "requires": { - "passport-oauth2": "1.x.x" - } - }, - "passport-google-oauth20": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", - "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==", - "requires": { - "passport-oauth2": "1.x.x" - } - }, - "passport-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", - "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", - "requires": { - "passport-strategy": "1.x.x" - } - }, - "passport-oauth2": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", - "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", - "requires": { - "base64url": "3.x.x", - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "uid2": "0.0.x", - "utils-merge": "1.x.x" - } - }, - "passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" - }, - "path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", - "requires": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" - }, - "pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pg": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/pg/-/pg-7.12.1.tgz", - "integrity": "sha512-l1UuyfEvoswYfcUe6k+JaxiN+5vkOgYcVSbSuw3FvdLqDbaoa2RJo1zfJKfPsSYPFVERd4GHvX3s2PjG1asSDA==", - "requires": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "0.1.3", - "pg-pool": "^2.0.4", - "pg-types": "^2.1.0", - "pgpass": "1.x", - "semver": "4.3.2" - }, - "dependencies": { - "semver": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", - "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" - } - } - }, - "pg-connection-string": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", - "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" - }, - "pg-hstore": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.3.tgz", - "integrity": "sha512-qpeTpdkguFgfdoidtfeTho1Q1zPVPbtMHgs8eQ+Aan05iLmIs3Z3oo5DOZRclPGoQ4i68I1kCtQSJSa7i0ZVYg==", - "requires": { - "underscore": "^1.7.0" - } - }, - "pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" - }, - "pg-pool": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.7.tgz", - "integrity": "sha512-UiJyO5B9zZpu32GSlP0tXy8J2NsJ9EFGFfz5v6PSbdz/1hBLX1rNiiy5+mAm5iJJYwfCv4A0EBcQLGWwjbpzZw==" - }, - "pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "requires": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - } - }, - "pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", - "requires": { - "split": "^1.0.0" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" - }, - "postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" - }, - "postgres-date": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz", - "integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA==" - }, - "postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "requires": { - "xtend": "^4.0.0" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" - }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.1.tgz", - "integrity": "sha512-2KLd5fKOdAfShtY2d/8XDWVRnmp3zp40Qt6ge2zBPFARLXOGUf2fHD5eg+TV/5oxBtQKVhjUaKFsAaE4HnwfSA==" - }, - "pstree.remy": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", - "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz", - "integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w==" - }, - "random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "react-is": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", - "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } + "coveralls": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.6.tgz", + "integrity": "sha512-Pgh4v3gCI4T/9VijVrm8Ym5v0OgjvGLKj3zTUwkvsCiwqae/p6VLzpsFNjQS2i6ewV7ef+DjFJ5TSKxYt/mCrA==", + "requires": { + "growl": "~> 1.10.0", + "js-yaml": "^3.13.1", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.86.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } + "cross-env": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz", + "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.5" + } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" - }, - "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", - "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", - "dev": true, - "requires": { - "private": "^0.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp-tree": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.13.tgz", - "integrity": "sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==", - "dev": true - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "regexpu-core": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.5.tgz", - "integrity": "sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, - "registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", - "dev": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { - "rc": "^1.0.1" - } - }, - "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", - "dev": true - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } + "csstype": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz", + "integrity": "sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==" + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retry-as-promised": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", - "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", - "requires": { - "any-promise": "^1.3.0" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true, - "requires": { - "semver": "^5.0.3" - } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } + "damerau-levenshtein": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", + "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "sendgrid": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/sendgrid/-/sendgrid-5.2.3.tgz", - "integrity": "sha512-FD7oR9TbJFUew1p0Vw9JX0wBetDyq634LzylSXz4n9+hwaf+6a9dNloZl8CcjpsX4NuEc3HJanTN4GjDwNyi4A==", - "requires": { - "async.ensureasync": "^0.5.2", - "async.queue": "^0.5.2", - "bottleneck": "^1.12.0", - "debug": "^2.2.0", - "lodash.chunk": "^4.2.0", - "mailparser": "^0.6.1", - "sendgrid-rest": "^2.3.0" - }, - "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "sendgrid-rest": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/sendgrid-rest/-/sendgrid-rest-2.4.0.tgz", - "integrity": "sha512-3VRHhTnln17jPQNzBjEHO6u2Y7kLlhVnOvX0aGjr7yRVZpq5LXo0ilAFMsaHUfKVH+jFdCrHMAVLOAdtu6wLJA==" - }, - "sequelize": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.18.1.tgz", - "integrity": "sha512-jngo7pqilyOycMv6ZEwHLVn2wuHi/xkSQZfwK4jhjG8ta1HWYJK3XyQDFdhVEOH1GEq9pnqaf+7Kwqm+eqXD9Q==", - "requires": { - "bluebird": "^3.5.0", - "cls-bluebird": "^2.1.0", - "debug": "^4.1.1", - "dottie": "^2.0.0", - "inflection": "1.12.0", - "lodash": "^4.17.11", - "moment": "^2.24.0", - "moment-timezone": "^0.5.21", - "retry-as-promised": "^3.1.0", - "semver": "^6.1.1", - "sequelize-pool": "^2.3.0", - "toposort-class": "^1.0.1", - "uuid": "^3.2.1", - "validator": "^10.11.0", - "wkx": "^0.4.6" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "^4.0.0" + } }, - "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" - } - } - }, - "sequelize-cli": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-5.5.1.tgz", - "integrity": "sha512-ZM4kUZvY3y14y+Rq3cYxGH7YDJz11jWHcN2p2x7rhAIemouu4CEXr5ebw30lzTBtyXV4j2kTO+nUjZOqzG7k+Q==", - "requires": { - "bluebird": "^3.5.3", - "cli-color": "^1.4.0", - "fs-extra": "^7.0.1", - "js-beautify": "^1.8.8", - "lodash": "^4.17.5", - "resolve": "^1.5.0", - "umzug": "^2.1.0", - "yargs": "^13.1.0" - } - }, - "sequelize-pool": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-2.3.0.tgz", - "integrity": "sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA==" - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } }, "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "requires": { - "through": "2" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.trimleft": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz", - "integrity": "sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.0.2" - } - }, - "string.prototype.trimright": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz", - "integrity": "sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "superagent": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", - "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", - "requires": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.2.0", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "dev": true, - "requires": { - "execa": "^0.7.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } + "dotenv": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", + "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" + }, + "dottie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz", + "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "toposort-class": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", - "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" - }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "requires": { - "nopt": "~1.0.10" - }, - "dependencies": { - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1" - } - } - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/type/-/type-1.0.3.tgz", - "integrity": "sha512-51IMtNfVcee8+9GJvj0spSuFcZHe9vSib6Xtgsny1Km9ugyz2mbS08I3rsUIRYgJohFRFU1160sgRodYz378Hg==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "type-fest": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", - "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "requires": { - "random-bytes": "~1.0.0" - } - }, - "uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" - }, - "umzug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.2.0.tgz", - "integrity": "sha512-xZLW76ax70pND9bx3wqwb8zqkFGzZIK8dIHD9WdNy/CrNfjWcwQgQkGCuUqcuwEBvUm+g07z+qWvY+pxDmMEEw==", - "requires": { - "babel-runtime": "^6.23.0", - "bluebird": "^3.5.3" - } - }, - "undefsafe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", - "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", - "dev": true, - "requires": { - "debug": "^2.2.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "dev": true, - "requires": { - "crypto-random-string": "^1.0.0" - }, - "dependencies": { - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - } - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.1.tgz", + "integrity": "sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==" + }, + "electron-to-chromium": { + "version": "1.3.252", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.252.tgz", + "integrity": "sha512-NWJ5TztDnjExFISZHFwpoJjMbLUifsNBnx7u2JI0gCw6SbKyQYYWWtBHasO/jPtHym69F4EZuTpRNGN11MT/jg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", + "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~6.1.0" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-client": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", + "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "errorhandler": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", + "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", + "requires": { + "accepts": "~1.3.7", + "escape-html": "~1.0.3" + } + }, + "es-abstract": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.1.tgz", + "integrity": "sha512-cp/Tb1oA/rh2X7vqeSOvM+TSo3UkJLX70eNihgVEvnzwAgikjkTFr/QVgRCaxjm0knCNQzNoxxxcw2zO2LJdZA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.51", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.51.tgz", + "integrity": "sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "^1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.2.tgz", + "integrity": "sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.51" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", + "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "eslint-config-airbnb": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.0.1.tgz", + "integrity": "sha512-hLb/ccvW4grVhvd6CT83bECacc+s4Z3/AEyWQdIT2KeTsG9dR7nx1gs7Iw4tDmGKozCNHFn4yZmRm3Tgy+XxyQ==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^14.0.0", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, + "eslint-config-airbnb-base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", + "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.7", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.1" + } + }, + "eslint-plugin-react": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", + "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.1.0", + "object.entries": "^1.1.0", + "object.fromentries": "^2.0.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "resolve": "^1.10.1" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", + "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==", + "dev": true + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } + }, + "express-jwt": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.1.tgz", + "integrity": "sha512-1C9RNq0wMp/JvsH/qZMlg3SIPvKu14YkZ4YYv7gJQ1Vq+Dv8LH9tLKenS5vMNth45gTlEUGx+ycp9IHIlaHP/g==", + "requires": { + "async": "^1.5.0", + "express-unless": "^0.3.0", + "jsonwebtoken": "^8.1.0", + "lodash.set": "^4.0.0" + } + }, + "express-session": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.2.tgz", + "integrity": "sha512-oy0sRsdw6n93E9wpCNWKRnSsxYnSDX9Dnr9mhZgqUEEorzcq5nshGYSZ4ZReHFhKQ80WI5iVUUSPW7u3GaKauw==", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.1.2", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "express-unless": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", + "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" + }, + "express-validator": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.2.0.tgz", + "integrity": "sha512-892cPistoSPzMuoG2p1W+2ZxBi0bAvPaaYgXK1E1C8/QncLo2d1HbiDDWkXUtTthjGEzEmwiELLJHu1Ez2hOEg==", + "requires": { + "lodash": "^4.17.15", + "validator": "^11.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "dev": true + } + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", + "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", + "requires": { + "minipass": "^2.2.1" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "ignore-walk": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.2.tgz", + "integrity": "sha512-EXyErtpHbn75ZTsOADsfx6J/FPo6/5cjev46PXrcTpd8z3BoRkXgYu9/JVqrI7tusjmwCZutGeRJeU0Wo1e4Cw==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflection": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", + "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", - "dev": true, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uue": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.2.tgz", - "integrity": "sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==", - "requires": { - "escape-string-regexp": "~1.0.5", - "extend": "~3.0.0" - } - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" - }, - "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", - "dev": true - }, - "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validator": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-11.1.0.tgz", - "integrity": "sha512-qiQ5ktdO7CD6C/5/mYV4jku/7qnqzjrxb3C/Q5wR3vGGinHTgJZN/TdFT3ZX4vXhX2R1PXx42fB1cn5W+uJ4lg==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", - "dev": true, - "requires": { - "string-width": "^2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-bluebird": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", + "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz", + "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=", + "requires": { + "ip-regex": "^2.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "js-beautify": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.10.2.tgz", + "integrity": "sha512-ZtBYyNUYJIsBWERnQP0rPN9KjkrDfJcMjuVGcvXOUJrD1zmOGwhRwQ4msG+HJ+Ni/FA7+sRQEMYVzdTQDvnzvQ==", + "requires": { + "config-chain": "^1.1.12", + "editorconfig": "^0.15.3", + "glob": "^7.1.3", + "mkdirp": "~0.5.1", + "nopt": "~4.0.1" + } + }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", + "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "lodash.set": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", + "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + }, + "dependencies": { + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + } + } + }, + "memoizee": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", + "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "requires": { + "d": "1", + "es5-ext": "^0.10.45", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.5" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "method-override": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.10.tgz", + "integrity": "sha1-49r41d7hDdLc59SuiNYrvud0drQ=", + "requires": { + "debug": "2.6.9", + "methods": "~1.1.2", + "parseurl": "~1.3.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "minipass": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.5.1.tgz", + "integrity": "sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "requires": { + "minipass": "^2.2.1" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz", + "integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.2.2", + "yargs-parser": "13.0.0", + "yargs-unparser": "1.5.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + } + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "yargs": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + } + }, + "yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "mocha-lcov-reporter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mocha-lcov-reporter/-/mocha-lcov-reporter-1.3.0.tgz", + "integrity": "sha1-Rpve9PivyaEWBW8HnfYYLQr7A4Q=", + "dev": true + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "moment-timezone": { + "version": "0.5.26", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz", + "integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-pre-gyp": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", + "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "node-releases": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.29.tgz", + "integrity": "sha512-R5bDhzh6I+tpi/9i2hrrvGJ3yKPYzlVOORDkXhnZuwi5D3q1I5w4vYy24PJXTcLk9Q0kws9TO77T75bcK8/ysQ==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "nodemon": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", + "integrity": "sha512-hRLYaw5Ihyw9zK7NF+9EUzVyS6Cvgc14yh8CAYr38tPxJa6UrOxwAQ351GwrgoanHCF0FalQFn6w5eoX/LGdJw==", + "dev": true, + "requires": { + "chokidar": "^2.1.5", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.6", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-bundled": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" + }, + "npm-packlist": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz", + "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "output-file-sync": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz", + "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "is-plain-obj": "^1.1.0", + "mkdirp": "^0.5.1" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "passport": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", + "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-facebook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-3.0.0.tgz", + "integrity": "sha512-K/qNzuFsFISYAyC1Nma4qgY/12V3RSLFdFVsPKXiKZt434wOvthFW1p7zKa1iQihQMRhaWorVE1o3Vi1o+ZgeQ==", + "requires": { + "passport-oauth2": "1.x.x" + } + }, + "passport-google-oauth20": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz", + "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==", + "requires": { + "passport-oauth2": "1.x.x" + } + }, + "passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.x.x" + } + }, + "passport-oauth2": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", + "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", + "requires": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" + }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pg": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.12.1.tgz", + "integrity": "sha512-l1UuyfEvoswYfcUe6k+JaxiN+5vkOgYcVSbSuw3FvdLqDbaoa2RJo1zfJKfPsSYPFVERd4GHvX3s2PjG1asSDA==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "0.1.3", + "pg-pool": "^2.0.4", + "pg-types": "^2.1.0", + "pgpass": "1.x", + "semver": "4.3.2" + }, + "dependencies": { + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + } + } + }, + "pg-connection-string": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", + "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + }, + "pg-hstore": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.3.tgz", + "integrity": "sha512-qpeTpdkguFgfdoidtfeTho1Q1zPVPbtMHgs8eQ+Aan05iLmIs3Z3oo5DOZRclPGoQ4i68I1kCtQSJSa7i0ZVYg==", + "requires": { + "underscore": "^1.7.0" + } + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.7.tgz", + "integrity": "sha512-UiJyO5B9zZpu32GSlP0tXy8J2NsJ9EFGFfz5v6PSbdz/1hBLX1rNiiy5+mAm5iJJYwfCv4A0EBcQLGWwjbpzZw==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz", + "integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.1.tgz", + "integrity": "sha512-2KLd5fKOdAfShtY2d/8XDWVRnmp3zp40Qt6ge2zBPFARLXOGUf2fHD5eg+TV/5oxBtQKVhjUaKFsAaE4HnwfSA==" + }, + "pstree.remy": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", + "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "qs": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz", + "integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w==" + }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wkx": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.8.tgz", - "integrity": "sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ==", - "requires": { - "@types/node": "*" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "react-is": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", + "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + }, + "regenerator-transform": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "dev": true, + "requires": { + "private": "^0.1.6" + } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", - "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.11", - "yargs": "^12.0.5" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } + "regexp-tree": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.13.tgz", + "integrity": "sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "regexpu-core": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.5.tgz", + "integrity": "sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "requires": { + "path-parse": "^1.0.6" + } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry-as-promised": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", + "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", + "requires": { + "any-promise": "^1.3.0" + } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "sequelize": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.18.1.tgz", + "integrity": "sha512-jngo7pqilyOycMv6ZEwHLVn2wuHi/xkSQZfwK4jhjG8ta1HWYJK3XyQDFdhVEOH1GEq9pnqaf+7Kwqm+eqXD9Q==", + "requires": { + "bluebird": "^3.5.0", + "cls-bluebird": "^2.1.0", + "debug": "^4.1.1", + "dottie": "^2.0.0", + "inflection": "1.12.0", + "lodash": "^4.17.11", + "moment": "^2.24.0", + "moment-timezone": "^0.5.21", + "retry-as-promised": "^3.1.0", + "semver": "^6.1.1", + "sequelize-pool": "^2.3.0", + "toposort-class": "^1.0.1", + "uuid": "^3.2.1", + "validator": "^10.11.0", + "wkx": "^0.4.6" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + } + } + }, + "sequelize-cli": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-5.5.1.tgz", + "integrity": "sha512-ZM4kUZvY3y14y+Rq3cYxGH7YDJz11jWHcN2p2x7rhAIemouu4CEXr5ebw30lzTBtyXV4j2kTO+nUjZOqzG7k+Q==", + "requires": { + "bluebird": "^3.5.3", + "cli-color": "^1.4.0", + "fs-extra": "^7.0.1", + "js-beautify": "^1.8.8", + "lodash": "^4.17.5", + "resolve": "^1.5.0", + "umzug": "^2.1.0", + "yargs": "^13.1.0" + } + }, + "sequelize-pool": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-2.3.0.tgz", + "integrity": "sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA==" + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socket.io": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", + "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.3.1", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.2.0", + "socket.io-parser": "~3.3.0" + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { + } + }, + "string.prototype.trimleft": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz", + "integrity": "sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.0.2" + } + }, + "string.prototype.trimright": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz", + "integrity": "sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { "ansi-regex": "^2.0.0" - } } - } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "tar": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.5", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/type/-/type-1.0.3.tgz", + "integrity": "sha512-51IMtNfVcee8+9GJvj0spSuFcZHe9vSib6Xtgsny1Km9ugyz2mbS08I3rsUIRYgJohFRFU1160sgRodYz378Hg==" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" + }, + "umzug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.2.0.tgz", + "integrity": "sha512-xZLW76ax70pND9bx3wqwb8zqkFGzZIK8dIHD9WdNy/CrNfjWcwQgQkGCuUqcuwEBvUm+g07z+qWvY+pxDmMEEw==", + "requires": { + "babel-runtime": "^6.23.0", + "bluebird": "^3.5.3" + } + }, + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "dev": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + }, + "dependencies": { + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validator": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-11.1.0.tgz", + "integrity": "sha512-qiQ5ktdO7CD6C/5/mYV4jku/7qnqzjrxb3C/Q5wR3vGGinHTgJZN/TdFT3ZX4vXhX2R1PXx42fB1cn5W+uJ4lg==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wkx": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.8.tgz", + "integrity": "sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ==", + "requires": { + "@types/node": "*" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", + "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.11", + "yargs": "^12.0.5" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } - } } - } } diff --git a/package.json b/package.json index 6d3cebc..64fe084 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "express-authorshaven", + "name": "archangel_barefoot_nomad", "version": "1.0.0", - "description": "A Social platform for the creative at heart", + "description": "An application for company global travels and accommodation", "main": "index.js", "scripts": { "build": "babel -d ./build ./src -s", @@ -9,7 +9,9 @@ "start": "set NODE_ENV=development&& babel-node src/index.js", "dev": "set DEBUG=web-app && set NODE_ENV=development&& nodemon src/index.js --exec babel-node", "test": "set NODE_ENV=test&& sequelize db:migrate:undo:all && sequelize db:migrate && mocha --timeout 0 ./src/tests/*.js --require @babel/register --reporter spec --exec babel-node --exit", - "coverage": "nyc report --reporter=text-lcov | coveralls", + "generate-lcov": "nyc report --reporter=text-lcov >lcov.info", + "coveralls-coverage": "coveralls < lcov.info", + "coverage": "nyc npm test && npm run generate-lcov && npm run coveralls-coverage", "coveralls": "nyc --reporter=lcov --reporter=text-lcov npm test", "create:db": "set NODE_ENV=development&& sequelize db:create", "drop:db": "set NODE_ENV=development&& sequelize db:drop", @@ -20,6 +22,7 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", + "auto-bind": "^2.1.0", "bcrypt": "^3.0.6", "chai": "^4.2.0", "chai-http": "^4.3.0", @@ -33,11 +36,14 @@ "express": "^4.17.1", "express-jwt": "^5.3.1", "express-session": "^1.15.6", + "express-validator": "^6.1.1", "jsonwebtoken": "^8.3.0", "method-override": "^2.3.10", "methods": "^1.1.2", "morgan": "^1.9.1", "passport": "^0.4.0", + "passport-facebook": "^3.0.0", + "passport-google-oauth20": "^2.0.0", "passport-local": "^1.0.0", "path": "^0.12.7", "pg": "^7.12.1", @@ -46,6 +52,7 @@ "request": "^2.87.0", "sequelize": "^5.15.2", "sequelize-cli": "^5.5.0", + "socket.io": "^2.2.0", "underscore": "^1.9.1" }, "devDependencies": { @@ -64,6 +71,7 @@ "eslint-plugin-react": "^7.14.3", "eslint-plugin-react-hooks": "^1.7.0", "mocha": "^6.2.0", + "mocha-lcov-reporter": "^1.3.0", "nodemon": "^1.19.1" } } diff --git a/src/database/migrations/20190904023213-create-notifications.js b/src/database/migrations/20190904023213-create-notifications.js new file mode 100644 index 0000000..f057309 --- /dev/null +++ b/src/database/migrations/20190904023213-create-notifications.js @@ -0,0 +1,29 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('notifications', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + travel_id: { + type: Sequelize.INTEGER + }, + read_status: { + type: Sequelize.BOOLEAN + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('notifications'); + } +}; \ No newline at end of file diff --git a/src/database/models/notifications.js b/src/database/models/notifications.js new file mode 100644 index 0000000..43b4540 --- /dev/null +++ b/src/database/models/notifications.js @@ -0,0 +1,13 @@ +module.exports = (sequelize, DataTypes) => { + const notifications = sequelize.define('notifications', { + travel_id: DataTypes.INTEGER, + read_status: DataTypes.BOOLEAN + }, {}); + notifications.associate = (models) => { + // associations can be defined here + notifications.belongsTo(models.travels, { + foreignKey: 'travel_id', + }); + }; + return notifications; +}; \ No newline at end of file diff --git a/src/database/seeders/20190904024301-notifications.js b/src/database/seeders/20190904024301-notifications.js new file mode 100644 index 0000000..d22b3ca --- /dev/null +++ b/src/database/seeders/20190904024301-notifications.js @@ -0,0 +1,23 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.bulkInsert('notifications', [{ + id: 333, + travel_id: 1378, + read_status: false, + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: 1627, + travel_id: 1573, + read_status: false, + createdAt: new Date(), + updatedAt: new Date() + }, + ], {}); + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.bulkDelete('notifications', null, {}); + } +}; \ No newline at end of file From a39836287ae226fd4cb714ee03ab3ab697192944 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Wed, 4 Sep 2019 05:53:50 +0100 Subject: [PATCH 03/23] pop-up of stashed commits --- src/index.js | 87 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/index.js b/src/index.js index c2ed93f..442176a 100755 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,8 @@ import logger from 'morgan'; import debug from 'debug'; import cors from 'cors'; import methodOverride from 'method-override'; +import http from 'http'; +import socketIo from 'socket.io'; import { fbStrategy, googleStrategy } from './config/passport'; import message from './utils/messageUtils'; @@ -13,10 +15,15 @@ import response from './utils/response'; import statusCode from './utils/statusCode'; import routes from './routes'; + + dotenv.config(); const debugLog = debug('web-app'); + // Create global app object const app = express(); +const server = http.server(app); +const io = socketIo(server); const PORT = process.env.PORT || 5000; @@ -30,18 +37,20 @@ app.use(express.urlencoded({ extended: false })); app.use(cors()); app.options('*', cors()); + app.use(methodOverride()); + // social media authentication passport.use(fbStrategy); passport.use(googleStrategy); passport.serializeUser((user, cb) => { - cb(null, user); + cb(null, user); }); passport.deserializeUser((user, cb) => { - cb(null, user); + cb(null, user); }); @@ -54,20 +63,26 @@ app.all('/', (req, res) => response.successResponse(res, statusCode.success, mes // app.use('/', router); -app.get(`${prefix}/`, (req, res) => { - response.successResponse(res, statusCode.success, message.welcome); +// This is the point where the main API routes is served from... +app.all(`${prefix}/`, (req, res) => { + response.successResponse(res, statusCode.success, message.welcome); }); +// serve the api endpoints built in routes folder +routes(prefix, app); + +app.use(routes(io)); + const isProduction = process.env.NODE_ENV === 'production'; // creating session app.use( - session({ - secret: 'authorshaven', - cookie: { maxAge: 60000 }, - resave: false, - saveUninitialized: false, - }), + session({ + secret: 'authorshaven', + cookie: { maxAge: 60000 }, + resave: false, + saveUninitialized: false, + }), ); app.use(passport.initialize()); @@ -77,9 +92,9 @@ app.use(passport.session()); // catch 404 and forward to error handler app.use((req, res, next) => { - const err = new Error('Not Found'); - err.status = 404; - next(err); + const err = new Error('Not Found'); + err.status = 404; + next(err); }); // error handlers @@ -87,36 +102,38 @@ app.use((req, res, next) => { // development error handler // will print stacktrace if (!isProduction) { - app.use((err, req, res, next) => { - debugLog(`Error Stack: ${err.stack}`); - - res.status(err.status || 500); - - res.json({ - errors: { - message: err.message, - error: err, - }, + app.use((err, req, res, next) => { + debugLog(`Error Stack: ${err.stack}`); + + res.status(err.status || 500); + + res.json({ + errors: { + message: err.message, + error: err, + }, + }); + next(); }); - next(); - }); } // production error handler // no stack-traces leaked to user app.use((err, req, res, next) => { - res.status(err.status || 500); - res.json({ - errors: { - message: err.message, - error: {}, - }, - }); - next(); + res.status(err.status || 500); + res.json({ + errors: { + message: err.message, + error: {}, + }, + }); + next(); }); -app.listen(PORT, () => { - debugLog(`Barefoot-Nomad [Backend] Server is running on port ${PORT}`); + +app.listen(PORT, () => { << + + debugLog(`Barefoot-Nomad [Backend] Server is running on port ${PORT}`); }); // for testing From e16b72e38e54ab584691290daaa0dd38747a02e9 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Wed, 4 Sep 2019 10:52:05 +0100 Subject: [PATCH 04/23] declaring server as a function in the entry point --- src/index.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/index.js b/src/index.js index 442176a..47de3fc 100755 --- a/src/index.js +++ b/src/index.js @@ -22,7 +22,7 @@ const debugLog = debug('web-app'); // Create global app object const app = express(); -const server = http.server(app); +const server = http.createServer(app); const io = socketIo(server); @@ -69,9 +69,9 @@ app.all(`${prefix}/`, (req, res) => { }); // serve the api endpoints built in routes folder -routes(prefix, app); +routes(prefix, app, io); -app.use(routes(io)); +// app.use(routes(io)); const isProduction = process.env.NODE_ENV === 'production'; @@ -130,11 +130,10 @@ app.use((err, req, res, next) => { next(); }); - -app.listen(PORT, () => { << - +server.listen(PORT, () => { debugLog(`Barefoot-Nomad [Backend] Server is running on port ${PORT}`); }); // for testing -export default app; +module.exports = server; +// module.exports = app; From 7b1af3a06d47ed6cf4b24af4538b442dea1220cf Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Wed, 4 Sep 2019 22:48:17 +0100 Subject: [PATCH 05/23] setting up the project --- .editorconfig | 2 +- src/controllers/notifyController.js | 0 src/controllers/travelControllers.js | 55 ++----------------- .../20190823125926-create-department.js | 32 ----------- .../20190823125926-create-departments.js | 35 ++++++++++++ .../20190823140019-create-travels.js | 41 ++++++++++++++ .../20190823140048-create-accommodation.js | 36 ------------ .../20190823140048-create-accommodations.js | 36 ++++++++++++ .../20190904023213-create-notifications.js | 3 + src/database/models/departments.js | 17 ++++++ src/database/models/notifications.js | 6 +- src/database/models/travels.js | 17 ++++++ .../seeders/20190824033354-department.js | 24 -------- .../seeders/20190824033354-departments.js | 27 +++++++++ .../seeders/20190824033956-travels.js | 31 +++++++++++ .../seeders/20190824034012-accommodation.js | 25 --------- .../seeders/20190824034012-accommodations.js | 35 ++++++++++++ .../seeders/20190904024301-notifications.js | 2 + src/models/accommodation.js | 18 ++---- src/routes/api/notifyRoutes.js | 5 ++ src/utils/messageUtils.js | 37 +++++++------ 21 files changed, 287 insertions(+), 197 deletions(-) create mode 100644 src/controllers/notifyController.js delete mode 100644 src/database/migrations/20190823125926-create-department.js create mode 100644 src/database/migrations/20190823125926-create-departments.js create mode 100644 src/database/migrations/20190823140019-create-travels.js delete mode 100644 src/database/migrations/20190823140048-create-accommodation.js create mode 100644 src/database/migrations/20190823140048-create-accommodations.js create mode 100644 src/database/models/departments.js create mode 100644 src/database/models/travels.js delete mode 100644 src/database/seeders/20190824033354-department.js create mode 100644 src/database/seeders/20190824033354-departments.js create mode 100644 src/database/seeders/20190824033956-travels.js delete mode 100644 src/database/seeders/20190824034012-accommodation.js create mode 100644 src/database/seeders/20190824034012-accommodations.js create mode 100644 src/routes/api/notifyRoutes.js diff --git a/.editorconfig b/.editorconfig index f71a6fd..55094a8 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,5 @@ charset = utf-8 # Set indentation style and size for javascript files [*.js] -indent_style = space +indent_style = tab indent_size = 2 diff --git a/src/controllers/notifyController.js b/src/controllers/notifyController.js new file mode 100644 index 0000000..e69de29 diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index 2de9619..0910625 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,7 +1,6 @@ import { onewayTripService, - showManagerPendingAppr, - showUsertravelsStatus + showManagerPendingAppr, } from '../services/travelServices'; import { successResponseWithData, errorResponse } from '../utils/response'; @@ -12,19 +11,13 @@ export default { createOneWayTrip: async (req, res) => { try { const { - origin, destination, departure_date, accommodation_id, travel_purpose - } = req.body; + origin, destination, departure_date, travel_purpose +} = req.body; const userId = req.userData.id; const travelObj = { - user_id: userId, - travel_type: 'one-way', - origin, - destination, - departure_date, - travel_purpose, - accommodation_id, - }; + user_id: userId, origin, destination, departure_date, travel_purpose +}; const data = await onewayTripService(travelObj); @@ -33,42 +26,4 @@ export default { errorResponse(res, statusCode.serverError, err); } }, - - pendingManagerApproval: async (req, res) => { - const { role } = req.userData; - - const { manager } = req.params; - - if (role === 'user') { - errorResponse(res, statusCode.unauthorized, message.unauthorized); - } - - try { - const requestsPending = await showManagerPendingAppr(manager); - - const filteredRequests = requestsPending.filter(request => request['user.department.line_manager'] !== null); - - const requestNumbers = filteredRequests.length; - - // eslint-disable-next-line max-len - successResponseWithData(res, statusCode.success, message.managerApproval(requestNumbers), filteredRequests); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, - - getUserTravelStatus: async(req, res) => { - const { role, id } = req.userData; - - if (role === 'admin') { - return errorResponse(res, statusCode.unauthorized, message.unauthorized); - } else { - try { - const data = await showUsertravelsStatus(id); - return successResponseWithData(res, statusCode.success, message.userApproval, data); - } catch (error) { - errorResponse(res, statusCode.serverError, error); - } - } - } }; diff --git a/src/database/migrations/20190823125926-create-department.js b/src/database/migrations/20190823125926-create-department.js deleted file mode 100644 index 97e5494..0000000 --- a/src/database/migrations/20190823125926-create-department.js +++ /dev/null @@ -1,32 +0,0 @@ -module.exports = { - up: function up(queryInterface, Sequelize) { - return queryInterface.createTable('departments', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - dept_name: { - type: Sequelize.TEXT - }, - line_manager: { - type: Sequelize.TEXT - }, - manager_staff_id: { - type: Sequelize.STRING - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }); - }, - down: function down(queryInterface, Sequelize) { - return queryInterface.dropTable('departments'); - } -}; diff --git a/src/database/migrations/20190823125926-create-departments.js b/src/database/migrations/20190823125926-create-departments.js new file mode 100644 index 0000000..1df3715 --- /dev/null +++ b/src/database/migrations/20190823125926-create-departments.js @@ -0,0 +1,35 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('departments', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + dept_name: { + type: Sequelize.TEXT + }, + line_manager: { + type: Sequelize.TEXT + }, + manager_staff_id: { + type: Sequelize.STRING + }, + manager_email: { + type: Sequelize.TEXT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('departments'); + } +}; diff --git a/src/database/migrations/20190823140019-create-travels.js b/src/database/migrations/20190823140019-create-travels.js new file mode 100644 index 0000000..e91e3c3 --- /dev/null +++ b/src/database/migrations/20190823140019-create-travels.js @@ -0,0 +1,41 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('travels', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + user_id: { + type: Sequelize.INTEGER, + }, + origin: { + type: Sequelize.TEXT + }, + destination: { + type: Sequelize.TEXT + }, + departure_date: { + type: Sequelize.DATE + }, + return_date: { + type: Sequelize.DATE + }, + travel_purpose: { + type: Sequelize.TEXT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('travels'); + } +}; \ No newline at end of file diff --git a/src/database/migrations/20190823140048-create-accommodation.js b/src/database/migrations/20190823140048-create-accommodation.js deleted file mode 100644 index 79e0dd9..0000000 --- a/src/database/migrations/20190823140048-create-accommodation.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = { - up: function up(queryInterface, Sequelize) { - return queryInterface.createTable('accommodations', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - location: { - type: Sequelize.TEXT - }, - capacity: { - type: Sequelize.INTEGER - }, - accommodation_name: { - type: Sequelize.TEXT, - allowNull: false, - validate: { - msg: 'Please provide your accommodation\'s name' - } - }, - createdAt: { - allowNull: true, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: true, - type: Sequelize.DATE - } - }); - }, - down: function down(queryInterface, Sequelize) { - return queryInterface.dropTable('accommodations'); - } -}; diff --git a/src/database/migrations/20190823140048-create-accommodations.js b/src/database/migrations/20190823140048-create-accommodations.js new file mode 100644 index 0000000..1fe66c4 --- /dev/null +++ b/src/database/migrations/20190823140048-create-accommodations.js @@ -0,0 +1,36 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('accommodations', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + location: { + type: Sequelize.TEXT + }, + capacity: { + type: Sequelize.INTEGER + }, + accommodation_name: { + type: Sequelize.TEXT, + allowNull: false, + validate: { + msg: 'Please provide your accommodation\'s name' + } + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('accommodations'); + } +}; diff --git a/src/database/migrations/20190904023213-create-notifications.js b/src/database/migrations/20190904023213-create-notifications.js index f057309..4d26913 100644 --- a/src/database/migrations/20190904023213-create-notifications.js +++ b/src/database/migrations/20190904023213-create-notifications.js @@ -10,6 +10,9 @@ module.exports = { travel_id: { type: Sequelize.INTEGER }, + manager_email: { + type: Sequelize.TEXT + }, read_status: { type: Sequelize.BOOLEAN }, diff --git a/src/database/models/departments.js b/src/database/models/departments.js new file mode 100644 index 0000000..81bbeb9 --- /dev/null +++ b/src/database/models/departments.js @@ -0,0 +1,17 @@ +module.exports = (sequelize, DataTypes) => { + const departments = sequelize.define('departments', { + dept_name: DataTypes.TEXT, + line_manager: DataTypes.TEXT, + manager_staff_id: DataTypes.STRING, + manager_email: DataTypes.TEXT + }, {}); + + departments.associate = (models) => { + // associations can be defined here + // departments.hasMany(models.notifications, { + // foreignKey: 'manager_email' + // }); + }; + + return departments; +}; \ No newline at end of file diff --git a/src/database/models/notifications.js b/src/database/models/notifications.js index 43b4540..8466eda 100644 --- a/src/database/models/notifications.js +++ b/src/database/models/notifications.js @@ -1,12 +1,16 @@ module.exports = (sequelize, DataTypes) => { const notifications = sequelize.define('notifications', { travel_id: DataTypes.INTEGER, + manager_email: DataTypes.TEXT, read_status: DataTypes.BOOLEAN }, {}); notifications.associate = (models) => { // associations can be defined here notifications.belongsTo(models.travels, { - foreignKey: 'travel_id', + foreignKey: 'travel_id' + }); + notifications.hasMany(models.departments, { + foreignKey: 'manager_email' }); }; return notifications; diff --git a/src/database/models/travels.js b/src/database/models/travels.js new file mode 100644 index 0000000..27a06bb --- /dev/null +++ b/src/database/models/travels.js @@ -0,0 +1,17 @@ +module.exports = (sequelize, DataTypes) => { + const travels = sequelize.define('travels', { + user_id: DataTypes.INTEGER, + origin: DataTypes.TEXT, + destination: DataTypes.TEXT, + departure_date: DataTypes.DATE, + return_date: DataTypes.DATE, + travel_purpose: DataTypes.TEXT + }, {}); + travels.associate = (models) => { + travels.belongsTo(models.users, { + foreignKey: 'user_id', + onDelete: 'CASCADE' + }); + }; + return travels; +}; \ No newline at end of file diff --git a/src/database/seeders/20190824033354-department.js b/src/database/seeders/20190824033354-department.js deleted file mode 100644 index b208731..0000000 --- a/src/database/seeders/20190824033354-department.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - up: function up(queryInterface, Sequelize) { - return queryInterface.bulkInsert('departments', [{ - id: 15327458, - dept_name: 'Business Admin', - line_manager: 'Mr. Benchfort', - manager_staff_id: 'GHJ-378-2838', - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: 1536907, - dept_name: 'Software Engr', - line_manager: 'Ms. Querty', - manager_staff_id: 'RDS-256-5787', - createdAt: new Date(), - updatedAt: new Date(), - }, - ], {}); - }, - down: function down(queryInterface, Sequelize) { - return queryInterface.bulkDelete('departments', null, {}); - } -}; diff --git a/src/database/seeders/20190824033354-departments.js b/src/database/seeders/20190824033354-departments.js new file mode 100644 index 0000000..d7939f8 --- /dev/null +++ b/src/database/seeders/20190824033354-departments.js @@ -0,0 +1,27 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.bulkInsert('departments', [{ + id: '15327458', + dept_name: 'Business Admin', + line_manager: 'Mr. Benchfort', + manager_staff_id: 'GHJ-378-2838', + manager_email: 'benchfort@gmail.com', + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: '1536907', + dept_name: 'Software Engr', + line_manager: 'Ms. Querty', + manager_staff_id: 'RDS-256-5787', + manager_email: 'trello@gmail.com', + createdAt: new Date(), + updatedAt: new Date(), + }, + ], {}); + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.bulkDelete('departments', null, {}); + } +}; diff --git a/src/database/seeders/20190824033956-travels.js b/src/database/seeders/20190824033956-travels.js new file mode 100644 index 0000000..6626a0c --- /dev/null +++ b/src/database/seeders/20190824033956-travels.js @@ -0,0 +1,31 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.bulkInsert('travels', [{ + id: 1898451, + user_id: 1674946, + origin: 'New York, USA', + destination: 'Paris, France', + departure_date: new Date(), + return_date: new Date(), + travel_purpose: 'This is the reason for my travel', + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 1891029, + user_id: 1215739, + origin: 'Washington DC, USA', + destination: 'Toronto, Canada', + departure_date: new Date(), + return_date: new Date(), + travel_purpose: 'This is the most important reason for my travel', + createdAt: new Date(), + updatedAt: new Date(), + }, + ], {}); + }, + + down: (queryInterface, Sequelize) => { + return queryInterface.bulkDelete('travels', null, {}); + } +}; \ No newline at end of file diff --git a/src/database/seeders/20190824034012-accommodation.js b/src/database/seeders/20190824034012-accommodation.js deleted file mode 100644 index 569f9a4..0000000 --- a/src/database/seeders/20190824034012-accommodation.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - up: function up(queryInterface, Sequelize) { - return queryInterface.bulkInsert('accommodations', [{ - id: 1653453, - location: 'Paris, France', - capacity: 3, - accommodation_name: 'Sheraton Protea', - createdAt: new Date(), - updatedAt: new Date() - }, - { - id: 1332557, - location: 'Toronto, Canada', - capacity: 1, - accommodation_name: 'PAR Towers', - createdAt: new Date(), - updatedAt: new Date() - }, - ], {}); - }, - - down: function down(queryInterface, Sequelize) { - return queryInterface.bulkDelete('accommodations', null, {}); - } -}; diff --git a/src/database/seeders/20190824034012-accommodations.js b/src/database/seeders/20190824034012-accommodations.js new file mode 100644 index 0000000..02cf36a --- /dev/null +++ b/src/database/seeders/20190824034012-accommodations.js @@ -0,0 +1,35 @@ +module.exports = { +up: (queryInterface, Sequelize) => { + return queryInterface.bulkInsert('accommodations', [{ + id: 1653453, + location: "Paris, France", + capacity: 3, + accommodation_name: "Sheraton Protea", + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: 13325578, + location: "Toronto, Canada", + capacity: 1, + accommodation_name: "PAR Towers", + createdAt: new Date(), + updatedAt: new Date() + }, + ], {}); +}, +{ + id: 1332557, + location: 'Toronto, Canada', + capacity: 1, + accommodation_name: 'PAR Towers', + createdAt: new Date(), + updatedAt: new Date() +}, +], {}); +}, + +down: (queryInterface, Sequelize) => { + return queryInterface.bulkDelete('accommodations', null, {}); +} +}; diff --git a/src/database/seeders/20190904024301-notifications.js b/src/database/seeders/20190904024301-notifications.js index d22b3ca..30cf598 100644 --- a/src/database/seeders/20190904024301-notifications.js +++ b/src/database/seeders/20190904024301-notifications.js @@ -3,6 +3,7 @@ module.exports = { return queryInterface.bulkInsert('notifications', [{ id: 333, travel_id: 1378, + manager_email: '83289benchfort@gmail.com', read_status: false, createdAt: new Date(), updatedAt: new Date() @@ -10,6 +11,7 @@ module.exports = { { id: 1627, travel_id: 1573, + manager_email: '234trello@gmail.com', read_status: false, createdAt: new Date(), updatedAt: new Date() diff --git a/src/models/accommodation.js b/src/models/accommodation.js index 142c842..5a807ae 100644 --- a/src/models/accommodation.js +++ b/src/models/accommodation.js @@ -1,15 +1,9 @@ module.exports = (sequelize, DataTypes) => { - const accommodations = sequelize.define('accommodations', { - location: DataTypes.TEXT, - capacity: DataTypes.INTEGER, - accommodation_name: DataTypes.TEXT - }, {}); + const accommodations = sequelize.define('accommodations', { + location: DataTypes.TEXT, + capacity: DataTypes.INTEGER, + accommodation_name: DataTypes.TEXT + }, {}); - accommodations.associate = (models) => { - accommodations.hasMany(models.travel_requests, { - foreignKey: 'accommodation_id', - }); - }; - - return accommodations; + return accommodations; }; diff --git a/src/routes/api/notifyRoutes.js b/src/routes/api/notifyRoutes.js new file mode 100644 index 0000000..007ae79 --- /dev/null +++ b/src/routes/api/notifyRoutes.js @@ -0,0 +1,5 @@ +import { Router } from 'express'; + +import notifyControllers from '../../controllers/notifyControllers'; +import notifyValidator from '../../validation/notifyValidation'; +import authUtils from '../../middlewares/tokenMiddleware'; \ No newline at end of file diff --git a/src/utils/messageUtils.js b/src/utils/messageUtils.js index 0d19aaa..8a7bd18 100644 --- a/src/utils/messageUtils.js +++ b/src/utils/messageUtils.js @@ -10,7 +10,6 @@ export default { managerApproval: (pendingReq) => `You have ${pendingReq} requests requiring your approval`, managerNotFound: "Manager's detail missing", noEmail: 'Email cannot be empty.', - userApproval: 'Here are your request status', // sign-up validation messages invalidEmail: 'Please, enter a valid email address.', usedEmail: (email) => `User with this email (${email}) already exist.`, @@ -32,19 +31,25 @@ export default { userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.`, - // comment messages - successComment: [ - 'You have successfully commented on a travel request.', - 'You have successfully retrieved all comments for this travel request.', - ], - unregisteredEmail: (email) => `User with this email (${email}) not found in our database.`, - emptyEmail: 'Email cannot be empty.', - invalidTravelId: 'The travel ID must be an integer value.', - travelNotFound: 'The travel request does not exist.', - unauthorizedAccessToTravel: - 'Access denied. Accessible only by travel requester or his/her line manager.', - emptyComment: 'comment cannot be empty.', - unauthorizedCommentDelete: "comment can only be deleted by it's author", - commentNotFound: 'The comment does not exist.', - deleteComment: 'Comment successfully deleted.', + noEmail: 'Email cannot be empty.', + // sign-up validation messages + invalidEmail: 'Please, enter a valid email address.', + usedEmail: (email) => `User with this email (${email}) already exist.`, + shortPassword: 'The length of the password must be 8 and above.', + noDigitInPassword: 'Password must contain at least one digit.', + emptyFirstname: 'First name cannot be empty.', + emptyLastname: 'Last name cannot be empty.', + emptyOrigin: 'You must state your current city.', + emptyDestination: 'You must state your destination', + emptyDepartureDate: 'You must state your departure date', + emptyReturnDate: 'You must state your return date', + emptyTravelPurpose: 'You must state your travel purpose', + lettersAlone: 'Only letters are allowed', + unauthorized: 'Not authorized.', + invalidToken: 'Invalid Token, please login.', + logoutSuccess: 'Logged out successfully.', + incorrectPassword: 'Sorry, the password entered is not correct.', + loginSuccess: 'You have been logged in successfully.', + userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, + userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.` }; From ce3ea151b30ed1a89cda51de37903e18af634eda Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Thu, 5 Sep 2019 12:12:02 +0100 Subject: [PATCH 06/23] updating the controller and test files with line-spacing --- src/tests/auth.test.js | 402 ++++++++++++++++++----------------------- 1 file changed, 175 insertions(+), 227 deletions(-) diff --git a/src/tests/auth.test.js b/src/tests/auth.test.js index 5f3b6ba..9c9d898 100644 --- a/src/tests/auth.test.js +++ b/src/tests/auth.test.js @@ -14,7 +14,6 @@ const passwordResetToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjM let passwordUserId; - chai.use(chaiHttp); describe('Test for the Auth controller functions', () => { @@ -24,15 +23,13 @@ describe('Test for the Auth controller functions', () => { email: 'emma.k@yahoo.com', password: 'testing123', }; - it('should successfully sign up a user', (done) => { chai .request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(user) .end((err, res) => { const { data } = res.body; - expect(res).to.have.status(201); expect(data).to.include({ first_name: 'Emma', @@ -42,18 +39,17 @@ describe('Test for the Auth controller functions', () => { done(); }); }); - it('should return an error message if the email is empty', (done) => { const mutatedUser = Object.assign({}, user); delete mutatedUser.email; chai.request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(message.noEmail); + .equal('Email cannot be empty.'); done(); }); }); @@ -62,23 +58,23 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'invalid@yahoo'; chai.request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(message.invalidEmail); + .equal('Please, enter a valid email address.'); done(); }); }); it('should return an error message if the email already exists', (done) => { chai.request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(user) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(message.usedEmail(user.email)); + .equal(`User with this email (${user.email}) already exist.`); done(); }); }); @@ -88,12 +84,12 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(message.shortPassword); + .equal('The length of the password must be 8 and above.'); done(); }); }); @@ -103,12 +99,12 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(message.noDigitInPassword); + .equal('Password must contain at least one digit.'); done(); }); }); @@ -118,12 +114,12 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(message.emptyFirstname); + .equal('First name cannot be empty.'); done(); }); }); @@ -133,224 +129,176 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(signupRoute) + .post(`${prefix}/auth/signup`) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(message.emptyLastname); + .equal('Last name cannot be empty.'); done(); }); }); -}); - -// This is the tests that will run for the user signin with username and password.. -describe('TEST USER LOGIN ROUTE', () => { - - const loginData = { - email: 'emma.k@yahoo.com', - password: 'testing123' - }; - - it('should throw an error with a status of 400 if the email supplied is invalid', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.email = 'invalidemail'; - - chai.request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal(message.invalidEmail); - done(); - }); - }); - - it('should throw an error with a status of 404 if the email supplied does not exist', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.email = 'testerroremail@yahoo.com'; - - chai - .request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { status } = res; - expect(status).to.be.eql(404); - done(err); - }); - }); - - it('should return an error message if the password length is less than 8', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'pwdless'; - - chai.request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal(message.shortPassword); - done(err); - }); - }); - - it('should return an error message if the password does not contain at least a digit', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'nodigitpwd'; - - chai.request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal(message.noDigitInPassword); - done(err); - }); - }); - - it('should throw an error with a status of 400 if the password supplied is wrong', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'passw4567'; - - chai - .request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.be.eql(400); - expect(body.error.message).to - .equal(message.incorrectPassword); - done(err); - }); - }); - - it('should authenticate a user with a valid email and password', (done) => { - chai - .request(app) - .post(signinRoute) - .send(loginData) - .end((err, res) => { - const { body, status } = res; - expect(body.data).to.not.eql(null); - expect(status).to.be.eql(200); - done(err); - }); - }); - - it('should contain a token value in its response data object', (done) => { - chai.request(app) - .post(signinRoute) - .send(loginData) - .end((err, res) => { - const { data } = res.body; - expect(data).to.have.ownProperty('token'); - done(err); - }); - }); -}); -// The test for the auth/login by email and paswword ends here... - -describe('Testing logout feature', () => { - const testuser = { - first_name: 'Emmatesto', - last_name: 'Koredetesto', - email: 'emmaff.ki@yahoo.com', - password: 'testing321', - }; - let token; - before((done) => { - chai - .request(app) - .post(signupRoute) - .send(testuser) - .end((err, res) => { - const { data } = res.body; - token = data.token; - done(); - }); - }); - - it('should return an error if token is not supplied', (done) => { - chai.request(app) - .post(logoutRoute) - .end((err, res) => { - expect(res.status).to.equal(401); - done(); - }); - }); - it('should return an error if the token is invalid', (done) => { - chai.request(app) - .post(logoutRoute) - .set('Authorization', 'Bearer hjgvju') - .end((err, res) => { - expect(res.status).to.equal(401); - done(); - }); - }); - it('should successfully logout a user', (done) => { - chai.request(app) - .post(logoutRoute) - .set('Authorization', token) - .end((err, res) => { - expect(res.status).to.equal(200); - done(); - }); - }); -}); - -describe('Send Password Reset', () => { - const testuser = { - first_name: 'Temi', - last_name: 'Bakar', - email: 'bakaretemitayo@gmail.com', - password: 'testing321', - }; - let email; - before((done) => { - chai - .request(app) - .post(signupRoute) - .send(testuser) - .end((err, res) => { - const { data } = res.body; - email = data.email; - passwordUserId = data.id; - done(); - }); + // This is the tests that will run for the user signin with username and password.. + describe('TEST USER LOGIN ROUTE', () => { + let signinRoute = `${prefix}/auth/login`; + + const loginData = { + email: 'emma.k@yahoo.com', + password: 'testing123' + }; + + it('should throw an error with a status of 400 if the email supplied is invalid', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.email = 'invalidemail'; + + chai.request(app) + .post(`${prefix}/auth/login`) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal('Please, enter a valid email address.'); + done(); + }); + }); + + it('should throw an error with a status of 404 if the email supplied does not exist', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.email = 'testerroremail@yahoo.com'; + + chai + .request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { status } = res; + expect(status).to.be.eql(404); + done(err); + }); + }); + + it('should return an error message if the password length is less than 8', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'pwdless'; + + chai.request(app) + .post(`${prefix}/auth/login`) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal('The length of the password must be 8 and above.'); + done(err); + }); + }); + + it('should return an error message if the password does not contain at least a digit', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'nodigitpwd'; + + chai.request(app) + .post(`${prefix}/auth/login`) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal('Password must contain at least one digit.'); + done(err); + }); + }); + + it('should throw an error with a status of 400 if the password supplied is wrong', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'passw4567'; + + chai + .request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.be.eql(400); + expect(body.error.message).to + .equal('Sorry, the password entered is not correct.'); + done(err); + }); + }); + + it('should authenticate a user with a valid email and password', (done) => { + chai + .request(app) + .post(signinRoute) + .send(loginData) + .end((err, res) => { + const { body, status } = res; + expect(body.data).to.not.eql(null); + expect(status).to.be.eql(200); + done(err); + }); + }); + + it('should contain a token value in its response data object', (done) => { + chai.request(app) + .post(signinRoute) + .send(loginData) + .end((err, res) => { + const { data } = res.body; + expect(data).to.have.ownProperty('token'); + done(err); + }); + }); }); - - /* it('it should send token for resetting password', (done) => { - // eslint-disable-next-line quote-props - const user_email = { 'email': email }; - chai.request(app) - .post(`${prefix}/forgot`) - .send(user_email) - .end((err, res) => { - expect(res.status).to.equal(200); - expect(user_email).to.have.property('email'); - done(); - }); - }); */ - - - it('it should reset password via password reset link', (done) => { - const passwordResetData = { password: 'testpassword' }; - chai.request(app) - .post(`${prefix}/receive_new_password/${passwordUserId}/${passwordResetToken}`) - .send(passwordResetData) - .end((err, res) => { - expect(res.status).to.equal(202); - expect(passwordResetData).to.have.property('password'); - done(); - }); + // The test for the auth/login by email and paswword ends here... + + + describe('Testing logout feature', () => { + const testuser = { + first_name: 'Emmatest', + last_name: 'Koredetest', + email: 'emmaff.k@yahoo.com', + password: 'testing321', + }; + let token; + before((done) => { + chai + .request(app) + .post(`${prefix}/auth/signup`) + .send(testuser) + .end((err, res) => { + const { data } = res.body; + token = data.token; + done(); + }); + }); + it('should return an error if token is not supplied', (done) => { + chai.request(app) + .post(`${prefix}/auth/logout`) + .end((err, res) => { + expect(res.status).to.equal(401); + done(); + }); + }); + it('should return an error if the token is invalid', (done) => { + chai.request(app) + .post(`${prefix}/auth/logout`) + .set('Authorization', 'Bearer hjgvju') + .end((err, res) => { + expect(res.status).to.equal(401); + done(); + }); + }); + it('should successfully logout a user', (done) => { + chai.request(app) + .post(`${prefix}/auth/logout`) + .set('Authorization', `Bearer ${token}`) + .end((err, res) => { + expect(res.status).to.equal(200); + done(); + }); + }); }); }); From 5e8e02364f20166904c5b077ae80d75ecdd9c7c3 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Thu, 5 Sep 2019 13:21:05 +0100 Subject: [PATCH 07/23] updating the .env file to hold values for sendGrid --- .env.sample | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.env.sample b/.env.sample index de391d5..0928421 100644 --- a/.env.sample +++ b/.env.sample @@ -28,3 +28,5 @@ JWT_EMAIL_SECRET EMAIL_ADD EMAIL_PASS +SENDGRID_API + From 1e22bad29f3e47790b4ea80f11bb20b06c922678 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Thu, 5 Sep 2019 16:28:21 +0100 Subject: [PATCH 08/23] created service and routes files --- package-lock.json | 5 + package.json | 1 + src/controllers/index.js | 4 +- ...tifyController.js => notifyControllers.js} | 0 src/controllers/resetPassword.js | 103 +++++++++--------- src/routes/api/notifyRoutes.js | 23 +++- src/services/notifyServices.js | 48 ++++++++ src/tests/mocks/users.js | 18 +++ 8 files changed, 145 insertions(+), 57 deletions(-) rename src/controllers/{notifyController.js => notifyControllers.js} (100%) create mode 100644 src/services/notifyServices.js create mode 100644 src/tests/mocks/users.js diff --git a/package-lock.json b/package-lock.json index 3a33748..f862f7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1592,6 +1592,11 @@ "tweetnacl": "^0.14.3" } }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, "better-assert": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", diff --git a/package.json b/package.json index 64fe084..3c046d2 100755 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@babel/runtime": "^7.5.5", "auto-bind": "^2.1.0", "bcrypt": "^3.0.6", + "bcryptjs": "^2.4.3", "chai": "^4.2.0", "chai-http": "^4.3.0", "core-js": "^3.2.1", diff --git a/src/controllers/index.js b/src/controllers/index.js index ea10091..1941fd2 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -1,5 +1,5 @@ import { authControllers } from './authControllers'; export { -authControllers -}; \ No newline at end of file + authControllers +}; diff --git a/src/controllers/notifyController.js b/src/controllers/notifyControllers.js similarity index 100% rename from src/controllers/notifyController.js rename to src/controllers/notifyControllers.js diff --git a/src/controllers/resetPassword.js b/src/controllers/resetPassword.js index fd35c85..fc9eb23 100644 --- a/src/controllers/resetPassword.js +++ b/src/controllers/resetPassword.js @@ -6,74 +6,73 @@ import { getPasswordResetURL, usePasswordHashToMakeToken, resetPasswordTemplate - } from "../modules/email" +} from "../modules/email" const { - queryByEmail, - queryById, - updatePassword - } = emailServices; + queryByEmail, + queryById, + updatePassword +} = emailServices; - /** - * Send user reset password on the application - * @static - * @param {object} req - The request object - * @param {object} res - The response object - * @return {object} JSON object representing success - */ +/** + * Send user reset password on the application + * @static + * @param {object} req - The request object + * @param {object} res - The response object + * @return {object} JSON object representing success + */ - const sendPasswordResetEmail = async (req, res) => { - const { email } = req.body - let user - try { - user = await queryByEmail(email) - } catch (err) { - res.status(404).json("No user with that email") - } - const token = usePasswordHashToMakeToken(user) - const url = getPasswordResetURL(user, token) - const emailTemplate = resetPasswordTemplate(user, url) - transporter(emailTemplate,res) - +const sendPasswordResetEmail = async(req, res) => { + const { email } = req.body + let user + try { + user = await queryByEmail(email) + } catch (err) { + res.status(404).json("No user with that email") + } + const token = usePasswordHashToMakeToken(user) + const url = getPasswordResetURL(user, token) + const emailTemplate = resetPasswordTemplate(user, url) + transporter(emailTemplate, res) + } - /** - * Update user reset password on the application - * @static - * @param {object} req - The request object - * @param {object} res - The response object - * @return {object} JSON object representing success - */ +/** + * Update user reset password on the application + * @static + * @param {object} req - The request object + * @param {object} res - The response object + * @return {object} JSON object representing success + */ - const receiveNewPassword = (req, res) => { - const { userId, token } = req.params - const { password } = req.body +const receiveNewPassword = (req, res) => { + const { userId, token } = req.params + const { password } = req.body queryById(userId) .then(user => { - const secret = user.password + "-" + user.createdAt - const payload = jwt.decode(token, secret) - if (payload.userId === user.id) { - bcrypt.genSalt(10, function(err, salt) { - if (err) return - bcrypt.hash(password, salt, function(err, hash) { - if (err) return - updatePassword(hash,userId) - .then(() => res.status(202).json("Password changed accepted")) - .catch(err => res.status(500).json(err)) - }) - }) - } + const secret = user.password + "-" + user.createdAt + const payload = jwt.decode(token, secret) + if (payload.userId === user.id) { + bcrypt.genSalt(10, function(err, salt) { + if (err) return + bcrypt.hash(password, salt, function(err, hash) { + if (err) return + updatePassword(hash, userId) + .then(() => res.status(202).json("Password changed accepted")) + .catch(err => res.status(500).json(err)) + }) + }) + } }) .catch(() => { - res.status(404).json("Invalid user") + res.status(404).json("Invalid user") }) } - export default { +export default { sendPasswordResetEmail, receiveNewPassword - } - +} diff --git a/src/routes/api/notifyRoutes.js b/src/routes/api/notifyRoutes.js index 007ae79..83c3bff 100644 --- a/src/routes/api/notifyRoutes.js +++ b/src/routes/api/notifyRoutes.js @@ -1,5 +1,22 @@ -import { Router } from 'express'; +import express from 'express'; import notifyControllers from '../../controllers/notifyControllers'; -import notifyValidator from '../../validation/notifyValidation'; -import authUtils from '../../middlewares/tokenMiddleware'; \ No newline at end of file +import authUtils from '../../middlewares/tokenMiddleware'; + + +const notifyRoutes = express.Router(); + +const { verifyToken } = authUtils; + +const trip = (io = null) => { + const notify = new notifyControllers(io); + const { createNewTravel, getManagerTravel } = notify; + + // Getting the email + notifyRoutes.post('/create_travels', verifyToken, createNewTravel); + notifyRoutes.get('/get_travels/:id', getManagerTravel); + + return notifyRoutes; +}; + +export default trip; diff --git a/src/services/notifyServices.js b/src/services/notifyServices.js new file mode 100644 index 0000000..c319593 --- /dev/null +++ b/src/services/notifyServices.js @@ -0,0 +1,48 @@ +import Model from '../database/models'; + +const { departments, travels, notifications } = Model; + +/** + * + * + * @class notifyService + */ +class notifyServices { + /** + * + * + * @static + * @param {object} newNotification + * @return {object} alreadyCreatedNotification + * @memberof notifyServices + */ + static async createNotification(newNotification) { + try { + const alreadyCreatedNotification = await notifications.create(newNotification); + return alreadyCreatedNotification; + } catch (error) { + return false; + } + } + + /** + * + * @static + * @param {Integer} id + * @param {string} updatePassword + * @returns {Object} users + * @memberof notifyServices + */ + static async getSpecificTravels(email) { + try { + const theTravels = await departments.findOne({ + where: { manager_email: email } + }); + return theTravels; + } catch (error) { + return false; + } + } +} + +export default notifyServices; diff --git a/src/tests/mocks/users.js b/src/tests/mocks/users.js new file mode 100644 index 0000000..d753c2c --- /dev/null +++ b/src/tests/mocks/users.js @@ -0,0 +1,18 @@ +export default { + id: 1674946, + staff_id: 'ABD-111-8209', + first_name: 'Peter', + last_name: 'Chidi', + email: 'petchidi@yahoo.com', + password: 'every125', + dept_id: 15327458, + dob: '2019-08-09', + gender: 'Male', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'processed', + is_active: false, + createdAt: new Date(), + updatedAt: new Date(), +} From 46c79b780883e69817d030b31ef633acc1f17bf6 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Thu, 5 Sep 2019 16:47:14 +0100 Subject: [PATCH 09/23] installing @sendgrid/mail package from npm --- package-lock.json | 71 ++++++++++++++++++++++++++++++++++++++++++++--- package.json | 1 + 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f862f7e..e3d7eaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -864,6 +864,39 @@ "to-fast-properties": "^2.0.0" } }, + "@sendgrid/client": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-6.4.0.tgz", + "integrity": "sha512-GcO+hKXMQiwN0xMGfPITArlj4Nab1vZsrsRLmsJlcXGZV1V1zQC6XuAWJv6MGDd0hr/jKaXmCJ1XMYkxIRQHFw==", + "requires": { + "@sendgrid/helpers": "^6.4.0", + "@types/request": "^2.0.3", + "request": "^2.88.0" + } + }, + "@sendgrid/helpers": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-6.4.0.tgz", + "integrity": "sha512-1dDDXauArHyxwTKFFfWvQpsijmwalyLgwoQJ3FRCssFq1RfqYDgFhRg0Xs3v/IXS2jkKWePSWiPORSR4Sysdpw==", + "requires": { + "chalk": "^2.0.1", + "deepmerge": "^2.1.1" + } + }, + "@sendgrid/mail": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-6.4.0.tgz", + "integrity": "sha512-pVzbqbxhZ4FUN6iSIksRLtyXRPurrcee1i0noPDStDCLlHVwUR+TofeeKIFWGpIvbbk5UR6S6iV/U5ie8Kdblw==", + "requires": { + "@sendgrid/client": "^6.4.0", + "@sendgrid/helpers": "^6.4.0" + } + }, + "@types/caseless": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + }, "@types/chai": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.1.tgz", @@ -893,6 +926,29 @@ "csstype": "^2.2.0" } }, + "@types/request": { + "version": "2.48.2", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.2.tgz", + "integrity": "sha512-gP+PSFXAXMrd5PcD7SqHeUjdGshAI8vKQ3+AvpQr3ht9iQea+59LOKvKITcQI+Lg+1EIkDP6AFSBUJPWG8GDyA==", + "requires": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + }, + "dependencies": { + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, "@types/superagent": { "version": "3.8.7", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-3.8.7.tgz", @@ -902,6 +958,11 @@ "@types/node": "*" } }, + "@types/tough-cookie": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", + "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1869,7 +1930,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -2345,6 +2405,11 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==" + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -4373,8 +4438,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.0", @@ -7711,7 +7775,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } diff --git a/package.json b/package.json index 3c046d2..89d19b0 100755 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", + "@sendgrid/mail": "^6.4.0", "auto-bind": "^2.1.0", "bcrypt": "^3.0.6", "bcryptjs": "^2.4.3", From ebbf9d99d788ebb1d2e4f446a6c6a99c2f294b33 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Sun, 8 Sep 2019 17:30:51 +0100 Subject: [PATCH 10/23] Checking out the socket.io client and server side --- src/controllers/notifyControllers.js | 41 +++++++++++++++++++++++ src/controllers/profile.js | 50 ++++++++++++++++++++++++++++ src/index.js | 10 ++++++ src/routes/api/notifyRoutes.js | 2 +- src/services/notifyServices.js | 48 -------------------------- src/services/websocket.js | 13 ++++++++ src/tests/mocks/users.js | 17 +++------- 7 files changed, 119 insertions(+), 62 deletions(-) create mode 100644 src/controllers/profile.js delete mode 100644 src/services/notifyServices.js create mode 100644 src/services/websocket.js diff --git a/src/controllers/notifyControllers.js b/src/controllers/notifyControllers.js index e69de29..e09ca75 100644 --- a/src/controllers/notifyControllers.js +++ b/src/controllers/notifyControllers.js @@ -0,0 +1,41 @@ +/* eslint-disable import/named */ +/* eslint-disable require-jsdoc */ + +import models from '../models'; + +const { notifications } = models; + + +class NotificationController { + /** + * @param {Object} req + * @param {Object} res + * @returns {Object} the all requests + * @description get all notification + */ + static async getAllNotification(req, res) { + try { + const userId = req.user.id; + const allRequests = await notifications.findAll({ where: { receiver: userId } }); + return res.status(200).json({ status: 200, data: allRequests }); + } catch (error) { + res.status(500).json({ status: 500, error }); + } + } + + static async readAllNotification(req, res) { + try { + const userId = req.user.id; + const allRequestsByUser = await notifications.update({ isRead: true }, { + where: { + receiver: userId + } + }); + return res.status(200).json({ status: 200, data: allRequestsByUser }); + } catch (error) { + res.status(500).json({ status: 500, error }); + } + } +} + +export default NotificationController; diff --git a/src/controllers/profile.js b/src/controllers/profile.js new file mode 100644 index 0000000..3757100 --- /dev/null +++ b/src/controllers/profile.js @@ -0,0 +1,50 @@ +/* eslint-disable import/named */ +/* eslint-disable require-jsdoc */ + +class ProfileController { + /** + * @param {Object} req + * @param {Object} res + * @returns {Object} the new user + * @description register a new client + */ + static async getProfile(req, res) { + const { user_Id } = req.params; + + const message = ` + + + + + + Chat App + + + + +
+

Notify User Trips

+ +
+ + + + + `; + + res.send(message); + } +} + +export default ProfileController; diff --git a/src/index.js b/src/index.js index 47de3fc..6694609 100755 --- a/src/index.js +++ b/src/index.js @@ -134,6 +134,16 @@ server.listen(PORT, () => { debugLog(`Barefoot-Nomad [Backend] Server is running on port ${PORT}`); }); +// Creating the client connection of Socket.io +io.on('connection', (client) => { + logger(`A client connected ${client.id}`); + client.emit('confirmation', 'We are successfully connected'); + + client.on('disconnect', () => { + logger(`A user connected ${client.id}`); + }); +}); + // for testing module.exports = server; // module.exports = app; diff --git a/src/routes/api/notifyRoutes.js b/src/routes/api/notifyRoutes.js index 83c3bff..f8392e1 100644 --- a/src/routes/api/notifyRoutes.js +++ b/src/routes/api/notifyRoutes.js @@ -8,7 +8,7 @@ const notifyRoutes = express.Router(); const { verifyToken } = authUtils; -const trip = (io = null) => { +const trip = (io) => { const notify = new notifyControllers(io); const { createNewTravel, getManagerTravel } = notify; diff --git a/src/services/notifyServices.js b/src/services/notifyServices.js deleted file mode 100644 index c319593..0000000 --- a/src/services/notifyServices.js +++ /dev/null @@ -1,48 +0,0 @@ -import Model from '../database/models'; - -const { departments, travels, notifications } = Model; - -/** - * - * - * @class notifyService - */ -class notifyServices { - /** - * - * - * @static - * @param {object} newNotification - * @return {object} alreadyCreatedNotification - * @memberof notifyServices - */ - static async createNotification(newNotification) { - try { - const alreadyCreatedNotification = await notifications.create(newNotification); - return alreadyCreatedNotification; - } catch (error) { - return false; - } - } - - /** - * - * @static - * @param {Integer} id - * @param {string} updatePassword - * @returns {Object} users - * @memberof notifyServices - */ - static async getSpecificTravels(email) { - try { - const theTravels = await departments.findOne({ - where: { manager_email: email } - }); - return theTravels; - } catch (error) { - return false; - } - } -} - -export default notifyServices; diff --git a/src/services/websocket.js b/src/services/websocket.js new file mode 100644 index 0000000..bd876d2 --- /dev/null +++ b/src/services/websocket.js @@ -0,0 +1,13 @@ +import { io } from '../index'; + +export const eventEmitter = (eventName, data) => { + io.on('connection', (client) => { + client.emit(eventName, data); + }); +}; + +export const onEvent = (eventName, handleEvent) => { + io.on('connection', (client) => { + client.on(eventName, handleEvent); + }); +}; diff --git a/src/tests/mocks/users.js b/src/tests/mocks/users.js index d753c2c..eec7bec 100644 --- a/src/tests/mocks/users.js +++ b/src/tests/mocks/users.js @@ -1,18 +1,9 @@ export default { id: 1674946, staff_id: 'ABD-111-8209', - first_name: 'Peter', - last_name: 'Chidi', - email: 'petchidi@yahoo.com', + first_name: 'Chidi', + last_name: 'Chuks', + email: 'chidiebere_chukwuma@yahoo.com', password: 'every125', dept_id: 15327458, - dob: '2019-08-09', - gender: 'Male', - address: 'Ok. This is my address', - preferred_lang: 'English', - preferred_currency: 'USD', - role: 'processed', - is_active: false, - createdAt: new Date(), - updatedAt: new Date(), -} +}; From 82d0ddc632aa521982a0eb0393279fc90f7be30a Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Tue, 10 Sep 2019 11:29:52 +0100 Subject: [PATCH 11/23] refactoring codes --- src/controllers/index.js | 2 +- src/controllers/notifyControllers.js | 52 +++++-------- src/controllers/profile.js | 4 +- src/controllers/travelControllers.js | 44 +++++++---- .../20190904023213-create-notifications.js | 77 +++++++++++-------- src/database/models/departments.js | 15 ++-- src/database/models/notifications.js | 36 ++++++--- src/index.js | 3 +- src/models/users.js | 76 +++++++++++------- src/routes/api/notifyRoutes.js | 52 ++++++++----- src/routes/api/travelRoute.js | 14 ++++ src/routes/authRoutes.js | 30 ++++---- src/services/deptServices.js | 43 +++++++++++ src/services/emailServices.js | 40 +++++----- src/services/index.js | 15 ++++ src/services/notifyServices.js | 24 ++++++ src/services/travelServices.js | 63 +++++---------- src/tests/mocks/users.js | 3 +- src/utils/email.js | 69 ++++++++--------- 19 files changed, 392 insertions(+), 270 deletions(-) create mode 100644 src/routes/api/travelRoute.js create mode 100644 src/services/deptServices.js create mode 100644 src/services/index.js create mode 100644 src/services/notifyServices.js diff --git a/src/controllers/index.js b/src/controllers/index.js index 1941fd2..0aa9228 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -2,4 +2,4 @@ import { authControllers } from './authControllers'; export { authControllers -}; +}; \ No newline at end of file diff --git a/src/controllers/notifyControllers.js b/src/controllers/notifyControllers.js index e09ca75..2d07bff 100644 --- a/src/controllers/notifyControllers.js +++ b/src/controllers/notifyControllers.js @@ -1,41 +1,31 @@ /* eslint-disable import/named */ /* eslint-disable require-jsdoc */ -import models from '../models'; +import models from '../database/models'; const { notifications } = models; -class NotificationController { - /** - * @param {Object} req - * @param {Object} res - * @returns {Object} the all requests - * @description get all notification - */ - static async getAllNotification(req, res) { - try { - const userId = req.user.id; - const allRequests = await notifications.findAll({ where: { receiver: userId } }); - return res.status(200).json({ status: 200, data: allRequests }); - } catch (error) { - res.status(500).json({ status: 500, error }); - } +export const getAllNotification = async(req, res) => { + try { + const user_id = req.users.id; + const allRequests = await notifications.findAll({ where: { receiver: user_id } }); + return res.status(200).json({ status: 200, data: allRequests }); + } catch (error) { + res.status(500).json({ status: 500, error }); } +}; - static async readAllNotification(req, res) { - try { - const userId = req.user.id; - const allRequestsByUser = await notifications.update({ isRead: true }, { - where: { - receiver: userId - } - }); - return res.status(200).json({ status: 200, data: allRequestsByUser }); - } catch (error) { - res.status(500).json({ status: 500, error }); - } +export const readAllNotification = async(req, res) => { + try { + const user_id = req.user.id; + const allRequestsByUser = await notifications.update({ is_read: true }, { + where: { + receiver: user_id + } + }); + return res.status(200).json({ status: 200, data: allRequestsByUser }); + } catch (error) { + res.status(500).json({ status: 500, error }); } -} - -export default NotificationController; +}; diff --git a/src/controllers/profile.js b/src/controllers/profile.js index 3757100..7362f1e 100644 --- a/src/controllers/profile.js +++ b/src/controllers/profile.js @@ -27,14 +27,14 @@ class ProfileController { div.appendChild(para); }; const socket = io(); - socket.on('tripCreated${user_Id}', (data) => { + socket.on('travelCreated${user_id}', (data) => { appendMessage(data); })
-

Notify User Trips

+

Notify User Travels

diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index 0910625..f1d704b 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,29 +1,39 @@ import { - onewayTripService, - showManagerPendingAppr, + onewayTripService, + showManagerPendingAppr, } from '../services/travelServices'; import { successResponseWithData, errorResponse } from '../utils/response'; import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; +const { oneWayTripService } = travelServices; +const { successResponseWithData, errorResponse } = response; + export default { - createOneWayTrip: async (req, res) => { - try { - const { - origin, destination, departure_date, travel_purpose -} = req.body; - const userId = req.userData.id; + createOneWayTrip: async(req, res) => { + try { + const { + origin, + destination, + departure_date, + travel_purpose + } = req.body; + const userId = req.userData.id; - const travelObj = { - user_id: userId, origin, destination, departure_date, travel_purpose -}; + const travelObj = { + user_id: userId, + origin, + destination, + departure_date, + travel_purpose + }; - const data = await onewayTripService(travelObj); + const data = await oneWayTripService(travelObj); - successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, + successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } + }, }; diff --git a/src/database/migrations/20190904023213-create-notifications.js b/src/database/migrations/20190904023213-create-notifications.js index 4d26913..2fcf3e2 100644 --- a/src/database/migrations/20190904023213-create-notifications.js +++ b/src/database/migrations/20190904023213-create-notifications.js @@ -1,32 +1,47 @@ module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.createTable('notifications', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - travel_id: { - type: Sequelize.INTEGER - }, - manager_email: { - type: Sequelize.TEXT - }, - read_status: { - type: Sequelize.BOOLEAN - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }); - }, - down: (queryInterface, Sequelize) => { - return queryInterface.dropTable('notifications'); - } -}; \ No newline at end of file + up: (queryInterface, Sequelize) => queryInterface.createTable('notifications', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + travel_id: { + allowNull: false, + type: Sequelize.INTEGER + }, + line_manager_id: { + allowNull: false, + type: Sequelize.INTEGER + }, + line_manager_email: { + allowNull: false, + type: Sequelize.STRING + }, + receiver: { + allowNull: false, + type: Sequelize.INTEGER + }, + content: { + allowNull: false, + type: Sequelize.STRING + }, + is_read: { + allowNull: false, + type: Sequelize.BOOLEAN + }, + type: { + allowNull: false, + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }), + down: (queryInterface) => queryInterface.dropTable('notifications') +}; diff --git a/src/database/models/departments.js b/src/database/models/departments.js index 81bbeb9..5657415 100644 --- a/src/database/models/departments.js +++ b/src/database/models/departments.js @@ -2,16 +2,17 @@ module.exports = (sequelize, DataTypes) => { const departments = sequelize.define('departments', { dept_name: DataTypes.TEXT, line_manager: DataTypes.TEXT, + line_manager_email: DataTypes.TEXT, + line_manager_id: DataTypes.INTEGER, manager_staff_id: DataTypes.STRING, - manager_email: DataTypes.TEXT }, {}); - departments.associate = (models) => { - // associations can be defined here - // departments.hasMany(models.notifications, { - // foreignKey: 'manager_email' - // }); - }; + // departments.associate = (models) => { + // // associations can be defined here + // // departments.hasMany(models.notifications, { + // // foreignKey: 'manager_email' + // // }); + // }; return departments; }; \ No newline at end of file diff --git a/src/database/models/notifications.js b/src/database/models/notifications.js index 8466eda..84c1ab6 100644 --- a/src/database/models/notifications.js +++ b/src/database/models/notifications.js @@ -1,17 +1,29 @@ module.exports = (sequelize, DataTypes) => { const notifications = sequelize.define('notifications', { + user_id: DataTypes.INTEGER, travel_id: DataTypes.INTEGER, - manager_email: DataTypes.TEXT, - read_status: DataTypes.BOOLEAN + is_read: DataTypes.TEXT, + line_manager_email: DataTypes.TEXT, + line_manager_id: DataTypes.INTEGER, + receiver: { + type: DataTypes.INTEGER, + allowNull: false, + validate: { + notEmpty: { + msg: 'notification receiver cannot be empty' + } + } + }, + content: { + type: DataTypes.STRING, + allowNull: false, + validate: { + notEmpty: { + msg: 'notification content cannot be empty' + } + } + }, }, {}); - notifications.associate = (models) => { - // associations can be defined here - notifications.belongsTo(models.travels, { - foreignKey: 'travel_id' - }); - notifications.hasMany(models.departments, { - foreignKey: 'manager_email' - }); - }; + return notifications; -}; \ No newline at end of file +}; diff --git a/src/index.js b/src/index.js index 6694609..b409e09 100755 --- a/src/index.js +++ b/src/index.js @@ -16,7 +16,6 @@ import statusCode from './utils/statusCode'; import routes from './routes'; - dotenv.config(); const debugLog = debug('web-app'); @@ -146,4 +145,4 @@ io.on('connection', (client) => { // for testing module.exports = server; -// module.exports = app; +// module.exports = app; \ No newline at end of file diff --git a/src/models/users.js b/src/models/users.js index ff0bdfa..dada405 100644 --- a/src/models/users.js +++ b/src/models/users.js @@ -1,35 +1,53 @@ import { hashSync, genSaltSync } from 'bcryptjs'; -module.exports = (sequelize, DataTypes) => { - const salt = genSaltSync(10); - const users = sequelize.define('users', { - staff_id: DataTypes.STRING, - first_name: DataTypes.TEXT, - last_name: DataTypes.TEXT, - email: DataTypes.TEXT, - password: DataTypes.TEXT, - dept_id: DataTypes.INTEGER, - dob: DataTypes.DATE, - gender: DataTypes.TEXT, - address: DataTypes.TEXT, - preferred_lang: DataTypes.TEXT, - preferred_currency: DataTypes.TEXT, - role: DataTypes.TEXT, - is_active: DataTypes.BOOLEAN - }, {}); +export default (sequelize, DataTypes) => { + const salt = genSaltSync(10); + const users = sequelize.define('users', { + staff_id: DataTypes.STRING, + first_name: DataTypes.TEXT, + last_name: DataTypes.TEXT, + email: DataTypes.TEXT, + password: DataTypes.TEXT, + dept_id: DataTypes.INTEGER, + dob: DataTypes.DATE, + gender: DataTypes.TEXT, + gmail: DataTypes.STRING, + facebook: DataTypes.STRING, + address: DataTypes.TEXT, + preferred_lang: DataTypes.TEXT, + preferred_currency: DataTypes.TEXT, + role: { + type: DataTypes.ENUM, + values: [ + 'super_admin', + 'travel_admin', + 'travel_team_member', + 'manager', + 'requester' + ], + required: false + }, + is_active: DataTypes.BOOLEAN + }, {}); - users.associate = (models) => { - users.belongsTo(models.departments, { - foreignKey: 'dept_id' - }); + users.associate = (models) => { + users.belongsTo(models.departments, { + foreignKey: 'dept_id' + }); - users.hasMany(models.travel_requests, { - foreignKey: 'user_id' + users.hasMany(models.travel_requests, { + foreignKey: 'user_id' + }); + }; + users.beforeCreate((incomingUser) => { + incomingUser.password = hashSync(incomingUser.password, salt); }); - }; - users.beforeCreate((incomingUser) => { - incomingUser.password = hashSync(incomingUser.password, salt); - }); - return users; -}; + << + << << < HEAD + return users; +}; === +=== = +return users; +}; >>> +>>> > refactoring codes diff --git a/src/routes/api/notifyRoutes.js b/src/routes/api/notifyRoutes.js index f8392e1..f0ef90d 100644 --- a/src/routes/api/notifyRoutes.js +++ b/src/routes/api/notifyRoutes.js @@ -1,22 +1,36 @@ -import express from 'express'; - -import notifyControllers from '../../controllers/notifyControllers'; -import authUtils from '../../middlewares/tokenMiddleware'; - - -const notifyRoutes = express.Router(); - -const { verifyToken } = authUtils; - -const trip = (io) => { - const notify = new notifyControllers(io); - const { createNewTravel, getManagerTravel } = notify; - - // Getting the email - notifyRoutes.post('/create_travels', verifyToken, createNewTravel); - notifyRoutes.get('/get_travels/:id', getManagerTravel); - - return notifyRoutes; +import { Router } from 'express'; +import { NotificationController } from '../../controllers'; +import profileController from '../../controllers/profile'; +import tokenMiddleware from '../../middlewares/tokenMiddleware'; + + +const router = Router(); +const { getProfile } = profileController; +const { getToken, verifyToken } = tokenMiddleware; + +// api/v1/notification is already prepended to the request +router.get('/notify', NotificationController.getAllNotification); +router.patch('/notify', NotificationController.readAllNotification); + + +export const foo = (io = null) => { + router.use('/auth', auth); + router.get('/profile/:user_id', getProfile); + router.use('/onewaytrip', getToken, verifyToken, travelRoute(io)); + + router.use((err, req, res, next) => { + if (err.name === 'Validation Error') { + return res.status(422).json({ + errors: Object.keys(err.errors).reduce((errors, key) => { + errors[key] = err.errors[key].message; + return errors; + }, {}) + }); + } + return next(err); + }); + return router; }; + export default trip; diff --git a/src/routes/api/travelRoute.js b/src/routes/api/travelRoute.js new file mode 100644 index 0000000..6336f37 --- /dev/null +++ b/src/routes/api/travelRoute.js @@ -0,0 +1,14 @@ +import { Router } from 'express'; + +import travelControllers from '../../controllers/travelControllers'; +import travelValidator from '../../validation/travelValidation'; +import { getToken, verifyToken } from '../../middlewares/tokenMiddleware'; + +const route = Router(); +const { createOneWayTrip, pendingManagerApproval } = travelControllers; +const { validateTravelRequest, validateResult } = travelValidator; + +// handles the api home route... +route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); + +export default route; \ No newline at end of file diff --git a/src/routes/authRoutes.js b/src/routes/authRoutes.js index 71000d1..255de54 100644 --- a/src/routes/authRoutes.js +++ b/src/routes/authRoutes.js @@ -10,7 +10,7 @@ const { sendPasswordResetEmail, receiveNewPassword } = resetPassword; const route = Router(); -const { signup, fbgooglesignup, login, logout} = authControllers; +const { signup, fbgooglesignup, login, logout } = authControllers; const { validateLogin, validateSignup, validateResult } = authValidator; // handles the api home route... @@ -19,24 +19,24 @@ route.post('/auth/signup', validateSignup, validateResult, signup); // handles social media authentication route.get('/auth/signup/facebook', - passport.authenticate('facebook')); + passport.authenticate('facebook')); route.get('/auth/signup/facebook/callback', - passport.authenticate('facebook', { - failureRedirect: '/auth/signup', - successRedirect: '/requests', - })); + passport.authenticate('facebook', { + failureRedirect: '/auth/signup', + successRedirect: '/requests', + })); route.get('/auth/signup/google', - passport.authenticate('google', { scope: ['profile', 'email'] })); + passport.authenticate('google', { scope: ['profile', 'email'] })); route.get('/auth/signup/google/callback', - passport.authenticate('google', { - failureRedirect: '/auth/signup', - successRedirect: '/requests', - })); + passport.authenticate('google', { + failureRedirect: '/auth/signup', + successRedirect: '/requests', + })); - // route path subject to change +// route path subject to change route.get('/requests', fbgooglesignup); // handles the sign in request by email and password.. @@ -45,8 +45,8 @@ route.post('/auth/login', validateLogin, validateResult, login); route.post('/auth/logout', getToken, verifyToken, logout); -route.post('/forgot',sendPasswordResetEmail); +route.post('/forgot', sendPasswordResetEmail); -route.post('/receive_new_password/:userId/:token',receiveNewPassword); +route.post('/receive_new_password/:userId/:token', receiveNewPassword); -export default route; +export default route; \ No newline at end of file diff --git a/src/services/deptServices.js b/src/services/deptServices.js new file mode 100644 index 0000000..51482d0 --- /dev/null +++ b/src/services/deptServices.js @@ -0,0 +1,43 @@ +import models from '../database/models'; + +const { departments } = models; + + +/** + * Helper function to find a user by email + * @param {String} email - line-manager's email + * @returns {Promise} - sequelize response + */ +export const findManagerByEmail = async(email) => { + try { + return await departments.findOne({ where: { line_manager_email: email } }); + } catch (err) { + throw err; + } + } + /** + * Helper function to find a user by id + * @param {String} id - user's id + * @returns {Promise} - sequelize response + */ +export const findDeptById = async(id) => { + try { + return await users.findOne({ where: { id } }); + } catch (err) { + throw err + } +} + +/** + * Helper function to update a user password + * @param {String} hash - user's password + * @param {String} id - user's id + * @returns {Promise} - sequelize response + */ +export const updatePassword = async(hash, id) => { + try { + return await users.update(hash, { where: { id } }); + } catch (err) { + throw err + } +} \ No newline at end of file diff --git a/src/services/emailServices.js b/src/services/emailServices.js index 1aa1fee..bf97f2b 100644 --- a/src/services/emailServices.js +++ b/src/services/emailServices.js @@ -7,26 +7,26 @@ const { users } = models; * Helper function to find a user by email * @param {String} email - user's email * @returns {Promise} - sequelize response -*/ + */ const queryByEmail = async (email) => { - try{ - return await users.findOne({ where: { email } }); - }catch(err){ - throw err; + try { + return await users.findOne({ where: { email } }); + } catch (err) { + throw err; } -} +}; /** - * Helper function to find a user by id - * @param {String} id - user's id - * @returns {Promise} - sequelize response - */ + * Helper function to find a user by id + * @param {String} id - user's id + * @returns {Promise} - sequelize response + */ const queryById = async (id) => { - try{ + try { return await users.findOne({ where: { id } }); - }catch(err){ - throw err + } catch (err) { + throw err; } -} +}; /** * Helper function to update a user password @@ -34,16 +34,16 @@ const queryById = async (id) => { * @param {String} id - user's id * @returns {Promise} - sequelize response */ -const updatePassword = async (hash, id) =>{ - try{ +const updatePassword = async (hash, id) => { + try { return await users.update(hash, { where: { id } }); - }catch(err){ - throw err + } catch (err) { + throw err; } -} +}; export default { queryByEmail, queryById, updatePassword -} +}; diff --git a/src/services/index.js b/src/services/index.js new file mode 100644 index 0000000..32ec711 --- /dev/null +++ b/src/services/index.js @@ -0,0 +1,15 @@ +const message = ` + + + + + + + Document + + + +

Hi, your first message

+ + +`; \ No newline at end of file diff --git a/src/services/notifyServices.js b/src/services/notifyServices.js new file mode 100644 index 0000000..137e1ef --- /dev/null +++ b/src/services/notifyServices.js @@ -0,0 +1,24 @@ +import Model from '../database/models'; + +const { notifications } = Model; + +// eslint-disable-next-line import/prefer-default-export +export const createNotification = async(notifications) => { + try { + const makeNotification = await notifications.create(notifications); + return makeNotification; + } catch (error) { + return false; + } +}; + +export const getSpecificTrips = async(id) => { + try { + const theTravels = await notifications.findOne({ + where: { line_manager_id: id } + }); + return theTravels; + } catch (error) { + return false; + } +} \ No newline at end of file diff --git a/src/services/travelServices.js b/src/services/travelServices.js index 076c952..a22043b 100644 --- a/src/services/travelServices.js +++ b/src/services/travelServices.js @@ -5,51 +5,24 @@ import models from '../models'; const { travel_requests, departments, users } = models; -export const onewayTripService = async (travelObj) => { - try { - return await travel_requests.create(travelObj); - } catch (err) { - throw err; - } -}; - -export const findTravelById = async (id) => { - try { - return await travel_requests.findOne({ - attributes: ['id', 'user_id'], - where: { id }, - }); - } catch (err) { - throw err; - } -}; - -export const showManagerPendingAppr = async (manager) => { - try { - return await travel_requests.findAll({ - where: { - approval_status: 'pending', - }, - include: [ - { - model: users, - attributes: ['first_name', 'last_name'], - include: [ - { - model: departments, - attributes: ['dept_name', 'line_manager'], - where: { - line_manager: manager, - }, - }, - ], - }, - ], - raw: true, - }); - } catch (err) { - throw err; - } +export default { + oneWayTripService: async(travelObj) => { + try { + return await travels.create(travelObj); + } catch (err) { + throw err; + } + }, + findTravelById: async(id) => { + try { + return await travels.findOne({ + attributes: ['id'], + where: { id }, + }); + } catch (err) { + throw err; + } + }, }; export const showUsertravelsStatus = async (userId) => { diff --git a/src/tests/mocks/users.js b/src/tests/mocks/users.js index eec7bec..61a3f1a 100644 --- a/src/tests/mocks/users.js +++ b/src/tests/mocks/users.js @@ -6,4 +6,5 @@ export default { email: 'chidiebere_chukwuma@yahoo.com', password: 'every125', dept_id: 15327458, -}; + role: 'line_manager' +}; \ No newline at end of file diff --git a/src/utils/email.js b/src/utils/email.js index b67855b..d7e8961 100644 --- a/src/utils/email.js +++ b/src/utils/email.js @@ -1,51 +1,44 @@ require('dotenv').config(); const sendGrid = require('sendgrid').mail; -const sg = require('sendgrid')(process.env.SENDGRID_API); +const sg = require('sendgrid')(process.env.SENDGRID_API_KEY); let hostUrl; const devHostUrl = 'http://localhost:5000'; const prodHostUrl = 'https://archangel-backend-staging.herokuapp.com/'; const sendVerificationEmail = (to) => { - if (process.env.NODE_ENV === 'development') { - hostUrl = devHostUrl; - } else { - hostUrl = prodHostUrl; - } + if (process.env.NODE_ENV === 'development') { + hostUrl = devHostUrl; + } else { + hostUrl = prodHostUrl; + } const request = sg.emptyRequest({ - method: "POST", - path: "/v3/mail/send", - body: { - personalizations: [ - { - to: [ - { - email: to - } - ], - subject:"Verify Your Email" - } - ], - from: { - email: "barefoot.nomad.archangel@gmail.com" - }, - content: [ - { - type: 'text/plain', - value: `Click on this link to verify your email ${hostUrl}` - } - ] - } + method: "POST", + path: "/v3/mail/send", + body: { + personalizations: [{ + to: [{ + email: to + }], + subject: "Verify Your Email" + }], + from: { + email: "barefoot.nomad.archangel@gmail.com" + }, + content: [{ + type: 'text/plain', + value: `Click on this link to verify your email ${hostUrl}` + }] + } }); return new Promise((resolve, reject) => { - sg.API(request, (error, response) => { - if (error) { - return reject(error); - } - else { - return resolve(response); - } - }); + sg.API(request, (error, response) => { + if (error) { + return reject(error); + } else { + return resolve(response); + } + }); }); - }; +}; export default sendVerificationEmail; From 4ebc6b70d0bbb22bd206337ab16b85ed1aa6ed8f Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Tue, 10 Sep 2019 19:13:13 +0100 Subject: [PATCH 12/23] edited the entry point and routes to test with postman --- .env.sample | 2 + src/controllers/{profile.js => client.js} | 19 ++- src/controllers/index.js | 5 +- src/controllers/notifyControllers.js | 2 + src/controllers/travelControllers.js | 22 ++- .../migrations/20190823135448-create-users.js | 157 ++++++++---------- src/index.js | 8 +- src/models/users.js | 11 +- src/routes/api/notifyRoutes.js | 57 +++---- src/routes/authRoutes.js | 17 +- src/routes/index.js | 8 +- src/services/authServices.js | 116 +++++++------ src/services/index.js | 15 -- src/services/websocket.js | 42 +++-- src/utils/messageUtils.js | 105 ++++++------ src/utils/notifyEmailUtils.js | 9 + src/utils/statusCode.js | 13 +- 17 files changed, 330 insertions(+), 278 deletions(-) rename src/controllers/{profile.js => client.js} (73%) delete mode 100644 src/services/index.js create mode 100644 src/utils/notifyEmailUtils.js diff --git a/.env.sample b/.env.sample index 0928421..37d3b13 100644 --- a/.env.sample +++ b/.env.sample @@ -30,3 +30,5 @@ EMAIL_PASS SENDGRID_API +SENDGRID_API_KEY + diff --git a/src/controllers/profile.js b/src/controllers/client.js similarity index 73% rename from src/controllers/profile.js rename to src/controllers/client.js index 7362f1e..a683542 100644 --- a/src/controllers/profile.js +++ b/src/controllers/client.js @@ -1,15 +1,15 @@ /* eslint-disable import/named */ /* eslint-disable require-jsdoc */ -class ProfileController { +class ClientController { /** * @param {Object} req * @param {Object} res * @returns {Object} the new user * @description register a new client */ - static async getProfile(req, res) { - const { user_Id } = req.params; + static async getClient(req, res) { + const { user_id } = req.params; const message = ` @@ -29,7 +29,11 @@ class ProfileController { const socket = io(); socket.on('travelCreated${user_id}', (data) => { appendMessage(data); - }) + }); + socket.on('here', (data) => { + console.log(data); + appendMessage(data); + }); @@ -47,4 +51,9 @@ class ProfileController { } } -export default ProfileController; +<< +<< << < HEAD: src / controllers / profile.js +export default ProfileController; === +=== = +export default ClientController; >>> +>>> > edited the entry point and routes to test with postman: src / controllers / client.js diff --git a/src/controllers/index.js b/src/controllers/index.js index 0aa9228..2306abd 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -1,5 +1,6 @@ import { authControllers } from './authControllers'; export { - authControllers -}; \ No newline at end of file + authControllers, + notifyContollers +}; diff --git a/src/controllers/notifyControllers.js b/src/controllers/notifyControllers.js index 2d07bff..614aeab 100644 --- a/src/controllers/notifyControllers.js +++ b/src/controllers/notifyControllers.js @@ -1,7 +1,9 @@ /* eslint-disable import/named */ /* eslint-disable require-jsdoc */ +// import jwt from 'jsonwebtoken'; import models from '../database/models'; +// import response from '../utils/response'; const { notifications } = models; diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index f1d704b..4e56fcb 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,18 +1,25 @@ -import { - onewayTripService, - showManagerPendingAppr, -} from '../services/travelServices'; -import { successResponseWithData, errorResponse } from '../utils/response'; - +import socketEmission from '../services/websocket'; +import authServices from '../services/authServices'; +import travelServices from '../services/travelServices'; import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; +import sendVerificationEmail from '../utils/email'; const { oneWayTripService } = travelServices; const { successResponseWithData, errorResponse } = response; +const { findUserById } = authServices; + +const { emission } = socketEmission; export default { createOneWayTrip: async(req, res) => { try { + const { id } = req.token; + const aUser = await findUserById(id); + const { email, dept_id } = aUser; + if (!dept_id) { + errorResponse(res, statusCode.badRequest, message.lineManager); + } const { origin, destination, @@ -31,6 +38,9 @@ export default { const data = await oneWayTripService(travelObj); + const emailVerify = await sendVerificationEmail(email, + 'Travel Confirmation', message.notifyUser); + emission('here', 'we made it'); successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); } catch (err) { errorResponse(res, statusCode.serverError, err); diff --git a/src/database/migrations/20190823135448-create-users.js b/src/database/migrations/20190823135448-create-users.js index d8f9e0b..1ca96f7 100644 --- a/src/database/migrations/20190823135448-create-users.js +++ b/src/database/migrations/20190823135448-create-users.js @@ -1,87 +1,76 @@ module.exports = { - up: function up(queryInterface, Sequelize) { - return queryInterface.createTable('users', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - staff_id: { - type: Sequelize.STRING, - unique: true, - }, - first_name: { - type: Sequelize.TEXT, - allowNull: false, - validate: { - msg: 'Please provide your First Name' + up: (queryInterface, Sequelize) => queryInterface.createTable('users', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + staff_id: { + type: Sequelize.STRING, + unique: true, + }, + first_name: { + type: Sequelize.TEXT, + allowNull: false, + validate: { + msg: 'Please provide your First Name' + } + }, + last_name: { + type: Sequelize.TEXT, + allowNull: false, + validate: { + msg: 'Please provide your Last Name' + } + }, + email: { + type: Sequelize.TEXT, + unique: true, + allowNull: true, + validate: { + msg: 'Please provide a valid email address' + } + }, + password: { + type: Sequelize.TEXT, + allowNull: true, + validate: { + msg: 'Please provide a password' + } + }, + dept_id: { + type: Sequelize.INTEGER, + }, + dob: { + type: Sequelize.DATE, + }, + gender: { + type: Sequelize.TEXT, + }, + address: { + type: Sequelize.TEXT, + }, + preferred_lang: { + type: Sequelize.TEXT, + }, + preferred_currency: { + type: Sequelize.TEXT, + }, + role: { + type: Sequelize.TEXT, + }, + is_active: { + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, } - }, - last_name: { - type: Sequelize.TEXT, - allowNull: false, - validate: { - msg: 'Please provide your Last Name' - } - }, - email: { - type: Sequelize.TEXT, - unique: true, - allowNull: true, - validate: { - msg: 'Please provide a valid email address' - } - }, - password: { - type: Sequelize.TEXT, - allowNull: true, - validate: { - msg: 'Please provide a password' - } - }, - dept_id: { - type: Sequelize.INTEGER, - references: { - model: { - tableName: 'departments', - }, - key: 'id' - } - }, - dob: { - type: Sequelize.DATE, - }, - gender: { - type: Sequelize.TEXT, - }, - address: { - type: Sequelize.TEXT, - }, - preferred_lang: { - type: Sequelize.TEXT, - }, - preferred_currency: { - type: Sequelize.TEXT, - }, - role: { - type: Sequelize.TEXT, - }, - is_active: { - type: Sequelize.BOOLEAN, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, - } - }); - }, - // eslint-disable-next-line no-unused-vars - down: function down(queryInterface, Sequelize) { - return queryInterface.dropTable('users'); - } + }), + down: (queryInterface, Sequelize) => queryInterface.dropTable('users') }; diff --git a/src/index.js b/src/index.js index b409e09..b318b7b 100755 --- a/src/index.js +++ b/src/index.js @@ -8,12 +8,12 @@ import cors from 'cors'; import methodOverride from 'method-override'; import http from 'http'; import socketIo from 'socket.io'; - import { fbStrategy, googleStrategy } from './config/passport'; import message from './utils/messageUtils'; import response from './utils/response'; import statusCode from './utils/statusCode'; -import routes from './routes'; +import routes from './routes/api'; +import socketEmission from './services/websocket'; dotenv.config(); @@ -22,7 +22,9 @@ const debugLog = debug('web-app'); // Create global app object const app = express(); const server = http.createServer(app); + const io = socketIo(server); +const emission = new socketEmission(io); const PORT = process.env.PORT || 5000; @@ -145,4 +147,4 @@ io.on('connection', (client) => { // for testing module.exports = server; -// module.exports = app; \ No newline at end of file +// module.exports = app; diff --git a/src/models/users.js b/src/models/users.js index dada405..714d829 100644 --- a/src/models/users.js +++ b/src/models/users.js @@ -17,7 +17,7 @@ export default (sequelize, DataTypes) => { preferred_lang: DataTypes.TEXT, preferred_currency: DataTypes.TEXT, role: { - type: DataTypes.ENUM, + type: DataTypes.TEXT, values: [ 'super_admin', 'travel_admin', @@ -44,10 +44,7 @@ export default (sequelize, DataTypes) => { }); << - << << < HEAD + << + << < HEAD return users; -}; === -=== = -return users; -}; >>> ->>> > refactoring codes +}; diff --git a/src/routes/api/notifyRoutes.js b/src/routes/api/notifyRoutes.js index f0ef90d..e5fb232 100644 --- a/src/routes/api/notifyRoutes.js +++ b/src/routes/api/notifyRoutes.js @@ -1,36 +1,33 @@ import { Router } from 'express'; -import { NotificationController } from '../../controllers'; -import profileController from '../../controllers/profile'; -import tokenMiddleware from '../../middlewares/tokenMiddleware'; +// import { notifyControllers } from '../../controllers'; +import ClientController from '../../controllers/client'; +// import tokenMiddleware from '../../middlewares/tokenMiddleware'; const router = Router(); -const { getProfile } = profileController; -const { getToken, verifyToken } = tokenMiddleware; +const { getClient } = ClientController; +// const { getToken, verifyToken } = tokenMiddleware; // api/v1/notification is already prepended to the request -router.get('/notify', NotificationController.getAllNotification); -router.patch('/notify', NotificationController.readAllNotification); - - -export const foo = (io = null) => { - router.use('/auth', auth); - router.get('/profile/:user_id', getProfile); - router.use('/onewaytrip', getToken, verifyToken, travelRoute(io)); - - router.use((err, req, res, next) => { - if (err.name === 'Validation Error') { - return res.status(422).json({ - errors: Object.keys(err.errors).reduce((errors, key) => { - errors[key] = err.errors[key].message; - return errors; - }, {}) - }); - } - return next(err); - }); - return router; -}; - - -export default trip; +// router.get('/notify', notificationController.getAllNotification); +// router.patch('/notify', notificationController.readAllNotification); + + +// router.use('/auth', auth); +router.get('/profile/:user_id', getClient); +// router.use('/onewaytrip', getToken, verifyToken); + +router.use((err, req, res, next) => { + if (err.name === 'Validation Error') { + return res.status(422).json({ + errors: Object.keys(err.errors).reduce((errors, key) => { + errors[key] = err.errors[key].message; + return errors; + }, {}) + }); + } + return next(err); +}); + + +export default router; diff --git a/src/routes/authRoutes.js b/src/routes/authRoutes.js index 255de54..bfdf5c8 100644 --- a/src/routes/authRoutes.js +++ b/src/routes/authRoutes.js @@ -1,16 +1,21 @@ import { Router } from 'express'; import passport from 'passport'; -import authControllers from '../controllers/authControllers'; -import resetPassword from '../controllers/resetPassword'; -import authValidator from '../validation/authValidation'; -import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; +import authControllers from '../../controllers/authControllers'; +import resetPassword from '../../controllers/resetPassword'; +import authValidator from '../../validation/authValidation'; +import tokenMiddlewares from '../../middlewares/tokenMiddleware'; const { sendPasswordResetEmail, receiveNewPassword } = resetPassword; const route = Router(); -const { signup, fbgooglesignup, login, logout } = authControllers; +const { + signup, + fbgooglesignup, + login, + logout +} = authControllers; const { validateLogin, validateSignup, validateResult } = authValidator; // handles the api home route... @@ -49,4 +54,4 @@ route.post('/forgot', sendPasswordResetEmail); route.post('/receive_new_password/:userId/:token', receiveNewPassword); -export default route; \ No newline at end of file +export default route; diff --git a/src/routes/index.js b/src/routes/index.js index 727e9ea..59c0f32 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -3,8 +3,10 @@ import travel from './travelRoute'; import comment from './commentRoutes'; + export default (prefix, app) => { - app.use(prefix, auth); - app.use(prefix, travel); - app.use(prefix, comment); + app.use(prefix, auth); + app.use(prefix, travel); + app.use(prefix, comment); + app.use(prefix, notify); }; diff --git a/src/services/authServices.js b/src/services/authServices.js index 3d55d0d..474bb6d 100644 --- a/src/services/authServices.js +++ b/src/services/authServices.js @@ -6,54 +6,72 @@ import models from '../models'; const { users, blacklists } = models; -export const signupService = async (userObj) => { - try { - const userRes = await users.create(userObj); - - return userRes; - } catch (err) { - throw err; - } -}; -// subject to changes -export const findUserById = async (id) => { - try { - return await users.findOne({ - where: { id }, - }); - } catch (err) { - throw err; - } -}; +export default { + signupService: async(userObj) => { + try { + const userRes = await users.create(userObj); + + return userRes; + + + } catch (err) { + throw err; + } + }, + // subject to changes + findUserById: async(userId) => { + try { + return await users.findAll({ + where: { + id: userId + }, + }); + } catch (err) { + throw err; + } + }, + findUserById: async(id) => { + try { + return await users + .findOne({ + where: { id }, + }); + } catch (err) { + throw err; + } + }, + + updateUserById: async(hash, id) => { + try { + return await users + .findOne(hash, { + where: { id }, + }); + } catch (err) { + throw err; + } + }, + /** + *This function will get a user by email address... + *@param {String} email - the user's email + *@return {Promise} - response of sequelize + */ + findUserByEmail: (email) => users.findOne({ where: { email } }), + + /** + *This function will compare the password supplied by the user with the one in the database... + *@param {String} password - the user's password supplied + *@param {String} hashedPassword - the user's password in database + *@return {boolean} - response of bcrypt hashing + */ + comparePassword: (password, hashedPassword) => compareSync(password, hashedPassword), + + logoutService: async(token) => { + try { + return await blacklists.create({ expired_tokens: token }) + } catch (err) { + throw err; + } + } -export const updateUserById = async (hash, id) => { - try { - return await users.findOne(hash, { - where: { id }, - }); - } catch (err) { - throw err; - } -}; -/** - *This function will get a user by email address... - *@param {String} email - the user's email - *@return {Promise} - response of sequelize - */ -export const findUserByEmail = (email) => users.findOne({ where: { email } }); - -/** - *This function will compare the password supplied by the user with the one in the database... - *@param {String} password - the user's password supplied - *@param {String} hashedPassword - the user's password in database - *@return {boolean} - response of bcrypt hashing - */ -export const comparePassword = (password, hashedPassword) => compareSync(password, hashedPassword); - -export const logoutService = async (token) => { - try { - return await blacklists.create({ expired_tokens: token }); - } catch (err) { - throw err; - } }; diff --git a/src/services/index.js b/src/services/index.js deleted file mode 100644 index 32ec711..0000000 --- a/src/services/index.js +++ /dev/null @@ -1,15 +0,0 @@ -const message = ` - - - - - - - Document - - - -

Hi, your first message

- - -`; \ No newline at end of file diff --git a/src/services/websocket.js b/src/services/websocket.js index bd876d2..562df72 100644 --- a/src/services/websocket.js +++ b/src/services/websocket.js @@ -1,13 +1,33 @@ -import { io } from '../index'; +import autoBind from 'auto-bind'; -export const eventEmitter = (eventName, data) => { - io.on('connection', (client) => { - client.emit(eventName, data); - }); -}; +let socketPlug = null; +/** + * + * + * @class socketEmission + */ +class socketEmission { + // eslint-disable-next-line valid-jsdoc + /** + *Creates an instance of socketEmission. + @param {} io + * @memberof socketEmission + */ + constructor(io) { + socketPlug = io; + autoBind(this); + } -export const onEvent = (eventName, handleEvent) => { - io.on('connection', (client) => { - client.on(eventName, handleEvent); - }); -}; + /** + *@description A function that handles multicity travel request by a user + * @static + * @param {Object} eventName + * @param {Object} eventMessage + * @returns {object} Details of booked trips + * @memberof Trips + */ + static async emission(eventName, eventMessage) { + return socketPlug.emit(eventName, eventMessage); + } +} +export default socketEmission; diff --git a/src/utils/messageUtils.js b/src/utils/messageUtils.js index 8a7bd18..90f7519 100644 --- a/src/utils/messageUtils.js +++ b/src/utils/messageUtils.js @@ -1,55 +1,58 @@ // This function handles messages export default { - defaultWelcome: [ - 'Welcome to Barefoot Nomad server.', - 'use /api/v1 as the base path url for the APIs of this app.', - ], - welcome: 'Welcome to Archangel Barefoot Nomad Web App API.', - signupSuccess: (email) => `You have successfully registered with this email, ${email}.`, - oneWayTripCreated: 'Your request has been successfully created', - managerApproval: (pendingReq) => `You have ${pendingReq} requests requiring your approval`, - managerNotFound: "Manager's detail missing", - noEmail: 'Email cannot be empty.', - // sign-up validation messages - invalidEmail: 'Please, enter a valid email address.', - usedEmail: (email) => `User with this email (${email}) already exist.`, - shortPassword: 'The length of the password must be 8 and above.', - noDigitInPassword: 'Password must contain at least one digit.', - emptyFirstname: 'First name cannot be empty.', - emptyLastname: 'Last name cannot be empty.', - emptyOrigin: 'You must state your current city.', - emptyDestination: 'You must state your destination', - emptyDepartureDate: 'You must state your departure date', - emptyReturnDate: 'You must state your return date', - emptyTravelPurpose: 'You must state your travel purpose', - lettersAlone: 'Only letters are allowed', - unauthorized: 'Not authorized.', - invalidToken: 'Invalid Token, please login.', - logoutSuccess: 'Logged out successfully.', - incorrectPassword: 'Sorry, the password entered is not correct.', - loginSuccess: 'You have been logged in sucessfully.', - userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, - userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.`, + defaultWelcome: [ + 'Welcome to Barefoot Nomad server.', + 'use /api/v1 as the base path url for the APIs of this app.', + ], + welcome: 'Welcome to Archangel Barefoot Nomad Web App API.', + signupSuccess: (email) => `You have successfully registered with this email, ${email}.`, + verificationMessage: (hostUrl) => `Click on this link to verify your email ${hostUrl}`, + oneWayTripCreated: 'Your request has been successfully created', + managerApproval: (pendingReq) => `You have ${pendingReq} requests requiring your approval`, + managerNotFound: "Manager's detail missing", + noEmail: 'Email cannot be empty.', + // sign-up validation messages + invalidEmail: 'Please, enter a valid email address.', + usedEmail: (email) => `User with this email (${email}) already exist.`, + shortPassword: 'The length of the password must be 8 and above.', + noDigitInPassword: 'Password must contain at least one digit.', + emptyFirstname: 'First name cannot be empty.', + emptyLastname: 'Last name cannot be empty.', + notifyUser: 'Your travel request has been successfully created and it is awaiting approval', + lineManager: 'Line manager must be present to continue', + emptyOrigin: 'You must state your current city.', + emptyDestination: 'You must state your destination', + emptyDepartureDate: 'You must state your departure date', + emptyReturnDate: 'You must state your return date', + emptyTravelPurpose: 'You must state your travel purpose', + lettersAlone: 'Only letters are allowed', + unauthorized: 'Not authorized.', + invalidToken: 'Invalid Token, please login.', + logoutSuccess: 'Logged out successfully.', + incorrectPassword: 'Sorry, the password entered is not correct.', + loginSuccess: 'You have been logged in sucessfully.', + userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, + userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.`, - noEmail: 'Email cannot be empty.', - // sign-up validation messages - invalidEmail: 'Please, enter a valid email address.', - usedEmail: (email) => `User with this email (${email}) already exist.`, - shortPassword: 'The length of the password must be 8 and above.', - noDigitInPassword: 'Password must contain at least one digit.', - emptyFirstname: 'First name cannot be empty.', - emptyLastname: 'Last name cannot be empty.', - emptyOrigin: 'You must state your current city.', - emptyDestination: 'You must state your destination', - emptyDepartureDate: 'You must state your departure date', - emptyReturnDate: 'You must state your return date', - emptyTravelPurpose: 'You must state your travel purpose', - lettersAlone: 'Only letters are allowed', - unauthorized: 'Not authorized.', - invalidToken: 'Invalid Token, please login.', - logoutSuccess: 'Logged out successfully.', - incorrectPassword: 'Sorry, the password entered is not correct.', - loginSuccess: 'You have been logged in successfully.', - userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, - userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.` + noEmail: 'Email cannot be empty.', + // sign-up validation messages + invalidEmail: 'Please, enter a valid email address.', + usedEmail: (email) => `User with this email (${email}) already exist.`, + shortPassword: 'The length of the password must be 8 and above.', + noDigitInPassword: 'Password must contain at least one digit.', + emptyFirstname: 'First name cannot be empty.', + emptyLastname: 'Last name cannot be empty.', + emptyOrigin: 'You must state your current city.', + emptyDestination: 'You must state your destination', + emptyDepartureDate: 'You must state your departure date', + emptyReturnDate: 'You must state your return date', + emptyTravelPurpose: 'You must state your travel purpose', + lettersAlone: 'Only letters are allowed', + unauthorized: 'Not authorized.', + invalidToken: 'Invalid Token, please login.', + logoutSuccess: 'Logged out successfully.', + incorrectPassword: 'Sorry, the password entered is not correct.', + loginSuccess: 'You have been logged in successfully.', + userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, + userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.` }; diff --git a/src/utils/notifyEmailUtils.js b/src/utils/notifyEmailUtils.js new file mode 100644 index 0000000..6187f0e --- /dev/null +++ b/src/utils/notifyEmailUtils.js @@ -0,0 +1,9 @@ +const emailBody = (userDetails, travelInfo) => { + const { + first_name, + last_name + } = userDetails; + const { destination, departure_date, return_date } => { + + } +} diff --git a/src/utils/statusCode.js b/src/utils/statusCode.js index 8d3737e..dfe48f5 100644 --- a/src/utils/statusCode.js +++ b/src/utils/statusCode.js @@ -1,8 +1,9 @@ export default { - success: 200, - created: 201, - badRequest: 400, - notFound: 404, - unauthorized: 401, - serverError: 500 + success: 200, + created: 201, + badRequest: 400, + + notFound: 404, + unauthorized: 401, + serverError: 500 }; From d412bd278c6c516aa4215d6917dadeca090ac5e5 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Wed, 11 Sep 2019 16:02:59 +0100 Subject: [PATCH 13/23] updating the database models, migrations and seeders files --- src/controllers/authControllers.js | 269 +++++++++++------- .../20190823125926-create-departments.js | 65 +++-- .../migrations/20190823135448-create-users.js | 6 + .../20190904023213-create-notifications.js | 12 +- src/database/models/notifications.js | 27 +- src/database/seeders/20190823204056-users.js | 43 +++ .../seeders/20190824033354-departments.js | 6 +- .../seeders/20190824034012-accommodations.js | 54 ++-- .../seeders/20190904024301-notifications.js | 48 ++-- src/modules/email.js | 54 ++-- src/routes/api/notifyRoutes.js | 2 +- 11 files changed, 354 insertions(+), 232 deletions(-) create mode 100644 src/database/seeders/20190823204056-users.js diff --git a/src/controllers/authControllers.js b/src/controllers/authControllers.js index 271126f..d2cd2ae 100644 --- a/src/controllers/authControllers.js +++ b/src/controllers/authControllers.js @@ -1,119 +1,190 @@ -/* eslint-disable max-len */ +import dotenv from 'dotenv'; import ApiErrors from '../utils/ApiErrors'; -// import sendVerificationEmail from '../utils/email'; +import sendVerificationEmail from '../utils/email'; import { - comparePassword, - findUserByEmail, - logoutService, - signupService, + comparePassword, + findUserByEmail, + logoutService, + signupService, } from '../services/authServices'; import { - successResponseWithData, - successResponse, - errorResponse, + successResponseWithData, + successResponse, + errorResponse, } from '../utils/response'; import { generateToken } from '../middlewares/tokenMiddleware'; import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; export default { - signup: async (req, res) => { - try { - const { - first_name, last_name, email, password, - } = req.body; + signup: async(req, res) => { + try { + const { + first_name, + last_name, + email, + password, + } = req.body; - const userObj = { - first_name, - last_name, - email, - password, - }; + const userObj = { + first_name, + last_name, + email, + password, + }; - userObj.role = req.body.role || 'user'; + export default { + signup: async(req, res) => { + try { + const { + first_name, + last_name, + email, + password + } = req.body; + const userObj = { + first_name, + last_name, + email, + password, + role: 'user' + }; - const user = await signupService(userObj); - // eslint-disable-next-line no-unused-vars - // const emailVerify = await sendVerificationEmail(user.dataValues.email); - const data = user.dataValues; + const user = await signupService(userObj); + // const emailVerify = await sendVerificationEmail(user.dataValues.email, + // mailSubject, message.verificationMessage(hostUrl)); + const data = user.dataValues; - data.token = generateToken(data.id, email, data.role, first_name); - delete data.password; - successResponseWithData( - res, - statusCode.created, - message.signupSuccess(req.email), - data - ); - } catch (err) { - errorResponse(res, err.statusCode || statusCode.serverError, err); - } - }, + data.token = generateToken(data.id, email, data.role, first_name); + delete data.password; + successResponseWithData( + res, + statusCode.created, + message.signupSuccess(req.email), + data + ); + } catch (err) { + errorResponse(res, err.statusCode || statusCode.serverError, err); + } + }, - fbgooglesignup: async (req, res) => { - try { - const { - // eslint-disable-next-line no-unused-vars - first_name, - last_name, - email, - role, - } = req.user; + << + << << < HEAD + fbgooglesignup: async(req, res) => { + try { + const { + // eslint-disable-next-line no-unused-vars + first_name, + last_name, + email, + role, + } = req.user; - const data = { - first_name, - last_name, - email, - role, - }; + const data = { + first_name, + last_name, + email, + role, + }; === + === = + fbgooglesignup: async(req, res) => { + try { + const { + first_name, + last_name, + email, + id, + role + } = req.user; - successResponseWithData( - res, - statusCode.created, - message.signupSuccess(email), - data - ); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, + const data = { + first_name, + last_name, + email, + id, + role + }; >>> + >>> > updating the database models, migrations and seeders files - login: async (req, res) => { - try { - const { email, password } = req.body; - const validUser = await findUserByEmail(email); - if (validUser === null || validUser === undefined) { - throw new ApiErrors( - message.userEmailNotFound(email), - statusCode.notFound - ); - } - const { password: hashedPassword, ...data } = validUser.dataValues; - const validPassword = await comparePassword(password, hashedPassword); - if (!validPassword) { - throw new ApiErrors(message.incorrectPassword, statusCode.badRequest); - } else { - const token = generateToken(data.id, email, data.role, data.first_name); - return successResponseWithData( - res, - statusCode.success, - message.loginSuccess, - { ...data, token } - ); - } - } catch (err) { - errorResponse(res, err.statusCode || statusCode.serverError, err); - } - }, + successResponseWithData( + res, + statusCode.created, + message.signupSuccess(email), + data + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } + }, - logout: async (req, res) => { - try { - const { token } = req; - await logoutService(token); - successResponse(res, statusCode.success, message.logoutSuccess); - } catch (err) { - errorResponse(res, statusCode.serverError, err.message); - } - }, -}; + << + << << < HEAD + login: async(req, res) => { + try { + const { email, password } = req.body; + const validUser = await findUserByEmail(email); + if (validUser === null || validUser === undefined) { + throw new ApiErrors( + message.userEmailNotFound(email), + statusCode.notFound + ); + } + const { password: hashedPassword, ...data } = validUser.dataValues; + const validPassword = await comparePassword(password, hashedPassword); + if (!validPassword) { + throw new ApiErrors(message.incorrectPassword, statusCode.badRequest); + } else { + const token = generateToken(data.id, email, data.role, data.first_name); + return successResponseWithData( + res, + statusCode.success, + message.loginSuccess, {...data, token } + ); + } + } catch (err) { + errorResponse(res, err.statusCode || statusCode.serverError, err); + } + }, + + logout: async(req, res) => { + try { + const { token } = req; + await logoutService(token); + successResponse(res, statusCode.success, message.logoutSuccess); + } catch (err) { + errorResponse(res, statusCode.serverError, err.message); + } + }, === + === = + login: async(req, res) => { + try { + const { email, password } = req.body; + const validUser = await findUserByEmail(email); + if (validUser === null || validUser === undefined) { + throw new ApiErrors(message.userEmailNotFound(email), statusCode.notFound); + } + const { password: hashedPassword, ...data } = validUser.dataValues; + const validPassword = await comparePassword(password, hashedPassword); + if (!validPassword) { + throw new ApiErrors(message.incorrectPassword, statusCode.badRequest); + } else { + const token = generateToken(data.id, email, data.role, data.first_name); + return successResponseWithData(res, statusCode.success, message.loginSuccess, {...data, token }); + } + } catch (err) { + errorResponse(res, err.statusCode || statusCode.serverError, err); + } + }, + + logout: async(req, res) => { + try { + const { token } = req; + await logoutService(token); + successResponse(res, statusCode.success, message.logoutSuccess); + } catch (err) { + errorResponse(res, statusCode.serverError, err.message); + } + }, >>> + >>> > updating the database models, migrations and seeders files + }; diff --git a/src/database/migrations/20190823125926-create-departments.js b/src/database/migrations/20190823125926-create-departments.js index 1df3715..b48f8ed 100644 --- a/src/database/migrations/20190823125926-create-departments.js +++ b/src/database/migrations/20190823125926-create-departments.js @@ -1,35 +1,34 @@ module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.createTable('departments', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - dept_name: { - type: Sequelize.TEXT - }, - line_manager: { - type: Sequelize.TEXT - }, - manager_staff_id: { - type: Sequelize.STRING - }, - manager_email: { - type: Sequelize.TEXT - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }); - }, - down: (queryInterface, Sequelize) => { - return queryInterface.dropTable('departments'); - } + up: (queryInterface, Sequelize) => queryInterface.createTable('departments', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + dept_name: { + type: Sequelize.TEXT + }, + line_manager: { + type: Sequelize.TEXT + }, + manager_staff_id: { + type: Sequelize.STRING + }, + line_manager_email: { + type: Sequelize.TEXT + }, + line_manager_id: { + type: Sequelize.INTEGER + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }), + down: (queryInterface, Sequelize) => queryInterface.dropTable('departments') }; diff --git a/src/database/migrations/20190823135448-create-users.js b/src/database/migrations/20190823135448-create-users.js index 1ca96f7..cd6fa7a 100644 --- a/src/database/migrations/20190823135448-create-users.js +++ b/src/database/migrations/20190823135448-create-users.js @@ -48,6 +48,12 @@ module.exports = { gender: { type: Sequelize.TEXT, }, + gmail: { + type: Sequelize.STRING, + }, + facebook: { + type: Sequelize.STRING, + }, address: { type: Sequelize.TEXT, }, diff --git a/src/database/migrations/20190904023213-create-notifications.js b/src/database/migrations/20190904023213-create-notifications.js index 2fcf3e2..13247cc 100644 --- a/src/database/migrations/20190904023213-create-notifications.js +++ b/src/database/migrations/20190904023213-create-notifications.js @@ -6,6 +6,10 @@ module.exports = { primaryKey: true, type: Sequelize.INTEGER }, + user_id: { + allowNull: false, + type: Sequelize.INTEGER + }, travel_id: { allowNull: false, type: Sequelize.INTEGER @@ -18,10 +22,6 @@ module.exports = { allowNull: false, type: Sequelize.STRING }, - receiver: { - allowNull: false, - type: Sequelize.INTEGER - }, content: { allowNull: false, type: Sequelize.STRING @@ -30,10 +30,6 @@ module.exports = { allowNull: false, type: Sequelize.BOOLEAN }, - type: { - allowNull: false, - type: Sequelize.STRING - }, createdAt: { allowNull: false, type: Sequelize.DATE diff --git a/src/database/models/notifications.js b/src/database/models/notifications.js index 84c1ab6..b53e6a0 100644 --- a/src/database/models/notifications.js +++ b/src/database/models/notifications.js @@ -5,15 +5,6 @@ module.exports = (sequelize, DataTypes) => { is_read: DataTypes.TEXT, line_manager_email: DataTypes.TEXT, line_manager_id: DataTypes.INTEGER, - receiver: { - type: DataTypes.INTEGER, - allowNull: false, - validate: { - notEmpty: { - msg: 'notification receiver cannot be empty' - } - } - }, content: { type: DataTypes.STRING, allowNull: false, @@ -22,8 +13,24 @@ module.exports = (sequelize, DataTypes) => { msg: 'notification content cannot be empty' } } - }, + } }, {}); + notifications.associate = (models) => { + notifications.belongsTo(models.users, { + foreignKey: 'user_id', + onDelete: 'CASCADE' + }); + notifications.belongsTo(models.travels, { + foreignKey: 'travel_id', + onDelete: 'CASCADE' + }); + notifications.belongsTo(models.departments, { + foreignKey: 'line_manager_id' + }); + notifications.belongsTo(models.departments, { + foreignKey: 'line_manager_email' + }); + }; return notifications; }; diff --git a/src/database/seeders/20190823204056-users.js b/src/database/seeders/20190823204056-users.js new file mode 100644 index 0000000..9ee4056 --- /dev/null +++ b/src/database/seeders/20190823204056-users.js @@ -0,0 +1,43 @@ +module.exports = { + up: (queryInterface) => queryInterface.bulkInsert( + 'users', [{ + id: 1674946, + staff_id: 'ABD-111-8209', + first_name: 'Chidi', + last_name: 'Chuks', + email: 'chidiebere_chukwuma@yahoo.com', + password: 'every125', + dept_id: 15327458, + dob: '2019-08-09', + gender: 'Male', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'manager', + is_active: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 1215739, + staff_id: 'GHD-123-9004', + first_name: 'Ngozi', + last_name: 'Nancy', + email: 'bakaretemitayo7@gmail.com', + password: 'nanevery125', + dept_id: 1536907, + dob: '2015-08-09', + gender: 'Female', + address: 'Ok. This is our address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'requester', + is_active: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + ], {} + ), + + down: (queryInterface) => queryInterface.bulkDelete('users', null, {}), +}; diff --git a/src/database/seeders/20190824033354-departments.js b/src/database/seeders/20190824033354-departments.js index d7939f8..306f117 100644 --- a/src/database/seeders/20190824033354-departments.js +++ b/src/database/seeders/20190824033354-departments.js @@ -5,7 +5,8 @@ module.exports = { dept_name: 'Business Admin', line_manager: 'Mr. Benchfort', manager_staff_id: 'GHJ-378-2838', - manager_email: 'benchfort@gmail.com', + line_manager_email: 'chidiebere_chukwuma@yahoo.com', + line_manager_id: 6453673, createdAt: new Date(), updatedAt: new Date(), }, @@ -14,7 +15,8 @@ module.exports = { dept_name: 'Software Engr', line_manager: 'Ms. Querty', manager_staff_id: 'RDS-256-5787', - manager_email: 'trello@gmail.com', + line_manager_email: 'chukschiboy@gmail.com', + line_manager_id: 3640773, createdAt: new Date(), updatedAt: new Date(), }, diff --git a/src/database/seeders/20190824034012-accommodations.js b/src/database/seeders/20190824034012-accommodations.js index 02cf36a..89b43a8 100644 --- a/src/database/seeders/20190824034012-accommodations.js +++ b/src/database/seeders/20190824034012-accommodations.js @@ -1,35 +1,25 @@ module.exports = { -up: (queryInterface, Sequelize) => { - return queryInterface.bulkInsert('accommodations', [{ - id: 1653453, - location: "Paris, France", - capacity: 3, - accommodation_name: "Sheraton Protea", - createdAt: new Date(), - updatedAt: new Date() - }, - { - id: 13325578, - location: "Toronto, Canada", - capacity: 1, - accommodation_name: "PAR Towers", - createdAt: new Date(), - updatedAt: new Date() - }, - ], {}); -}, -{ - id: 1332557, - location: 'Toronto, Canada', - capacity: 1, - accommodation_name: 'PAR Towers', - createdAt: new Date(), - updatedAt: new Date() -}, -], {}); -}, + up: (queryInterface) => queryInterface.bulkInsert( + 'accommodations', [{ + id: 1653453, + location: 'Paris, France', + capacity: 3, + accommodation_name: 'Sheraton Protea', + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 13325578, + location: 'Toronto, Canada', + capacity: 1, + accommodation_name: 'PAR Towers', + createdAt: new Date(), + updatedAt: new Date(), + }, + ], {} + ), -down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete('accommodations', null, {}); -} + down: (queryInterface, Sequelize) => { + return queryInterface.bulkDelete('accommodations', null, {}); + } }; diff --git a/src/database/seeders/20190904024301-notifications.js b/src/database/seeders/20190904024301-notifications.js index 30cf598..241d857 100644 --- a/src/database/seeders/20190904024301-notifications.js +++ b/src/database/seeders/20190904024301-notifications.js @@ -1,25 +1,27 @@ module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.bulkInsert('notifications', [{ - id: 333, - travel_id: 1378, - manager_email: '83289benchfort@gmail.com', - read_status: false, - createdAt: new Date(), - updatedAt: new Date() - }, - { - id: 1627, - travel_id: 1573, - manager_email: '234trello@gmail.com', - read_status: false, - createdAt: new Date(), - updatedAt: new Date() - }, - ], {}); - }, + up: (queryInterface, Sequelize) => queryInterface.bulkInsert('notifications', [{ + id: 333, + user_id: 1674946, + travel_id: 1898451, + line_manager_id: 6453673, + line_manager_email: 'chidiebere_chukwuma@yahoo.com', + is_read: false, + content: 'Your travel request has been created', + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: 1627, + user_id: 1215739, + travel_id: 1891029, + line_manager_id: 3640773, + line_manager_email: 'chukschiboy@gmail.com', + is_read: false, + content: 'Your travel request has been created', + createdAt: new Date(), + updatedAt: new Date() + }, + ], {}), - down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete('notifications', null, {}); - } -}; \ No newline at end of file + down: (queryInterface, Sequelize) => queryInterface.bulkDelete('notifications', null, {}) +}; diff --git a/src/modules/email.js b/src/modules/email.js index f6f4578..29d17ee 100644 --- a/src/modules/email.js +++ b/src/modules/email.js @@ -1,42 +1,43 @@ // import nodemailer from 'nodemailer'; import sgMail from '@sendgrid/mail'; -sgMail.setApiKey(process.env.SENDGRID_API); import jwt from 'jsonwebtoken'; import dotenv from 'dotenv'; -dotenv.config(); +sgMail.setApiKey(process.env.SENDGRID_API_KEY); -export const transporter = async (msg,res) => { -try{ - await sgMail.send(msg); - return res.status(200).json({"message":"Mail sent successfully"}) -}catch(err){ - return res.status(500).json({"Error sending email":err}) -} -} +dotenv.config(); +export const transporter = async (msg, res) => { + try { + await sgMail.send(msg); + return res.status(200).json({ message: 'Mail sent successfully' }); + } catch (err) { + return res.status(500).json({ 'Error sending email': err }); + } +}; + export const usePasswordHashToMakeToken = ({ - password: passwordHash, - id: userId, - createdAt + password: passwordHash, + id: userId, + createdAt }) => { - const secret = `${passwordHash - createdAt}`; - const token = jwt.sign({ userId }, secret, { - expiresIn: 3600 // 1 hour - }); - return token; + const secret = `${passwordHash - createdAt}`; + const token = jwt.sign({ userId }, secret, { + expiresIn: 3600 // 1 hour + }); + return token; }; export const getPasswordResetURL = (user, token) => `http://localhost:5000/password/reset/${user.id}/${token}`; export const resetPasswordTemplate = (user, url) => { - const from = 'bakaretemitayo712@gmail.com'; - const to = user.email; - const subject = 'Barefoot Nomad Password Reset'; - const html = ` + const from = 'chidiebere_chukwuma@yahoo.com'; + const to = user.email; + const subject = 'Barefoot Nomad Password Reset'; + const html = `

Hey ${user.name || user.email},

We heard that you lost your Barefoot nomad password. Sorry about that!

But don’t worry! You can use the following link to reset your password:

@@ -45,5 +46,10 @@ export const resetPasswordTemplate = (user, url) => {

Do something outside today!

–Your friends at Barefoot Nomad

`; - return { from, to, subject, html } -} \ No newline at end of file + return { + from, + to, + subject, + html + }; +}; diff --git a/src/routes/api/notifyRoutes.js b/src/routes/api/notifyRoutes.js index e5fb232..7bec6e4 100644 --- a/src/routes/api/notifyRoutes.js +++ b/src/routes/api/notifyRoutes.js @@ -14,7 +14,7 @@ const { getClient } = ClientController; // router.use('/auth', auth); -router.get('/profile/:user_id', getClient); +router.get('/notify/:user_id', getClient); // router.use('/onewaytrip', getToken, verifyToken); router.use((err, req, res, next) => { From 2bba6ea9bddfc62e60019634c20524d307bec015 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Thu, 12 Sep 2019 13:26:41 +0100 Subject: [PATCH 14/23] reconfigured local project to be in sync with develop --- .editorconfig | 2 +- package-lock.json | 1411 ++++++----------- package.json | 9 +- src/config/config.js | 37 +- src/config/passport.js | 4 +- src/controllers/authControllers.js | 269 ++-- src/controllers/client.js | 59 - src/controllers/index.js | 5 +- src/controllers/notifyControllers.js | 33 - src/controllers/resetPassword.js | 103 +- src/controllers/travelControllers.js | 95 +- src/database/config.js | 66 +- .../20190823125926-create-department.js | 32 + .../20190823125926-create-departments.js | 34 - .../migrations/20190823135448-create-users.js | 163 +- .../20190823140019-create-travels.js | 41 - .../20190823140048-create-accommodation.js | 36 + .../20190823140048-create-accommodations.js | 36 - .../20190904023213-create-notifications.js | 43 - src/database/models/departments.js | 18 - src/database/models/notifications.js | 36 - src/database/models/travels.js | 17 - src/database/seeders/20190823204056-users.js | 43 - .../seeders/20190824033354-department.js | 24 + .../seeders/20190824033354-departments.js | 29 - .../seeders/20190824033956-travels.js | 31 - .../seeders/20190824034012-accommodation.js | 25 + .../seeders/20190824034012-accommodations.js | 25 - .../seeders/20190904024301-notifications.js | 27 - src/index.js | 101 +- src/models/accommodation.js | 18 +- src/models/users.js | 71 +- src/modules/email.js | 54 +- src/routes/api/notifyRoutes.js | 33 - src/routes/api/travelRoute.js | 5 +- src/routes/authRoutes.js | 35 +- src/routes/index.js | 8 +- src/services/authServices.js | 116 +- src/services/deptServices.js | 43 - src/services/emailServices.js | 50 +- src/services/notifyServices.js | 24 - src/services/travelServices.js | 63 +- src/services/websocket.js | 33 - src/tests/authTest.js | 357 +++++ src/tests/mocks/users.js | 10 - src/utils/email.js | 69 +- src/utils/messageUtils.js | 99 +- src/utils/notifyEmailUtils.js | 9 - src/utils/statusCode.js | 13 +- 49 files changed, 1612 insertions(+), 2352 deletions(-) delete mode 100644 src/controllers/client.js delete mode 100644 src/controllers/notifyControllers.js create mode 100644 src/database/migrations/20190823125926-create-department.js delete mode 100644 src/database/migrations/20190823125926-create-departments.js delete mode 100644 src/database/migrations/20190823140019-create-travels.js create mode 100644 src/database/migrations/20190823140048-create-accommodation.js delete mode 100644 src/database/migrations/20190823140048-create-accommodations.js delete mode 100644 src/database/migrations/20190904023213-create-notifications.js delete mode 100644 src/database/models/departments.js delete mode 100644 src/database/models/notifications.js delete mode 100644 src/database/models/travels.js delete mode 100644 src/database/seeders/20190823204056-users.js create mode 100644 src/database/seeders/20190824033354-department.js delete mode 100644 src/database/seeders/20190824033354-departments.js delete mode 100644 src/database/seeders/20190824033956-travels.js create mode 100644 src/database/seeders/20190824034012-accommodation.js delete mode 100644 src/database/seeders/20190824034012-accommodations.js delete mode 100644 src/database/seeders/20190904024301-notifications.js delete mode 100644 src/routes/api/notifyRoutes.js delete mode 100644 src/services/deptServices.js delete mode 100644 src/services/notifyServices.js delete mode 100644 src/services/websocket.js create mode 100644 src/tests/authTest.js delete mode 100644 src/tests/mocks/users.js delete mode 100644 src/utils/notifyEmailUtils.js diff --git a/.editorconfig b/.editorconfig index 55094a8..f71a6fd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,5 @@ charset = utf-8 # Set indentation style and size for javascript files [*.js] -indent_style = tab +indent_style = space indent_size = 2 diff --git a/package-lock.json b/package-lock.json index e3d7eaf..6ae0639 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,12 +5,12 @@ "requires": true, "dependencies": { "@babel/cli": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.5.5.tgz", - "integrity": "sha512-UHI+7pHv/tk9g6WXQKYz+kmXTI77YtuY3vqC59KIqcoWEjsJJSG6rAxKaLsgj3LDyadsPrCB929gVOKM6Hui0w==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.6.0.tgz", + "integrity": "sha512-1CTDyGUjQqW3Mz4gfKZ04KGOckyyaNmKneAMlABPS+ZyuxWv3FrVEVz7Ag08kNIztVx8VaJ8YgvYLSNlMKAT5Q==", "dev": true, "requires": { - "chokidar": "^2.0.4", + "chokidar": "^2.1.8", "commander": "^2.8.1", "convert-source-map": "^1.1.0", "fs-readdir-recursive": "^1.1.0", @@ -32,18 +32,18 @@ } }, "@babel/core": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", - "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.0.tgz", + "integrity": "sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.5.5", - "@babel/helpers": "^7.5.5", - "@babel/parser": "^7.5.5", - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5", + "@babel/generator": "^7.6.0", + "@babel/helpers": "^7.6.0", + "@babel/parser": "^7.6.0", + "@babel/template": "^7.6.0", + "@babel/traverse": "^7.6.0", + "@babel/types": "^7.6.0", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -54,12 +54,12 @@ } }, "@babel/generator": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", - "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz", + "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==", "dev": true, "requires": { - "@babel/types": "^7.5.5", + "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0", @@ -259,14 +259,14 @@ } }, "@babel/helpers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", - "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.0.tgz", + "integrity": "sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ==", "dev": true, "requires": { - "@babel/template": "^7.4.4", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" + "@babel/template": "^7.6.0", + "@babel/traverse": "^7.6.0", + "@babel/types": "^7.6.0" } }, "@babel/highlight": { @@ -281,13 +281,13 @@ } }, "@babel/node": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.5.5.tgz", - "integrity": "sha512-xsW6il+yY+lzXMsQuvIJNA7tU8ix/f4G6bDt4DrnCkVpsR6clk9XgEbp7QF+xGNDdoD7M7QYokCH83pm+UjD0w==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.6.1.tgz", + "integrity": "sha512-q2sJw+7aES/5wwjccECJfOuIgM1XIbZcn7b63JZM6VpaZwvOq913jL+tXRIn41Eg/Hr+BeIGWnvnjLTuT579pA==", "dev": true, "requires": { - "@babel/polyfill": "^7.0.0", - "@babel/register": "^7.5.5", + "@babel/polyfill": "^7.6.0", + "@babel/register": "^7.6.0", "commander": "^2.8.1", "lodash": "^4.17.13", "node-environment-flags": "^1.0.5", @@ -295,9 +295,9 @@ } }, "@babel/parser": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", - "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", + "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -437,9 +437,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", - "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz", + "integrity": "sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -472,9 +472,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", - "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz", + "integrity": "sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -559,9 +559,9 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", - "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz", + "integrity": "sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.4.4", @@ -592,12 +592,12 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", - "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz", + "integrity": "sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew==", "dev": true, "requires": { - "regexp-tree": "^0.1.6" + "regexp-tree": "^0.1.13" } }, "@babel/plugin-transform-new-target": { @@ -658,9 +658,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz", - "integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz", + "integrity": "sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -728,9 +728,9 @@ } }, "@babel/polyfill": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", - "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.6.0.tgz", + "integrity": "sha512-q5BZJI0n/B10VaQQvln1IlDK3BTBJFbADx7tv+oXDPIDZuTo37H5Adb9jhlXm/fEN4Y7/64qD9mnrJJG7rmaTw==", "dev": true, "requires": { "core-js": "^2.6.5", @@ -746,9 +746,9 @@ } }, "@babel/preset-env": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", - "integrity": "sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.0.tgz", + "integrity": "sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -767,10 +767,10 @@ "@babel/plugin-transform-arrow-functions": "^7.2.0", "@babel/plugin-transform-async-to-generator": "^7.5.0", "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.5.5", + "@babel/plugin-transform-block-scoping": "^7.6.0", "@babel/plugin-transform-classes": "^7.5.5", "@babel/plugin-transform-computed-properties": "^7.2.0", - "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-destructuring": "^7.6.0", "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/plugin-transform-duplicate-keys": "^7.5.0", "@babel/plugin-transform-exponentiation-operator": "^7.2.0", @@ -779,10 +779,10 @@ "@babel/plugin-transform-literals": "^7.2.0", "@babel/plugin-transform-member-expression-literals": "^7.2.0", "@babel/plugin-transform-modules-amd": "^7.5.0", - "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "@babel/plugin-transform-modules-commonjs": "^7.6.0", "@babel/plugin-transform-modules-systemjs": "^7.5.0", "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.0", "@babel/plugin-transform-new-target": "^7.4.4", "@babel/plugin-transform-object-super": "^7.5.5", "@babel/plugin-transform-parameters": "^7.4.4", @@ -795,7 +795,7 @@ "@babel/plugin-transform-template-literals": "^7.4.4", "@babel/plugin-transform-typeof-symbol": "^7.2.0", "@babel/plugin-transform-unicode-regex": "^7.4.4", - "@babel/types": "^7.5.5", + "@babel/types": "^7.6.0", "browserslist": "^4.6.0", "core-js-compat": "^3.1.1", "invariant": "^2.2.2", @@ -804,12 +804,11 @@ } }, "@babel/register": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.5.5.tgz", - "integrity": "sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.6.0.tgz", + "integrity": "sha512-78BomdN8el+x/nkup9KwtjJXuptW5oXMFmP11WoM2VJBjxrKv4grC3qjpLL8RGGUYUGsm57xnjYFM2uom+jWUQ==", "dev": true, "requires": { - "core-js": "^3.0.0", "find-cache-dir": "^2.0.0", "lodash": "^4.17.13", "mkdirp": "^0.5.1", @@ -818,45 +817,45 @@ } }, "@babel/runtime": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", - "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", + "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", "requires": { "regenerator-runtime": "^0.13.2" } }, "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", + "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.0" } }, "@babel/traverse": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", - "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz", + "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.5.5", + "@babel/generator": "^7.6.0", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.5.5", - "@babel/types": "^7.5.5", + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", - "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", + "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -898,9 +897,9 @@ "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" }, "@types/chai": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.1.tgz", - "integrity": "sha512-LDKlQW/V8bQr5p9aoHye9p7x9faxq0GVeWAkn/Zgyyn848LIAzuR1sHQjGmUBFUpINuGWDG2NTM/ofA2aLMIew==" + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.2.tgz", + "integrity": "sha512-8V2aCcPM3WLuJvJpF6N60uUvdZb7NHjpjQlLk1QmZbTP4XZET/FX0c3TJ3K7qt4L98FS1Pifa8BVofTVuJFWVA==" }, "@types/cookiejar": { "version": "2.1.1", @@ -908,45 +907,19 @@ "integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==" }, "@types/node": { - "version": "12.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.4.tgz", - "integrity": "sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ==" - }, - "@types/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-f8JzJNWVhKtc9dg/dyDNfliTKNOJSLa7Oht/ElZdF/UbMUmAH3rLmAk3ODNjw0mZajDEgatA03tRjB4+Dp/tzA==" - }, - "@types/react": { - "version": "16.9.2", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.2.tgz", - "integrity": "sha512-jYP2LWwlh+FTqGd9v7ynUKZzjj98T8x7Yclz479QdRhHfuW9yQ+0jjnD31eXSXutmBpppj5PYNLYLRfnZJvcfg==", - "requires": { - "@types/prop-types": "*", - "csstype": "^2.2.0" - } + "version": "12.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", + "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==" }, "@types/request": { - "version": "2.48.2", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.2.tgz", - "integrity": "sha512-gP+PSFXAXMrd5PcD7SqHeUjdGshAI8vKQ3+AvpQr3ht9iQea+59LOKvKITcQI+Lg+1EIkDP6AFSBUJPWG8GDyA==", + "version": "2.48.3", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.3.tgz", + "integrity": "sha512-3Wo2jNYwqgXcIz/rrq18AdOZUQB8cQ34CXZo+LUwPJNpvRAL86+Kc2wwI8mqpz9Cr1V+enIox5v+WZhy/p3h8w==", "requires": { "@types/caseless": "*", "@types/node": "*", "@types/tough-cookie": "*", "form-data": "^2.5.0" - }, - "dependencies": { - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - } } }, "@types/superagent": { @@ -989,10 +962,10 @@ "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", "dev": true }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + "addressparser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", + "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=" }, "ajv": { "version": "6.10.2", @@ -1020,12 +993,6 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -1098,20 +1065,6 @@ } } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1169,11 +1122,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -1221,10 +1169,78 @@ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + "async.ensureasync": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.ensureasync/-/async.ensureasync-0.5.2.tgz", + "integrity": "sha1-w8fkpOmzHZaHXVa4UEWYRG4eMF0=", + "requires": { + "async.util.ensureasync": "0.5.2" + } + }, + "async.queue": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.queue/-/async.queue-0.5.2.tgz", + "integrity": "sha1-jV2QgS4UgQZrwJBOjMFxKxfDvXw=", + "requires": { + "async.util.queue": "0.5.2" + } + }, + "async.util.arrayeach": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz", + "integrity": "sha1-WMTpgCjVXWm/sFrrOvROClVagpw=" + }, + "async.util.ensureasync": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.ensureasync/-/async.util.ensureasync-0.5.2.tgz", + "integrity": "sha1-EJB/LL0GegYfma5tIuCM7TDbDWg=", + "requires": { + "async.util.restparam": "0.5.2", + "async.util.setimmediate": "0.5.2" + } + }, + "async.util.isarray": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", + "integrity": "sha1-5i2sjyY29lh13PdSHC0k0N+yu98=" + }, + "async.util.map": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.map/-/async.util.map-0.5.2.tgz", + "integrity": "sha1-5YjvhuCzq18CfZevTWg10FXKadY=" + }, + "async.util.noop": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", + "integrity": "sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk=" + }, + "async.util.onlyonce": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", + "integrity": "sha1-uOb8AErckjFk154y8oE+5GXCT/I=" + }, + "async.util.queue": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.queue/-/async.util.queue-0.5.2.tgz", + "integrity": "sha1-V/Zavho83yc9MavSirlUJfgiLuU=", + "requires": { + "async.util.arrayeach": "0.5.2", + "async.util.isarray": "0.5.2", + "async.util.map": "0.5.2", + "async.util.noop": "0.5.2", + "async.util.onlyonce": "0.5.2", + "async.util.setimmediate": "0.5.2" + } + }, + "async.util.restparam": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz", + "integrity": "sha1-A+/r88Ane5ciDlJaunUPXgT8gM0=" + }, + "async.util.setimmediate": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz", + "integrity": "sha1-KBLrq/KlgCd1jUvHeT0cz68QJV8=" }, "asynckit": { "version": "0.4.0", @@ -1237,14 +1253,6 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, - "auto-bind": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-2.1.0.tgz", - "integrity": "sha512-qZuFvkes1eh9lB2mg8/HG18C+5GIO51r+RrCSst/lh+i5B1CtVlkhTE488M805Nr3dKl0sM/pIFKSKUIlg3zUg==", - "requires": { - "@types/react": "^16.8.12" - } - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -1300,6 +1308,15 @@ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -1364,6 +1381,20 @@ } } }, + "babel-eslint": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", + "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, "babel-generator": { "version": "6.26.1", "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", @@ -1548,11 +1579,6 @@ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1613,16 +1639,6 @@ } } }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" - }, "base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", @@ -1634,15 +1650,13 @@ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "requires": { "safe-buffer": "5.1.2" - } - }, - "bcrypt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-3.0.6.tgz", - "integrity": "sha512-taA5bCTfXe7FUjKroKky9EXpdhkVvhE5owfxfLYodbrAR1Ul3juLmIQmIQBK4L9a5BuUcE6cqmwT+Da20lF9tg==", - "requires": { - "nan": "2.13.2", - "node-pre-gyp": "0.12.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "bcrypt-pbkdf": { @@ -1658,25 +1672,12 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "requires": { - "callsite": "1.0.0" - } - }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" - }, "bluebird": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", @@ -1719,6 +1720,11 @@ } } }, + "bottleneck": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-1.16.0.tgz", + "integrity": "sha1-1s4TgIUnr8gLaQkvFWBmVeWyHxo=" + }, "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", @@ -1746,12 +1752,6 @@ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -1866,11 +1866,6 @@ "unset-value": "^1.0.0" } }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1967,11 +1962,6 @@ "upath": "^1.1.1" } }, - "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" - }, "ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -2043,36 +2033,6 @@ "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } } }, "cls-bluebird": { @@ -2087,7 +2047,8 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true }, "collection-visit": { "version": "1.0.0", @@ -2131,21 +2092,11 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2197,11 +2148,6 @@ "integrity": "sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg==", "dev": true }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", @@ -2214,6 +2160,13 @@ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "requires": { "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "content-type": { @@ -2228,6 +2181,14 @@ "dev": true, "requires": { "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } } }, "cookie": { @@ -2299,13 +2260,6 @@ "log-driver": "^1.2.7", "minimist": "^1.2.0", "request": "^2.86.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } } }, "create-error-class": { @@ -2339,10 +2293,13 @@ "which": "^1.2.9" } }, - "csstype": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz", - "integrity": "sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==" + "crypto-random-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-3.0.1.tgz", + "integrity": "sha512-dUL0cJ4PBLanJGJQBHQUkvZ3C4q13MXzl54oRqAIiJGiNkOZ4JDwkg/SBo7daGghzlJv16yW1p/4lIQukmbedA==", + "requires": { + "type-fest": "^0.5.2" + } }, "d": { "version": "1.0.1", @@ -2397,7 +2354,8 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true }, "deep-is": { "version": "0.1.3", @@ -2465,11 +2423,6 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -2489,11 +2442,6 @@ "repeating": "^2.0.0" } }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -2573,9 +2521,9 @@ "integrity": "sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==" }, "electron-to-chromium": { - "version": "1.3.252", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.252.tgz", - "integrity": "sha512-NWJ5TztDnjExFISZHFwpoJjMbLUifsNBnx7u2JI0gCw6SbKyQYYWWtBHasO/jPtHym69F4EZuTpRNGN11MT/jg==", + "version": "1.3.256", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.256.tgz", + "integrity": "sha512-GHY1r2mO56BRMng6rkxxJvsWKtqy9k/IlSBrAV/VKwZKpTydVUJnOwajTNnl5uutJpthHgZy+HeofK5K6PqEgQ==", "dev": true }, "emoji-regex": { @@ -2588,6 +2536,14 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -2597,89 +2553,6 @@ "once": "^1.4.0" } }, - "engine.io": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", - "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", - "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~6.1.0" - }, - "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "engine.io-client": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", - "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~6.1.0", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "engine.io-parser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" - } - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2699,9 +2572,9 @@ } }, "es-abstract": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.1.tgz", - "integrity": "sha512-cp/Tb1oA/rh2X7vqeSOvM+TSo3UkJLX70eNihgVEvnzwAgikjkTFr/QVgRCaxjm0knCNQzNoxxxcw2zO2LJdZA==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", + "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", "dev": true, "requires": { "es-to-primitive": "^1.2.0", @@ -2775,8 +2648,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { "version": "6.3.0", @@ -2823,12 +2695,6 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, "glob-parent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", @@ -2843,21 +2709,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true } } }, @@ -3290,6 +3141,11 @@ "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -3341,6 +3197,11 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -3596,17 +3457,6 @@ "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "flatted": { @@ -3670,14 +3520,6 @@ "universalify": "^0.1.0" } }, - "fs-minipass": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", - "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", - "requires": { - "minipass": "^2.2.1" - } - }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -4249,21 +4091,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -4415,26 +4242,6 @@ "ansi-regex": "^2.0.0" } }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -4446,11 +4253,6 @@ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -4563,14 +4365,6 @@ "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", "dev": true }, - "ignore-walk": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.2.tgz", - "integrity": "sha512-EXyErtpHbn75ZTsOADsfx6J/FPo6/5cjev46PXrcTpd8z3BoRkXgYu9/JVqrI7tusjmwCZutGeRJeU0Wo1e4Cw==", - "requires": { - "minimatch": "^3.0.4" - } - }, "import-fresh": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", @@ -4593,11 +4387,6 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" - }, "inflection": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", @@ -4649,12 +4438,6 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -4675,23 +4458,6 @@ } } } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } } } }, @@ -4848,12 +4614,9 @@ } }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-glob": { "version": "4.0.1", @@ -4959,9 +4722,9 @@ } }, "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", "dev": true }, "is-stream": { @@ -5084,14 +4847,6 @@ "dev": true, "requires": { "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "jsonfile": { @@ -5232,6 +4987,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "lodash.chunk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", + "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -5308,13 +5068,6 @@ "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" - }, - "dependencies": { - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } } }, "lru-queue": { @@ -5325,6 +5078,17 @@ "es5-ext": "~0.10.2" } }, + "mailparser": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.6.2.tgz", + "integrity": "sha1-A8SGA5vfTfbNO2rcqqxBB9/bwGg=", + "requires": { + "encoding": "^0.1.12", + "mime": "^1.3.4", + "mimelib": "^0.3.0", + "uue": "^3.1.0" + } + }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -5473,6 +5237,15 @@ "mime-db": "1.40.0" } }, + "mimelib": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz", + "integrity": "sha1-eHrdJBXYJ6yzr27EvKHqlZZBiFM=", + "requires": { + "addressparser": "~1.0.1", + "encoding": "~0.1.12" + } + }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", @@ -5488,26 +5261,9 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "minipass": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.5.1.tgz", - "integrity": "sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "requires": { - "minipass": "^2.2.1" - } + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "mixin-deep": { "version": "1.3.2", @@ -5536,6 +5292,13 @@ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } } }, "mocha": { @@ -5621,12 +5384,6 @@ "path-is-absolute": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -5643,34 +5400,6 @@ "semver": "^5.7.0" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -5680,6 +5409,12 @@ "ansi-regex": "^3.0.0" } }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "supports-color": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", @@ -5825,9 +5560,11 @@ "dev": true }, "nan": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", - "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==" + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true }, "nanomatch": { "version": "1.2.13", @@ -5854,26 +5591,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "needle": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -5906,32 +5623,20 @@ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true }, - "node-pre-gyp": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, "node-releases": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.29.tgz", - "integrity": "sha512-R5bDhzh6I+tpi/9i2hrrvGJ3yKPYzlVOORDkXhnZuwi5D3q1I5w4vYy24PJXTcLk9Q0kws9TO77T75bcK8/ysQ==", + "version": "1.1.30", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.30.tgz", + "integrity": "sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw==", "dev": true, "requires": { "semver": "^5.3.0" } }, + "nodemailer": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.3.0.tgz", + "integrity": "sha512-TEHBNBPHv7Ie/0o3HXnb7xrPSSQmH1dXwQKRaMKDBGt/ZN54lvDVujP6hKkO/vjkIYL9rK8kHSG11+G42Nhxuw==" + }, "nodemon": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.2.tgz", @@ -5988,20 +5693,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" - }, - "npm-packlist": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz", - "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==", - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -6011,21 +5702,11 @@ "path-key": "^2.0.0" } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true }, "oauth": { "version": "0.9.15", @@ -6042,11 +5723,6 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -6331,22 +6007,6 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "requires": { - "better-assert": "~1.0.0" - } - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -6669,9 +6329,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.1.tgz", - "integrity": "sha512-2KLd5fKOdAfShtY2d/8XDWVRnmp3zp40Qt6ge2zBPFARLXOGUf2fHD5eg+TV/5oxBtQKVhjUaKFsAaE4HnwfSA==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" }, "pstree.remy": { "version": "1.1.7", @@ -6695,9 +6355,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz", - "integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w==" + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "random-bytes": { "version": "1.0.0", @@ -6724,6 +6384,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -6731,10 +6392,11 @@ "strip-json-comments": "~2.0.1" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true } } }, @@ -6822,6 +6484,13 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "readdirp": { @@ -7005,11 +6674,6 @@ "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" } } }, @@ -7068,9 +6732,10 @@ } }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -7094,9 +6759,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, "safe-regex": { "version": "1.1.0", @@ -7112,11 +6777,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -7173,10 +6833,44 @@ } } }, + "sendgrid": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/sendgrid/-/sendgrid-5.2.3.tgz", + "integrity": "sha512-FD7oR9TbJFUew1p0Vw9JX0wBetDyq634LzylSXz4n9+hwaf+6a9dNloZl8CcjpsX4NuEc3HJanTN4GjDwNyi4A==", + "requires": { + "async.ensureasync": "^0.5.2", + "async.queue": "^0.5.2", + "bottleneck": "^1.12.0", + "debug": "^2.2.0", + "lodash.chunk": "^4.2.0", + "mailparser": "^0.6.1", + "sendgrid-rest": "^2.3.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "sendgrid-rest": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/sendgrid-rest/-/sendgrid-rest-2.4.0.tgz", + "integrity": "sha512-3VRHhTnln17jPQNzBjEHO6u2Y7kLlhVnOvX0aGjr7yRVZpq5LXo0ilAFMsaHUfKVH+jFdCrHMAVLOAdtu6wLJA==" + }, "sequelize": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.18.1.tgz", - "integrity": "sha512-jngo7pqilyOycMv6ZEwHLVn2wuHi/xkSQZfwK4jhjG8ta1HWYJK3XyQDFdhVEOH1GEq9pnqaf+7Kwqm+eqXD9Q==", + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.18.4.tgz", + "integrity": "sha512-bBmJqpO1H8Z7L0xzITqVo5KHXFI7GmKfGl/5SIPDKsuUMbuZT98s+gyGeaLXpOWGH1ZUO79hvJ8z74vNcxBWHg==", "requires": { "bluebird": "^3.5.0", "cls-bluebird": "^2.1.0", @@ -7299,7 +6993,8 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true }, "slash": { "version": "2.0.0", @@ -7316,14 +7011,6 @@ "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } } }, "snapdragon": { @@ -7448,100 +7135,6 @@ } } }, - "socket.io": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", - "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", - "requires": { - "debug": "~4.1.0", - "engine.io": "~3.3.1", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.2.0", - "socket.io-parser": "~3.3.0" - } - }, - "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" - }, - "socket.io-client": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", - "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.3.1", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7682,33 +7275,33 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, "string.prototype.trimleft": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz", - "integrity": "sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.0.2" + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" } }, "string.prototype.trimright": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz", - "integrity": "sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.0.2" + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" } }, "string_decoder": { @@ -7717,14 +7310,28 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + } } }, "strip-bom": { @@ -7740,9 +7347,10 @@ "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true }, "superagent": { "version": "3.8.3", @@ -7789,54 +7397,6 @@ "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" } }, "term-size": { @@ -7917,11 +7477,6 @@ "os-tmpdir": "~1.0.2" } }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -8060,6 +7615,11 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -8313,6 +7873,15 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uue": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.2.tgz", + "integrity": "sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==", + "requires": { + "escape-string-regexp": "~1.0.5", + "extend": "~3.0.0" + } + }, "uuid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", @@ -8381,8 +7950,36 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, "requires": { "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "widest-line": { @@ -8400,12 +7997,6 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -8449,36 +8040,6 @@ "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } } }, "wrappy": { @@ -8506,25 +8067,12 @@ "signal-exit": "^3.0.2" } }, - "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "requires": { - "async-limiter": "~1.0.0" - } - }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -8536,9 +8084,9 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { "version": "13.3.0", @@ -8555,36 +8103,6 @@ "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } } }, "yargs-parser": { @@ -8630,12 +8148,6 @@ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", @@ -8739,11 +8251,6 @@ } } } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } } } diff --git a/package.json b/package.json index 89d19b0..e6a5021 100755 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "prod": "set NODE_ENV=production&& node build/index.js", "start": "set NODE_ENV=development&& babel-node src/index.js", "dev": "set DEBUG=web-app && set NODE_ENV=development&& nodemon src/index.js --exec babel-node", - "test": "set NODE_ENV=test&& sequelize db:migrate:undo:all && sequelize db:migrate && mocha --timeout 0 ./src/tests/*.js --require @babel/register --reporter spec --exec babel-node --exit", + "test": "set NODE_ENV=test&& sequelize db:migrate:undo:all && sequelize db:migrate && sequelize db:seed:all && mocha --timeout 0 ./src/tests/*.js --require @babel/register --reporter spec --exec babel-node --exit", "generate-lcov": "nyc report --reporter=text-lcov >lcov.info", "coveralls-coverage": "coveralls < lcov.info", "coverage": "nyc npm test && npm run generate-lcov && npm run coveralls-coverage", @@ -23,14 +23,13 @@ "dependencies": { "@babel/runtime": "^7.5.5", "@sendgrid/mail": "^6.4.0", - "auto-bind": "^2.1.0", - "bcrypt": "^3.0.6", "bcryptjs": "^2.4.3", "chai": "^4.2.0", "chai-http": "^4.3.0", "core-js": "^3.2.1", "cors": "^2.8.4", "coveralls": "^3.0.3", + "crypto-random-string": "^3.0.1", "debug": "^4.1.1", "dotenv": "^6.2.0", "ejs": "^2.6.1", @@ -43,6 +42,7 @@ "method-override": "^2.3.10", "methods": "^1.1.2", "morgan": "^1.9.1", + "nodemailer": "^6.3.0", "passport": "^0.4.0", "passport-facebook": "^3.0.0", "passport-google-oauth20": "^2.0.0", @@ -52,9 +52,9 @@ "pg-hstore": "^2.3.3", "regenerator-runtime": "^0.13.3", "request": "^2.87.0", + "sendgrid": "^5.2.3", "sequelize": "^5.15.2", "sequelize-cli": "^5.5.0", - "socket.io": "^2.2.0", "underscore": "^1.9.1" }, "devDependencies": { @@ -64,6 +64,7 @@ "@babel/plugin-transform-runtime": "^7.5.5", "@babel/preset-env": "^7.5.5", "@babel/register": "^7.5.5", + "babel-eslint": "^10.0.3", "babel-register": "^6.26.0", "cross-env": "^5.2.0", "eslint": "^6.1.0", diff --git a/src/config/config.js b/src/config/config.js index ea2ea06..7fa7e60 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -3,34 +3,33 @@ import dotenv from 'dotenv'; dotenv.config(); const { - DB_USERNAME, - DATABASE, - DB_PASSWORD, - DB_HOST, - DB_PORT, - PORT, - DB_DIALECT + DB_USERNAME, + DATABASE, + DB_PASSWORD, + DB_HOST, + DB_PORT, + PORT, + DB_DIALECT } = process.env; export const db = { - DB_USERNAME, - DATABASE, - DB_PASSWORD, - DB_HOST, - DB_PORT, - PORT, - DB_DIALECT + DB_USERNAME, + DATABASE, + DB_PASSWORD, + DB_HOST, + DB_PORT, + PORT, + DB_DIALECT }; let connection; if (process.env.NODE_ENV === 'test') { - connection = { - connectionString: process.env.TESTDB_URL - } + connection = { + connectionString: process.env.TESTDB_URL + }; } connection = { - connectionString: process.env.DATABASE_URL + connectionString: process.env.DATABASE_URL }; - diff --git a/src/config/passport.js b/src/config/passport.js index 0f2eb1e..e331fc1 100755 --- a/src/config/passport.js +++ b/src/config/passport.js @@ -3,7 +3,7 @@ import { Strategy } from 'passport-google-oauth20'; import dotenv from 'dotenv'; import { signupService, findUserById } from '../services/authServices'; -dotenv.config() +dotenv.config(); const fbStrategy = new FacebookStrategy({ clientID: '521471335085949', @@ -13,7 +13,7 @@ const fbStrategy = new FacebookStrategy({ async (accessToken, refreshToken, profile, cb) => { try { - const email = profile.emails? profile.emails[0].value : null; + const email = profile.emails ? profile.emails[0].value : null; const { id } = profile; const userExists = await findUserById(id); diff --git a/src/controllers/authControllers.js b/src/controllers/authControllers.js index d2cd2ae..271126f 100644 --- a/src/controllers/authControllers.js +++ b/src/controllers/authControllers.js @@ -1,190 +1,119 @@ -import dotenv from 'dotenv'; +/* eslint-disable max-len */ import ApiErrors from '../utils/ApiErrors'; -import sendVerificationEmail from '../utils/email'; +// import sendVerificationEmail from '../utils/email'; import { - comparePassword, - findUserByEmail, - logoutService, - signupService, + comparePassword, + findUserByEmail, + logoutService, + signupService, } from '../services/authServices'; import { - successResponseWithData, - successResponse, - errorResponse, + successResponseWithData, + successResponse, + errorResponse, } from '../utils/response'; import { generateToken } from '../middlewares/tokenMiddleware'; import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; export default { - signup: async(req, res) => { - try { - const { - first_name, - last_name, - email, - password, - } = req.body; + signup: async (req, res) => { + try { + const { + first_name, last_name, email, password, + } = req.body; - const userObj = { - first_name, - last_name, - email, - password, - }; + const userObj = { + first_name, + last_name, + email, + password, + }; - export default { - signup: async(req, res) => { - try { - const { - first_name, - last_name, - email, - password - } = req.body; - const userObj = { - first_name, - last_name, - email, - password, - role: 'user' - }; + userObj.role = req.body.role || 'user'; - const user = await signupService(userObj); - // const emailVerify = await sendVerificationEmail(user.dataValues.email, - // mailSubject, message.verificationMessage(hostUrl)); - const data = user.dataValues; + const user = await signupService(userObj); + // eslint-disable-next-line no-unused-vars + // const emailVerify = await sendVerificationEmail(user.dataValues.email); + const data = user.dataValues; - data.token = generateToken(data.id, email, data.role, first_name); - delete data.password; - successResponseWithData( - res, - statusCode.created, - message.signupSuccess(req.email), - data - ); - } catch (err) { - errorResponse(res, err.statusCode || statusCode.serverError, err); - } - }, + data.token = generateToken(data.id, email, data.role, first_name); + delete data.password; + successResponseWithData( + res, + statusCode.created, + message.signupSuccess(req.email), + data + ); + } catch (err) { + errorResponse(res, err.statusCode || statusCode.serverError, err); + } + }, - << - << << < HEAD - fbgooglesignup: async(req, res) => { - try { - const { - // eslint-disable-next-line no-unused-vars - first_name, - last_name, - email, - role, - } = req.user; + fbgooglesignup: async (req, res) => { + try { + const { + // eslint-disable-next-line no-unused-vars + first_name, + last_name, + email, + role, + } = req.user; - const data = { - first_name, - last_name, - email, - role, - }; === - === = - fbgooglesignup: async(req, res) => { - try { - const { - first_name, - last_name, - email, - id, - role - } = req.user; + const data = { + first_name, + last_name, + email, + role, + }; - const data = { - first_name, - last_name, - email, - id, - role - }; >>> - >>> > updating the database models, migrations and seeders files + successResponseWithData( + res, + statusCode.created, + message.signupSuccess(email), + data + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } + }, - successResponseWithData( - res, - statusCode.created, - message.signupSuccess(email), - data - ); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, + login: async (req, res) => { + try { + const { email, password } = req.body; + const validUser = await findUserByEmail(email); + if (validUser === null || validUser === undefined) { + throw new ApiErrors( + message.userEmailNotFound(email), + statusCode.notFound + ); + } + const { password: hashedPassword, ...data } = validUser.dataValues; + const validPassword = await comparePassword(password, hashedPassword); + if (!validPassword) { + throw new ApiErrors(message.incorrectPassword, statusCode.badRequest); + } else { + const token = generateToken(data.id, email, data.role, data.first_name); + return successResponseWithData( + res, + statusCode.success, + message.loginSuccess, + { ...data, token } + ); + } + } catch (err) { + errorResponse(res, err.statusCode || statusCode.serverError, err); + } + }, - << - << << < HEAD - login: async(req, res) => { - try { - const { email, password } = req.body; - const validUser = await findUserByEmail(email); - if (validUser === null || validUser === undefined) { - throw new ApiErrors( - message.userEmailNotFound(email), - statusCode.notFound - ); - } - const { password: hashedPassword, ...data } = validUser.dataValues; - const validPassword = await comparePassword(password, hashedPassword); - if (!validPassword) { - throw new ApiErrors(message.incorrectPassword, statusCode.badRequest); - } else { - const token = generateToken(data.id, email, data.role, data.first_name); - return successResponseWithData( - res, - statusCode.success, - message.loginSuccess, {...data, token } - ); - } - } catch (err) { - errorResponse(res, err.statusCode || statusCode.serverError, err); - } - }, - - logout: async(req, res) => { - try { - const { token } = req; - await logoutService(token); - successResponse(res, statusCode.success, message.logoutSuccess); - } catch (err) { - errorResponse(res, statusCode.serverError, err.message); - } - }, === - === = - login: async(req, res) => { - try { - const { email, password } = req.body; - const validUser = await findUserByEmail(email); - if (validUser === null || validUser === undefined) { - throw new ApiErrors(message.userEmailNotFound(email), statusCode.notFound); - } - const { password: hashedPassword, ...data } = validUser.dataValues; - const validPassword = await comparePassword(password, hashedPassword); - if (!validPassword) { - throw new ApiErrors(message.incorrectPassword, statusCode.badRequest); - } else { - const token = generateToken(data.id, email, data.role, data.first_name); - return successResponseWithData(res, statusCode.success, message.loginSuccess, {...data, token }); - } - } catch (err) { - errorResponse(res, err.statusCode || statusCode.serverError, err); - } - }, - - logout: async(req, res) => { - try { - const { token } = req; - await logoutService(token); - successResponse(res, statusCode.success, message.logoutSuccess); - } catch (err) { - errorResponse(res, statusCode.serverError, err.message); - } - }, >>> - >>> > updating the database models, migrations and seeders files - }; + logout: async (req, res) => { + try { + const { token } = req; + await logoutService(token); + successResponse(res, statusCode.success, message.logoutSuccess); + } catch (err) { + errorResponse(res, statusCode.serverError, err.message); + } + }, +}; diff --git a/src/controllers/client.js b/src/controllers/client.js deleted file mode 100644 index a683542..0000000 --- a/src/controllers/client.js +++ /dev/null @@ -1,59 +0,0 @@ -/* eslint-disable import/named */ -/* eslint-disable require-jsdoc */ - -class ClientController { - /** - * @param {Object} req - * @param {Object} res - * @returns {Object} the new user - * @description register a new client - */ - static async getClient(req, res) { - const { user_id } = req.params; - - const message = ` - - - - - - Chat App - - - - -
-

Notify User Travels

- -
- - - - - `; - - res.send(message); - } -} - -<< -<< << < HEAD: src / controllers / profile.js -export default ProfileController; === -=== = -export default ClientController; >>> ->>> > edited the entry point and routes to test with postman: src / controllers / client.js diff --git a/src/controllers/index.js b/src/controllers/index.js index 2306abd..ea10091 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -1,6 +1,5 @@ import { authControllers } from './authControllers'; export { - authControllers, - notifyContollers -}; +authControllers +}; \ No newline at end of file diff --git a/src/controllers/notifyControllers.js b/src/controllers/notifyControllers.js deleted file mode 100644 index 614aeab..0000000 --- a/src/controllers/notifyControllers.js +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable import/named */ -/* eslint-disable require-jsdoc */ - -// import jwt from 'jsonwebtoken'; -import models from '../database/models'; -// import response from '../utils/response'; - -const { notifications } = models; - - -export const getAllNotification = async(req, res) => { - try { - const user_id = req.users.id; - const allRequests = await notifications.findAll({ where: { receiver: user_id } }); - return res.status(200).json({ status: 200, data: allRequests }); - } catch (error) { - res.status(500).json({ status: 500, error }); - } -}; - -export const readAllNotification = async(req, res) => { - try { - const user_id = req.user.id; - const allRequestsByUser = await notifications.update({ is_read: true }, { - where: { - receiver: user_id - } - }); - return res.status(200).json({ status: 200, data: allRequestsByUser }); - } catch (error) { - res.status(500).json({ status: 500, error }); - } -}; diff --git a/src/controllers/resetPassword.js b/src/controllers/resetPassword.js index fc9eb23..fd35c85 100644 --- a/src/controllers/resetPassword.js +++ b/src/controllers/resetPassword.js @@ -6,73 +6,74 @@ import { getPasswordResetURL, usePasswordHashToMakeToken, resetPasswordTemplate -} from "../modules/email" + } from "../modules/email" const { - queryByEmail, - queryById, - updatePassword -} = emailServices; + queryByEmail, + queryById, + updatePassword + } = emailServices; -/** - * Send user reset password on the application - * @static - * @param {object} req - The request object - * @param {object} res - The response object - * @return {object} JSON object representing success - */ + /** + * Send user reset password on the application + * @static + * @param {object} req - The request object + * @param {object} res - The response object + * @return {object} JSON object representing success + */ -const sendPasswordResetEmail = async(req, res) => { - const { email } = req.body - let user - try { - user = await queryByEmail(email) - } catch (err) { - res.status(404).json("No user with that email") - } - const token = usePasswordHashToMakeToken(user) - const url = getPasswordResetURL(user, token) - const emailTemplate = resetPasswordTemplate(user, url) - transporter(emailTemplate, res) - + const sendPasswordResetEmail = async (req, res) => { + const { email } = req.body + let user + try { + user = await queryByEmail(email) + } catch (err) { + res.status(404).json("No user with that email") + } + const token = usePasswordHashToMakeToken(user) + const url = getPasswordResetURL(user, token) + const emailTemplate = resetPasswordTemplate(user, url) + transporter(emailTemplate,res) + } -/** - * Update user reset password on the application - * @static - * @param {object} req - The request object - * @param {object} res - The response object - * @return {object} JSON object representing success - */ + /** + * Update user reset password on the application + * @static + * @param {object} req - The request object + * @param {object} res - The response object + * @return {object} JSON object representing success + */ -const receiveNewPassword = (req, res) => { - const { userId, token } = req.params - const { password } = req.body + const receiveNewPassword = (req, res) => { + const { userId, token } = req.params + const { password } = req.body queryById(userId) .then(user => { - const secret = user.password + "-" + user.createdAt - const payload = jwt.decode(token, secret) - if (payload.userId === user.id) { - bcrypt.genSalt(10, function(err, salt) { - if (err) return - bcrypt.hash(password, salt, function(err, hash) { - if (err) return - updatePassword(hash, userId) - .then(() => res.status(202).json("Password changed accepted")) - .catch(err => res.status(500).json(err)) - }) - }) - } + const secret = user.password + "-" + user.createdAt + const payload = jwt.decode(token, secret) + if (payload.userId === user.id) { + bcrypt.genSalt(10, function(err, salt) { + if (err) return + bcrypt.hash(password, salt, function(err, hash) { + if (err) return + updatePassword(hash,userId) + .then(() => res.status(202).json("Password changed accepted")) + .catch(err => res.status(500).json(err)) + }) + }) + } }) .catch(() => { - res.status(404).json("Invalid user") + res.status(404).json("Invalid user") }) } -export default { + export default { sendPasswordResetEmail, receiveNewPassword -} + } + diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index 4e56fcb..1eb72e2 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,49 +1,58 @@ -import socketEmission from '../services/websocket'; -import authServices from '../services/authServices'; -import travelServices from '../services/travelServices'; +import { + onewayTripService, + showManagerPendingAppr, +} from '../services/travelServices'; +import { successResponseWithData, errorResponse } from '../utils/response'; + import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; -import sendVerificationEmail from '../utils/email'; -const { oneWayTripService } = travelServices; -const { successResponseWithData, errorResponse } = response; -const { findUserById } = authServices; +export default { + createOneWayTrip: async (req, res) => { + try { + const { + origin, destination, departure_date, accommodation_id, travel_purpose + } = req.body; + const userId = req.userData.id; -const { emission } = socketEmission; + const travelObj = { + user_id: userId, + travel_type: 'one-way', + origin, + destination, + departure_date, + travel_purpose, + accommodation_id, + }; -export default { - createOneWayTrip: async(req, res) => { - try { - const { id } = req.token; - const aUser = await findUserById(id); - const { email, dept_id } = aUser; - if (!dept_id) { - errorResponse(res, statusCode.badRequest, message.lineManager); - } - const { - origin, - destination, - departure_date, - travel_purpose - } = req.body; - const userId = req.userData.id; - - const travelObj = { - user_id: userId, - origin, - destination, - departure_date, - travel_purpose - }; - - const data = await oneWayTripService(travelObj); - - const emailVerify = await sendVerificationEmail(email, - 'Travel Confirmation', message.notifyUser); - emission('here', 'we made it'); - successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, + const data = await onewayTripService(travelObj); + + successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } + }, + + pendingManagerApproval: async (req, res) => { + const { role } = req.userData; + + const { manager } = req.params; + + if (role === 'user') { + errorResponse(res, statusCode.unauthorized, message.unauthorized); + } + + try { + const requestsPending = await showManagerPendingAppr(manager); + + const filteredRequests = requestsPending.filter(request => request['user.department.line_manager'] !== null); + + const requestNumbers = filteredRequests.length; + + // eslint-disable-next-line max-len + successResponseWithData(res, statusCode.success, message.managerApproval(requestNumbers), filteredRequests); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } + } }; diff --git a/src/database/config.js b/src/database/config.js index d9e43b0..d85a733 100644 --- a/src/database/config.js +++ b/src/database/config.js @@ -1,40 +1,40 @@ require('dotenv').config(); const { - /* DATABASE_URL, */ - DB_USERNAME, - DB_PASSWORD, - DB_HOST, - DB_PORT, - DATABASE, + /* DATABASE_URL, */ + DB_USERNAME, + DB_PASSWORD, + DB_HOST, + DB_PORT, + DATABASE, } = process.env; module.exports = { - development: { - // use_env_variable: DATABASE_URL, - username: DB_USERNAME, - password: DB_PASSWORD, - database: DATABASE, - host: DB_HOST, - port: DB_PORT, - dialect: 'postgres', - }, - test: { - // use_env_variable: DATABASE_URL, - username: DB_USERNAME, - password: DB_PASSWORD, - database: DATABASE, - host: DB_HOST, - port: DB_PORT, - dialect: 'postgres', - }, - production: { - // use_env_variable: DATABASE_URL, - username: DB_USERNAME, - password: DB_PASSWORD, - database: DATABASE, - host: DB_HOST, - port: DB_PORT, - dialect: 'postgres', - }, + development: { + // use_env_variable: DATABASE_URL, + username: DB_USERNAME, + password: DB_PASSWORD, + database: DATABASE, + host: DB_HOST, + port: DB_PORT, + dialect: 'postgres', + }, + test: { + // use_env_variable: DATABASE_URL, + username: DB_USERNAME, + password: DB_PASSWORD, + database: DATABASE, + host: DB_HOST, + port: DB_PORT, + dialect: 'postgres', + }, + production: { + // use_env_variable: DATABASE_URL, + username: DB_USERNAME, + password: DB_PASSWORD, + database: DATABASE, + host: DB_HOST, + port: DB_PORT, + dialect: 'postgres', + }, }; diff --git a/src/database/migrations/20190823125926-create-department.js b/src/database/migrations/20190823125926-create-department.js new file mode 100644 index 0000000..97e5494 --- /dev/null +++ b/src/database/migrations/20190823125926-create-department.js @@ -0,0 +1,32 @@ +module.exports = { + up: function up(queryInterface, Sequelize) { + return queryInterface.createTable('departments', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + dept_name: { + type: Sequelize.TEXT + }, + line_manager: { + type: Sequelize.TEXT + }, + manager_staff_id: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: function down(queryInterface, Sequelize) { + return queryInterface.dropTable('departments'); + } +}; diff --git a/src/database/migrations/20190823125926-create-departments.js b/src/database/migrations/20190823125926-create-departments.js deleted file mode 100644 index b48f8ed..0000000 --- a/src/database/migrations/20190823125926-create-departments.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => queryInterface.createTable('departments', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - dept_name: { - type: Sequelize.TEXT - }, - line_manager: { - type: Sequelize.TEXT - }, - manager_staff_id: { - type: Sequelize.STRING - }, - line_manager_email: { - type: Sequelize.TEXT - }, - line_manager_id: { - type: Sequelize.INTEGER - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }), - down: (queryInterface, Sequelize) => queryInterface.dropTable('departments') -}; diff --git a/src/database/migrations/20190823135448-create-users.js b/src/database/migrations/20190823135448-create-users.js index cd6fa7a..d8f9e0b 100644 --- a/src/database/migrations/20190823135448-create-users.js +++ b/src/database/migrations/20190823135448-create-users.js @@ -1,82 +1,87 @@ module.exports = { - up: (queryInterface, Sequelize) => queryInterface.createTable('users', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - staff_id: { - type: Sequelize.STRING, - unique: true, - }, - first_name: { - type: Sequelize.TEXT, - allowNull: false, - validate: { - msg: 'Please provide your First Name' - } - }, - last_name: { - type: Sequelize.TEXT, - allowNull: false, - validate: { - msg: 'Please provide your Last Name' - } - }, - email: { - type: Sequelize.TEXT, - unique: true, - allowNull: true, - validate: { - msg: 'Please provide a valid email address' - } - }, - password: { - type: Sequelize.TEXT, - allowNull: true, - validate: { - msg: 'Please provide a password' - } - }, - dept_id: { - type: Sequelize.INTEGER, - }, - dob: { - type: Sequelize.DATE, - }, - gender: { - type: Sequelize.TEXT, - }, - gmail: { - type: Sequelize.STRING, - }, - facebook: { - type: Sequelize.STRING, - }, - address: { - type: Sequelize.TEXT, - }, - preferred_lang: { - type: Sequelize.TEXT, - }, - preferred_currency: { - type: Sequelize.TEXT, - }, - role: { - type: Sequelize.TEXT, - }, - is_active: { - type: Sequelize.BOOLEAN, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, + up: function up(queryInterface, Sequelize) { + return queryInterface.createTable('users', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + staff_id: { + type: Sequelize.STRING, + unique: true, + }, + first_name: { + type: Sequelize.TEXT, + allowNull: false, + validate: { + msg: 'Please provide your First Name' } - }), - down: (queryInterface, Sequelize) => queryInterface.dropTable('users') + }, + last_name: { + type: Sequelize.TEXT, + allowNull: false, + validate: { + msg: 'Please provide your Last Name' + } + }, + email: { + type: Sequelize.TEXT, + unique: true, + allowNull: true, + validate: { + msg: 'Please provide a valid email address' + } + }, + password: { + type: Sequelize.TEXT, + allowNull: true, + validate: { + msg: 'Please provide a password' + } + }, + dept_id: { + type: Sequelize.INTEGER, + references: { + model: { + tableName: 'departments', + }, + key: 'id' + } + }, + dob: { + type: Sequelize.DATE, + }, + gender: { + type: Sequelize.TEXT, + }, + address: { + type: Sequelize.TEXT, + }, + preferred_lang: { + type: Sequelize.TEXT, + }, + preferred_currency: { + type: Sequelize.TEXT, + }, + role: { + type: Sequelize.TEXT, + }, + is_active: { + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + } + }); + }, + // eslint-disable-next-line no-unused-vars + down: function down(queryInterface, Sequelize) { + return queryInterface.dropTable('users'); + } }; diff --git a/src/database/migrations/20190823140019-create-travels.js b/src/database/migrations/20190823140019-create-travels.js deleted file mode 100644 index e91e3c3..0000000 --- a/src/database/migrations/20190823140019-create-travels.js +++ /dev/null @@ -1,41 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.createTable('travels', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - user_id: { - type: Sequelize.INTEGER, - }, - origin: { - type: Sequelize.TEXT - }, - destination: { - type: Sequelize.TEXT - }, - departure_date: { - type: Sequelize.DATE - }, - return_date: { - type: Sequelize.DATE - }, - travel_purpose: { - type: Sequelize.TEXT - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }); - }, - down: (queryInterface, Sequelize) => { - return queryInterface.dropTable('travels'); - } -}; \ No newline at end of file diff --git a/src/database/migrations/20190823140048-create-accommodation.js b/src/database/migrations/20190823140048-create-accommodation.js new file mode 100644 index 0000000..79e0dd9 --- /dev/null +++ b/src/database/migrations/20190823140048-create-accommodation.js @@ -0,0 +1,36 @@ +module.exports = { + up: function up(queryInterface, Sequelize) { + return queryInterface.createTable('accommodations', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + location: { + type: Sequelize.TEXT + }, + capacity: { + type: Sequelize.INTEGER + }, + accommodation_name: { + type: Sequelize.TEXT, + allowNull: false, + validate: { + msg: 'Please provide your accommodation\'s name' + } + }, + createdAt: { + allowNull: true, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: true, + type: Sequelize.DATE + } + }); + }, + down: function down(queryInterface, Sequelize) { + return queryInterface.dropTable('accommodations'); + } +}; diff --git a/src/database/migrations/20190823140048-create-accommodations.js b/src/database/migrations/20190823140048-create-accommodations.js deleted file mode 100644 index 1fe66c4..0000000 --- a/src/database/migrations/20190823140048-create-accommodations.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.createTable('accommodations', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - location: { - type: Sequelize.TEXT - }, - capacity: { - type: Sequelize.INTEGER - }, - accommodation_name: { - type: Sequelize.TEXT, - allowNull: false, - validate: { - msg: 'Please provide your accommodation\'s name' - } - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }); - }, - down: (queryInterface, Sequelize) => { - return queryInterface.dropTable('accommodations'); - } -}; diff --git a/src/database/migrations/20190904023213-create-notifications.js b/src/database/migrations/20190904023213-create-notifications.js deleted file mode 100644 index 13247cc..0000000 --- a/src/database/migrations/20190904023213-create-notifications.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => queryInterface.createTable('notifications', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - user_id: { - allowNull: false, - type: Sequelize.INTEGER - }, - travel_id: { - allowNull: false, - type: Sequelize.INTEGER - }, - line_manager_id: { - allowNull: false, - type: Sequelize.INTEGER - }, - line_manager_email: { - allowNull: false, - type: Sequelize.STRING - }, - content: { - allowNull: false, - type: Sequelize.STRING - }, - is_read: { - allowNull: false, - type: Sequelize.BOOLEAN - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }), - down: (queryInterface) => queryInterface.dropTable('notifications') -}; diff --git a/src/database/models/departments.js b/src/database/models/departments.js deleted file mode 100644 index 5657415..0000000 --- a/src/database/models/departments.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = (sequelize, DataTypes) => { - const departments = sequelize.define('departments', { - dept_name: DataTypes.TEXT, - line_manager: DataTypes.TEXT, - line_manager_email: DataTypes.TEXT, - line_manager_id: DataTypes.INTEGER, - manager_staff_id: DataTypes.STRING, - }, {}); - - // departments.associate = (models) => { - // // associations can be defined here - // // departments.hasMany(models.notifications, { - // // foreignKey: 'manager_email' - // // }); - // }; - - return departments; -}; \ No newline at end of file diff --git a/src/database/models/notifications.js b/src/database/models/notifications.js deleted file mode 100644 index b53e6a0..0000000 --- a/src/database/models/notifications.js +++ /dev/null @@ -1,36 +0,0 @@ -module.exports = (sequelize, DataTypes) => { - const notifications = sequelize.define('notifications', { - user_id: DataTypes.INTEGER, - travel_id: DataTypes.INTEGER, - is_read: DataTypes.TEXT, - line_manager_email: DataTypes.TEXT, - line_manager_id: DataTypes.INTEGER, - content: { - type: DataTypes.STRING, - allowNull: false, - validate: { - notEmpty: { - msg: 'notification content cannot be empty' - } - } - } - }, {}); - notifications.associate = (models) => { - notifications.belongsTo(models.users, { - foreignKey: 'user_id', - onDelete: 'CASCADE' - }); - notifications.belongsTo(models.travels, { - foreignKey: 'travel_id', - onDelete: 'CASCADE' - }); - notifications.belongsTo(models.departments, { - foreignKey: 'line_manager_id' - }); - notifications.belongsTo(models.departments, { - foreignKey: 'line_manager_email' - }); - }; - - return notifications; -}; diff --git a/src/database/models/travels.js b/src/database/models/travels.js deleted file mode 100644 index 27a06bb..0000000 --- a/src/database/models/travels.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = (sequelize, DataTypes) => { - const travels = sequelize.define('travels', { - user_id: DataTypes.INTEGER, - origin: DataTypes.TEXT, - destination: DataTypes.TEXT, - departure_date: DataTypes.DATE, - return_date: DataTypes.DATE, - travel_purpose: DataTypes.TEXT - }, {}); - travels.associate = (models) => { - travels.belongsTo(models.users, { - foreignKey: 'user_id', - onDelete: 'CASCADE' - }); - }; - return travels; -}; \ No newline at end of file diff --git a/src/database/seeders/20190823204056-users.js b/src/database/seeders/20190823204056-users.js deleted file mode 100644 index 9ee4056..0000000 --- a/src/database/seeders/20190823204056-users.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = { - up: (queryInterface) => queryInterface.bulkInsert( - 'users', [{ - id: 1674946, - staff_id: 'ABD-111-8209', - first_name: 'Chidi', - last_name: 'Chuks', - email: 'chidiebere_chukwuma@yahoo.com', - password: 'every125', - dept_id: 15327458, - dob: '2019-08-09', - gender: 'Male', - address: 'Ok. This is my address', - preferred_lang: 'English', - preferred_currency: 'USD', - role: 'manager', - is_active: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: 1215739, - staff_id: 'GHD-123-9004', - first_name: 'Ngozi', - last_name: 'Nancy', - email: 'bakaretemitayo7@gmail.com', - password: 'nanevery125', - dept_id: 1536907, - dob: '2015-08-09', - gender: 'Female', - address: 'Ok. This is our address', - preferred_lang: 'English', - preferred_currency: 'USD', - role: 'requester', - is_active: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], {} - ), - - down: (queryInterface) => queryInterface.bulkDelete('users', null, {}), -}; diff --git a/src/database/seeders/20190824033354-department.js b/src/database/seeders/20190824033354-department.js new file mode 100644 index 0000000..b208731 --- /dev/null +++ b/src/database/seeders/20190824033354-department.js @@ -0,0 +1,24 @@ +module.exports = { + up: function up(queryInterface, Sequelize) { + return queryInterface.bulkInsert('departments', [{ + id: 15327458, + dept_name: 'Business Admin', + line_manager: 'Mr. Benchfort', + manager_staff_id: 'GHJ-378-2838', + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 1536907, + dept_name: 'Software Engr', + line_manager: 'Ms. Querty', + manager_staff_id: 'RDS-256-5787', + createdAt: new Date(), + updatedAt: new Date(), + }, + ], {}); + }, + down: function down(queryInterface, Sequelize) { + return queryInterface.bulkDelete('departments', null, {}); + } +}; diff --git a/src/database/seeders/20190824033354-departments.js b/src/database/seeders/20190824033354-departments.js deleted file mode 100644 index 306f117..0000000 --- a/src/database/seeders/20190824033354-departments.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.bulkInsert('departments', [{ - id: '15327458', - dept_name: 'Business Admin', - line_manager: 'Mr. Benchfort', - manager_staff_id: 'GHJ-378-2838', - line_manager_email: 'chidiebere_chukwuma@yahoo.com', - line_manager_id: 6453673, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: '1536907', - dept_name: 'Software Engr', - line_manager: 'Ms. Querty', - manager_staff_id: 'RDS-256-5787', - line_manager_email: 'chukschiboy@gmail.com', - line_manager_id: 3640773, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], {}); - }, - - down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete('departments', null, {}); - } -}; diff --git a/src/database/seeders/20190824033956-travels.js b/src/database/seeders/20190824033956-travels.js deleted file mode 100644 index 6626a0c..0000000 --- a/src/database/seeders/20190824033956-travels.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.bulkInsert('travels', [{ - id: 1898451, - user_id: 1674946, - origin: 'New York, USA', - destination: 'Paris, France', - departure_date: new Date(), - return_date: new Date(), - travel_purpose: 'This is the reason for my travel', - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: 1891029, - user_id: 1215739, - origin: 'Washington DC, USA', - destination: 'Toronto, Canada', - departure_date: new Date(), - return_date: new Date(), - travel_purpose: 'This is the most important reason for my travel', - createdAt: new Date(), - updatedAt: new Date(), - }, - ], {}); - }, - - down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete('travels', null, {}); - } -}; \ No newline at end of file diff --git a/src/database/seeders/20190824034012-accommodation.js b/src/database/seeders/20190824034012-accommodation.js new file mode 100644 index 0000000..569f9a4 --- /dev/null +++ b/src/database/seeders/20190824034012-accommodation.js @@ -0,0 +1,25 @@ +module.exports = { + up: function up(queryInterface, Sequelize) { + return queryInterface.bulkInsert('accommodations', [{ + id: 1653453, + location: 'Paris, France', + capacity: 3, + accommodation_name: 'Sheraton Protea', + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: 1332557, + location: 'Toronto, Canada', + capacity: 1, + accommodation_name: 'PAR Towers', + createdAt: new Date(), + updatedAt: new Date() + }, + ], {}); + }, + + down: function down(queryInterface, Sequelize) { + return queryInterface.bulkDelete('accommodations', null, {}); + } +}; diff --git a/src/database/seeders/20190824034012-accommodations.js b/src/database/seeders/20190824034012-accommodations.js deleted file mode 100644 index 89b43a8..0000000 --- a/src/database/seeders/20190824034012-accommodations.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - up: (queryInterface) => queryInterface.bulkInsert( - 'accommodations', [{ - id: 1653453, - location: 'Paris, France', - capacity: 3, - accommodation_name: 'Sheraton Protea', - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: 13325578, - location: 'Toronto, Canada', - capacity: 1, - accommodation_name: 'PAR Towers', - createdAt: new Date(), - updatedAt: new Date(), - }, - ], {} - ), - - down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete('accommodations', null, {}); - } -}; diff --git a/src/database/seeders/20190904024301-notifications.js b/src/database/seeders/20190904024301-notifications.js deleted file mode 100644 index 241d857..0000000 --- a/src/database/seeders/20190904024301-notifications.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => queryInterface.bulkInsert('notifications', [{ - id: 333, - user_id: 1674946, - travel_id: 1898451, - line_manager_id: 6453673, - line_manager_email: 'chidiebere_chukwuma@yahoo.com', - is_read: false, - content: 'Your travel request has been created', - createdAt: new Date(), - updatedAt: new Date() - }, - { - id: 1627, - user_id: 1215739, - travel_id: 1891029, - line_manager_id: 3640773, - line_manager_email: 'chukschiboy@gmail.com', - is_read: false, - content: 'Your travel request has been created', - createdAt: new Date(), - updatedAt: new Date() - }, - ], {}), - - down: (queryInterface, Sequelize) => queryInterface.bulkDelete('notifications', null, {}) -}; diff --git a/src/index.js b/src/index.js index b318b7b..1dd13c3 100755 --- a/src/index.js +++ b/src/index.js @@ -6,25 +6,17 @@ import logger from 'morgan'; import debug from 'debug'; import cors from 'cors'; import methodOverride from 'method-override'; -import http from 'http'; -import socketIo from 'socket.io'; + import { fbStrategy, googleStrategy } from './config/passport'; import message from './utils/messageUtils'; import response from './utils/response'; import statusCode from './utils/statusCode'; import routes from './routes/api'; -import socketEmission from './services/websocket'; - dotenv.config(); const debugLog = debug('web-app'); - // Create global app object const app = express(); -const server = http.createServer(app); - -const io = socketIo(server); -const emission = new socketEmission(io); const PORT = process.env.PORT || 5000; @@ -38,20 +30,18 @@ app.use(express.urlencoded({ extended: false })); app.use(cors()); app.options('*', cors()); - app.use(methodOverride()); - // social media authentication passport.use(fbStrategy); passport.use(googleStrategy); passport.serializeUser((user, cb) => { - cb(null, user); + cb(null, user); }); passport.deserializeUser((user, cb) => { - cb(null, user); + cb(null, user); }); @@ -64,26 +54,20 @@ app.all('/', (req, res) => response.successResponse(res, statusCode.success, mes // app.use('/', router); -// This is the point where the main API routes is served from... -app.all(`${prefix}/`, (req, res) => { - response.successResponse(res, statusCode.success, message.welcome); +app.get(`${prefix}/`, (req, res) => { + response.successResponse(res, statusCode.success, message.welcome); }); -// serve the api endpoints built in routes folder -routes(prefix, app, io); - -// app.use(routes(io)); - const isProduction = process.env.NODE_ENV === 'production'; // creating session app.use( - session({ - secret: 'authorshaven', - cookie: { maxAge: 60000 }, - resave: false, - saveUninitialized: false, - }), + session({ + secret: 'authorshaven', + cookie: { maxAge: 60000 }, + resave: false, + saveUninitialized: false, + }), ); app.use(passport.initialize()); @@ -93,9 +77,9 @@ app.use(passport.session()); // catch 404 and forward to error handler app.use((req, res, next) => { - const err = new Error('Not Found'); - err.status = 404; - next(err); + const err = new Error('Not Found'); + err.status = 404; + next(err); }); // error handlers @@ -103,48 +87,37 @@ app.use((req, res, next) => { // development error handler // will print stacktrace if (!isProduction) { - app.use((err, req, res, next) => { - debugLog(`Error Stack: ${err.stack}`); - - res.status(err.status || 500); - - res.json({ - errors: { - message: err.message, - error: err, - }, - }); - next(); - }); -} + app.use((err, req, res, next) => { + debugLog(`Error Stack: ${err.stack}`); -// production error handler -// no stack-traces leaked to user -app.use((err, req, res, next) => { res.status(err.status || 500); + res.json({ - errors: { - message: err.message, - error: {}, - }, + errors: { + message: err.message, + error: err, + }, }); next(); -}); + }); +} -server.listen(PORT, () => { - debugLog(`Barefoot-Nomad [Backend] Server is running on port ${PORT}`); +// production error handler +// no stack-traces leaked to user +app.use((err, req, res, next) => { + res.status(err.status || 500); + res.json({ + errors: { + message: err.message, + error: {}, + }, + }); + next(); }); -// Creating the client connection of Socket.io -io.on('connection', (client) => { - logger(`A client connected ${client.id}`); - client.emit('confirmation', 'We are successfully connected'); - - client.on('disconnect', () => { - logger(`A user connected ${client.id}`); - }); +app.listen(PORT, () => { + debugLog(`Barefoot-Nomad [Backend] Server is running on port ${PORT}`); }); // for testing -module.exports = server; -// module.exports = app; +export default app; diff --git a/src/models/accommodation.js b/src/models/accommodation.js index 5a807ae..142c842 100644 --- a/src/models/accommodation.js +++ b/src/models/accommodation.js @@ -1,9 +1,15 @@ module.exports = (sequelize, DataTypes) => { - const accommodations = sequelize.define('accommodations', { - location: DataTypes.TEXT, - capacity: DataTypes.INTEGER, - accommodation_name: DataTypes.TEXT - }, {}); + const accommodations = sequelize.define('accommodations', { + location: DataTypes.TEXT, + capacity: DataTypes.INTEGER, + accommodation_name: DataTypes.TEXT + }, {}); - return accommodations; + accommodations.associate = (models) => { + accommodations.hasMany(models.travel_requests, { + foreignKey: 'accommodation_id', + }); + }; + + return accommodations; }; diff --git a/src/models/users.js b/src/models/users.js index 714d829..ff0bdfa 100644 --- a/src/models/users.js +++ b/src/models/users.js @@ -1,50 +1,35 @@ import { hashSync, genSaltSync } from 'bcryptjs'; -export default (sequelize, DataTypes) => { - const salt = genSaltSync(10); - const users = sequelize.define('users', { - staff_id: DataTypes.STRING, - first_name: DataTypes.TEXT, - last_name: DataTypes.TEXT, - email: DataTypes.TEXT, - password: DataTypes.TEXT, - dept_id: DataTypes.INTEGER, - dob: DataTypes.DATE, - gender: DataTypes.TEXT, - gmail: DataTypes.STRING, - facebook: DataTypes.STRING, - address: DataTypes.TEXT, - preferred_lang: DataTypes.TEXT, - preferred_currency: DataTypes.TEXT, - role: { - type: DataTypes.TEXT, - values: [ - 'super_admin', - 'travel_admin', - 'travel_team_member', - 'manager', - 'requester' - ], - required: false - }, - is_active: DataTypes.BOOLEAN - }, {}); +module.exports = (sequelize, DataTypes) => { + const salt = genSaltSync(10); + const users = sequelize.define('users', { + staff_id: DataTypes.STRING, + first_name: DataTypes.TEXT, + last_name: DataTypes.TEXT, + email: DataTypes.TEXT, + password: DataTypes.TEXT, + dept_id: DataTypes.INTEGER, + dob: DataTypes.DATE, + gender: DataTypes.TEXT, + address: DataTypes.TEXT, + preferred_lang: DataTypes.TEXT, + preferred_currency: DataTypes.TEXT, + role: DataTypes.TEXT, + is_active: DataTypes.BOOLEAN + }, {}); - users.associate = (models) => { - users.belongsTo(models.departments, { - foreignKey: 'dept_id' - }); + users.associate = (models) => { + users.belongsTo(models.departments, { + foreignKey: 'dept_id' + }); - users.hasMany(models.travel_requests, { - foreignKey: 'user_id' - }); - }; - users.beforeCreate((incomingUser) => { - incomingUser.password = hashSync(incomingUser.password, salt); + users.hasMany(models.travel_requests, { + foreignKey: 'user_id' }); + }; + users.beforeCreate((incomingUser) => { + incomingUser.password = hashSync(incomingUser.password, salt); + }); - << - << - << < HEAD - return users; + return users; }; diff --git a/src/modules/email.js b/src/modules/email.js index 29d17ee..f6f4578 100644 --- a/src/modules/email.js +++ b/src/modules/email.js @@ -1,43 +1,42 @@ // import nodemailer from 'nodemailer'; import sgMail from '@sendgrid/mail'; +sgMail.setApiKey(process.env.SENDGRID_API); import jwt from 'jsonwebtoken'; import dotenv from 'dotenv'; - -sgMail.setApiKey(process.env.SENDGRID_API_KEY); - dotenv.config(); -export const transporter = async (msg, res) => { - try { - await sgMail.send(msg); - return res.status(200).json({ message: 'Mail sent successfully' }); - } catch (err) { - return res.status(500).json({ 'Error sending email': err }); - } -}; +export const transporter = async (msg,res) => { +try{ + await sgMail.send(msg); + return res.status(200).json({"message":"Mail sent successfully"}) +}catch(err){ + return res.status(500).json({"Error sending email":err}) +} +} + export const usePasswordHashToMakeToken = ({ - password: passwordHash, - id: userId, - createdAt + password: passwordHash, + id: userId, + createdAt }) => { - const secret = `${passwordHash - createdAt}`; - const token = jwt.sign({ userId }, secret, { - expiresIn: 3600 // 1 hour - }); - return token; + const secret = `${passwordHash - createdAt}`; + const token = jwt.sign({ userId }, secret, { + expiresIn: 3600 // 1 hour + }); + return token; }; export const getPasswordResetURL = (user, token) => `http://localhost:5000/password/reset/${user.id}/${token}`; export const resetPasswordTemplate = (user, url) => { - const from = 'chidiebere_chukwuma@yahoo.com'; - const to = user.email; - const subject = 'Barefoot Nomad Password Reset'; - const html = ` + const from = 'bakaretemitayo712@gmail.com'; + const to = user.email; + const subject = 'Barefoot Nomad Password Reset'; + const html = `

Hey ${user.name || user.email},

We heard that you lost your Barefoot nomad password. Sorry about that!

But don’t worry! You can use the following link to reset your password:

@@ -46,10 +45,5 @@ export const resetPasswordTemplate = (user, url) => {

Do something outside today!

–Your friends at Barefoot Nomad

`; - return { - from, - to, - subject, - html - }; -}; + return { from, to, subject, html } +} \ No newline at end of file diff --git a/src/routes/api/notifyRoutes.js b/src/routes/api/notifyRoutes.js deleted file mode 100644 index 7bec6e4..0000000 --- a/src/routes/api/notifyRoutes.js +++ /dev/null @@ -1,33 +0,0 @@ -import { Router } from 'express'; -// import { notifyControllers } from '../../controllers'; -import ClientController from '../../controllers/client'; -// import tokenMiddleware from '../../middlewares/tokenMiddleware'; - - -const router = Router(); -const { getClient } = ClientController; -// const { getToken, verifyToken } = tokenMiddleware; - -// api/v1/notification is already prepended to the request -// router.get('/notify', notificationController.getAllNotification); -// router.patch('/notify', notificationController.readAllNotification); - - -// router.use('/auth', auth); -router.get('/notify/:user_id', getClient); -// router.use('/onewaytrip', getToken, verifyToken); - -router.use((err, req, res, next) => { - if (err.name === 'Validation Error') { - return res.status(422).json({ - errors: Object.keys(err.errors).reduce((errors, key) => { - errors[key] = err.errors[key].message; - return errors; - }, {}) - }); - } - return next(err); -}); - - -export default router; diff --git a/src/routes/api/travelRoute.js b/src/routes/api/travelRoute.js index 6336f37..b49f7e8 100644 --- a/src/routes/api/travelRoute.js +++ b/src/routes/api/travelRoute.js @@ -11,4 +11,7 @@ const { validateTravelRequest, validateResult } = travelValidator; // handles the api home route... route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); -export default route; \ No newline at end of file +// handles manager pending req approvals route +route.get('/requests/pending/:manager', getToken, verifyToken, pendingManagerApproval); + +export default route; diff --git a/src/routes/authRoutes.js b/src/routes/authRoutes.js index bfdf5c8..962f070 100644 --- a/src/routes/authRoutes.js +++ b/src/routes/authRoutes.js @@ -4,18 +4,13 @@ import passport from 'passport'; import authControllers from '../../controllers/authControllers'; import resetPassword from '../../controllers/resetPassword'; import authValidator from '../../validation/authValidation'; -import tokenMiddlewares from '../../middlewares/tokenMiddleware'; +import { getToken, verifyToken } from '../../middlewares/tokenMiddleware'; const { sendPasswordResetEmail, receiveNewPassword } = resetPassword; const route = Router(); -const { - signup, - fbgooglesignup, - login, - logout -} = authControllers; +const { signup, fbgooglesignup, login, logout} = authControllers; const { validateLogin, validateSignup, validateResult } = authValidator; // handles the api home route... @@ -24,24 +19,24 @@ route.post('/auth/signup', validateSignup, validateResult, signup); // handles social media authentication route.get('/auth/signup/facebook', - passport.authenticate('facebook')); + passport.authenticate('facebook')); route.get('/auth/signup/facebook/callback', - passport.authenticate('facebook', { - failureRedirect: '/auth/signup', - successRedirect: '/requests', - })); + passport.authenticate('facebook', { + failureRedirect: '/auth/signup', + successRedirect: '/requests', + })); route.get('/auth/signup/google', - passport.authenticate('google', { scope: ['profile', 'email'] })); + passport.authenticate('google', { scope: ['profile', 'email'] })); route.get('/auth/signup/google/callback', - passport.authenticate('google', { - failureRedirect: '/auth/signup', - successRedirect: '/requests', - })); + passport.authenticate('google', { + failureRedirect: '/auth/signup', + successRedirect: '/requests', + })); -// route path subject to change + // route path subject to change route.get('/requests', fbgooglesignup); // handles the sign in request by email and password.. @@ -50,8 +45,8 @@ route.post('/auth/login', validateLogin, validateResult, login); route.post('/auth/logout', getToken, verifyToken, logout); -route.post('/forgot', sendPasswordResetEmail); +route.post('/forgot',sendPasswordResetEmail); -route.post('/receive_new_password/:userId/:token', receiveNewPassword); +route.post('/receive_new_password/:userId/:token',receiveNewPassword); export default route; diff --git a/src/routes/index.js b/src/routes/index.js index 59c0f32..727e9ea 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -3,10 +3,8 @@ import travel from './travelRoute'; import comment from './commentRoutes'; - export default (prefix, app) => { - app.use(prefix, auth); - app.use(prefix, travel); - app.use(prefix, comment); - app.use(prefix, notify); + app.use(prefix, auth); + app.use(prefix, travel); + app.use(prefix, comment); }; diff --git a/src/services/authServices.js b/src/services/authServices.js index 474bb6d..3d55d0d 100644 --- a/src/services/authServices.js +++ b/src/services/authServices.js @@ -6,72 +6,54 @@ import models from '../models'; const { users, blacklists } = models; -export default { - signupService: async(userObj) => { - try { - const userRes = await users.create(userObj); - - return userRes; - - - } catch (err) { - throw err; - } - }, - // subject to changes - findUserById: async(userId) => { - try { - return await users.findAll({ - where: { - id: userId - }, - }); - } catch (err) { - throw err; - } - }, - findUserById: async(id) => { - try { - return await users - .findOne({ - where: { id }, - }); - } catch (err) { - throw err; - } - }, - - updateUserById: async(hash, id) => { - try { - return await users - .findOne(hash, { - where: { id }, - }); - } catch (err) { - throw err; - } - }, - /** - *This function will get a user by email address... - *@param {String} email - the user's email - *@return {Promise} - response of sequelize - */ - findUserByEmail: (email) => users.findOne({ where: { email } }), - - /** - *This function will compare the password supplied by the user with the one in the database... - *@param {String} password - the user's password supplied - *@param {String} hashedPassword - the user's password in database - *@return {boolean} - response of bcrypt hashing - */ - comparePassword: (password, hashedPassword) => compareSync(password, hashedPassword), - - logoutService: async(token) => { - try { - return await blacklists.create({ expired_tokens: token }) - } catch (err) { - throw err; - } - } +export const signupService = async (userObj) => { + try { + const userRes = await users.create(userObj); + + return userRes; + } catch (err) { + throw err; + } +}; +// subject to changes +export const findUserById = async (id) => { + try { + return await users.findOne({ + where: { id }, + }); + } catch (err) { + throw err; + } +}; +export const updateUserById = async (hash, id) => { + try { + return await users.findOne(hash, { + where: { id }, + }); + } catch (err) { + throw err; + } +}; +/** + *This function will get a user by email address... + *@param {String} email - the user's email + *@return {Promise} - response of sequelize + */ +export const findUserByEmail = (email) => users.findOne({ where: { email } }); + +/** + *This function will compare the password supplied by the user with the one in the database... + *@param {String} password - the user's password supplied + *@param {String} hashedPassword - the user's password in database + *@return {boolean} - response of bcrypt hashing + */ +export const comparePassword = (password, hashedPassword) => compareSync(password, hashedPassword); + +export const logoutService = async (token) => { + try { + return await blacklists.create({ expired_tokens: token }); + } catch (err) { + throw err; + } }; diff --git a/src/services/deptServices.js b/src/services/deptServices.js deleted file mode 100644 index 51482d0..0000000 --- a/src/services/deptServices.js +++ /dev/null @@ -1,43 +0,0 @@ -import models from '../database/models'; - -const { departments } = models; - - -/** - * Helper function to find a user by email - * @param {String} email - line-manager's email - * @returns {Promise} - sequelize response - */ -export const findManagerByEmail = async(email) => { - try { - return await departments.findOne({ where: { line_manager_email: email } }); - } catch (err) { - throw err; - } - } - /** - * Helper function to find a user by id - * @param {String} id - user's id - * @returns {Promise} - sequelize response - */ -export const findDeptById = async(id) => { - try { - return await users.findOne({ where: { id } }); - } catch (err) { - throw err - } -} - -/** - * Helper function to update a user password - * @param {String} hash - user's password - * @param {String} id - user's id - * @returns {Promise} - sequelize response - */ -export const updatePassword = async(hash, id) => { - try { - return await users.update(hash, { where: { id } }); - } catch (err) { - throw err - } -} \ No newline at end of file diff --git a/src/services/emailServices.js b/src/services/emailServices.js index bf97f2b..1753773 100644 --- a/src/services/emailServices.js +++ b/src/services/emailServices.js @@ -8,25 +8,25 @@ const { users } = models; * @param {String} email - user's email * @returns {Promise} - sequelize response */ -const queryByEmail = async (email) => { - try { - return await users.findOne({ where: { email } }); - } catch (err) { - throw err; - } -}; -/** +const queryByEmail = async(email) => { + try { + return await users.findOne({ where: { email } }); + } catch (err) { + throw err; + } + } + /** * Helper function to find a user by id * @param {String} id - user's id * @returns {Promise} - sequelize response */ -const queryById = async (id) => { - try { - return await users.findOne({ where: { id } }); - } catch (err) { - throw err; - } -}; +const queryById = async(id) => { + try { + return await users.findOne({ where: { id } }); + } catch (err) { + throw err + } +} /** * Helper function to update a user password @@ -34,16 +34,16 @@ const queryById = async (id) => { * @param {String} id - user's id * @returns {Promise} - sequelize response */ -const updatePassword = async (hash, id) => { - try { - return await users.update(hash, { where: { id } }); - } catch (err) { - throw err; - } -}; +const updatePassword = async(hash, id) => { + try { + return await users.update(hash, { where: { id } }); + } catch (err) { + throw err + } +} export default { - queryByEmail, - queryById, - updatePassword + queryByEmail, + queryById, + updatePassword }; diff --git a/src/services/notifyServices.js b/src/services/notifyServices.js deleted file mode 100644 index 137e1ef..0000000 --- a/src/services/notifyServices.js +++ /dev/null @@ -1,24 +0,0 @@ -import Model from '../database/models'; - -const { notifications } = Model; - -// eslint-disable-next-line import/prefer-default-export -export const createNotification = async(notifications) => { - try { - const makeNotification = await notifications.create(notifications); - return makeNotification; - } catch (error) { - return false; - } -}; - -export const getSpecificTrips = async(id) => { - try { - const theTravels = await notifications.findOne({ - where: { line_manager_id: id } - }); - return theTravels; - } catch (error) { - return false; - } -} \ No newline at end of file diff --git a/src/services/travelServices.js b/src/services/travelServices.js index a22043b..076c952 100644 --- a/src/services/travelServices.js +++ b/src/services/travelServices.js @@ -5,24 +5,51 @@ import models from '../models'; const { travel_requests, departments, users } = models; -export default { - oneWayTripService: async(travelObj) => { - try { - return await travels.create(travelObj); - } catch (err) { - throw err; - } - }, - findTravelById: async(id) => { - try { - return await travels.findOne({ - attributes: ['id'], - where: { id }, - }); - } catch (err) { - throw err; - } - }, +export const onewayTripService = async (travelObj) => { + try { + return await travel_requests.create(travelObj); + } catch (err) { + throw err; + } +}; + +export const findTravelById = async (id) => { + try { + return await travel_requests.findOne({ + attributes: ['id', 'user_id'], + where: { id }, + }); + } catch (err) { + throw err; + } +}; + +export const showManagerPendingAppr = async (manager) => { + try { + return await travel_requests.findAll({ + where: { + approval_status: 'pending', + }, + include: [ + { + model: users, + attributes: ['first_name', 'last_name'], + include: [ + { + model: departments, + attributes: ['dept_name', 'line_manager'], + where: { + line_manager: manager, + }, + }, + ], + }, + ], + raw: true, + }); + } catch (err) { + throw err; + } }; export const showUsertravelsStatus = async (userId) => { diff --git a/src/services/websocket.js b/src/services/websocket.js deleted file mode 100644 index 562df72..0000000 --- a/src/services/websocket.js +++ /dev/null @@ -1,33 +0,0 @@ -import autoBind from 'auto-bind'; - -let socketPlug = null; -/** - * - * - * @class socketEmission - */ -class socketEmission { - // eslint-disable-next-line valid-jsdoc - /** - *Creates an instance of socketEmission. - @param {} io - * @memberof socketEmission - */ - constructor(io) { - socketPlug = io; - autoBind(this); - } - - /** - *@description A function that handles multicity travel request by a user - * @static - * @param {Object} eventName - * @param {Object} eventMessage - * @returns {object} Details of booked trips - * @memberof Trips - */ - static async emission(eventName, eventMessage) { - return socketPlug.emit(eventName, eventMessage); - } -} -export default socketEmission; diff --git a/src/tests/authTest.js b/src/tests/authTest.js new file mode 100644 index 0000000..6e618bf --- /dev/null +++ b/src/tests/authTest.js @@ -0,0 +1,357 @@ +/* eslint-disable prefer-object-spread */ +import chai, { expect } from 'chai'; +import chaiHttp from 'chai-http'; +import dotenv from 'dotenv'; + +import app from '../index'; + +const prefix = '/api/v1'; + +let passwordUserId; +const passwordResetToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImlhdCI6MTU2NzUzNzkwNSwiZXhwIjoxNTY3NTQxNTA1fQ.nPMaVY0-y_FhF9eVroUIe08PXW9kqnmmqUvAcu8uD74'; + + +dotenv.config(); + +chai.use(chaiHttp); + +describe('Test for the Auth controller functions', () => { + const user = { + first_name: 'Emma', + last_name: 'Korede', + email: 'emma.k@yahoo.com', + password: 'testing123', + }; + + it('should successfully sign up a user', (done) => { + chai + .request(app) + .post(`${prefix}/auth/signup`) + .send(user) + .end((err, res) => { + const { data } = res.body; + + expect(res).to.have.status(201); + expect(data).to.include({ + first_name: 'Emma', + last_name: 'Korede', + email: 'emma.k@yahoo.com', + }); + done(); + }); + }); + + it('should return an error message if the email is empty', (done) => { + const mutatedUser = Object.assign({}, user); + delete mutatedUser.email; + + chai.request(app) + .post(`${prefix}/auth/signup`) + .send(mutatedUser) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to + .equal('Email cannot be empty.'); + done(); + }); + }); + it('should return an error message if the email is invalid', (done) => { + const mutatedUser = Object.assign({}, user); + mutatedUser.email = 'invalid@yahoo'; + + chai.request(app) + .post(`${prefix}/auth/signup`) + .send(mutatedUser) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to + .equal('Please, enter a valid email address.'); + done(); + }); + }); + it('should return an error message if the email already exists', (done) => { + chai.request(app) + .post(`${prefix}/auth/signup`) + .send(user) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to + .equal(`User with this email (${user.email}) already exist.`); + done(); + }); + }); + it('should return an error message if the password length is less than 8', (done) => { + const mutatedUser = Object.assign({}, user); + mutatedUser.password = 'test'; + mutatedUser.email = 'valid@yahoo.com'; + + chai.request(app) + .post(`${prefix}/auth/signup`) + .send(mutatedUser) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to + .equal('The length of the password must be 8 and above.'); + done(); + }); + }); + it('should return an error message if the password does not contain at least a digit', (done) => { + const mutatedUser = Object.assign({}, user); + mutatedUser.password = 'testingit'; + mutatedUser.email = 'valid@yahoo.com'; + + chai.request(app) + .post(`${prefix}/auth/signup`) + .send(mutatedUser) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to + .equal('Password must contain at least one digit.'); + done(); + }); + }); + it('should return an error message if the first name is empty', (done) => { + const mutatedUser = Object.assign({}, user); + mutatedUser.first_name = ''; + mutatedUser.email = 'valid@yahoo.com'; + + chai.request(app) + .post(`${prefix}/auth/signup`) + .send(mutatedUser) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to + .equal('First name cannot be empty.'); + done(); + }); + }); + it('should return an error message if the last name is empty', (done) => { + const mutatedUser = Object.assign({}, user); + mutatedUser.last_name = ''; + mutatedUser.email = 'valid@yahoo.com'; + + chai.request(app) + .post(`${prefix}/auth/signup`) + .send(mutatedUser) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to + .equal('Last name cannot be empty.'); + done(); + }); + }); +}); + + +describe('Testing logout feature', () => { + // This is the tests that will run for the user signin with username and password.. + describe('TEST USER LOGIN ROUTE', () => { + const signinRoute = `${prefix}/auth/login`; + + const loginData = { + email: 'emma.k@yahoo.com', + password: 'testing123' + }; + + it('should throw an error with a status of 400 if the email supplied is invalid', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.email = 'invalidemail'; + + chai.request(app) + .post(`${prefix}/auth/login`) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal('Please, enter a valid email address.'); + done(); + }); + }); + + it('should throw an error with a status of 404 if the email supplied does not exist', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.email = 'testerroremail@yahoo.com'; + + chai + .request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { status } = res; + expect(status).to.be.eql(404); + done(err); + }); + }); + + it('should return an error message if the password length is less than 8', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'pwdless'; + + chai.request(app) + .post(`${prefix}/auth/login`) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal('The length of the password must be 8 and above.'); + done(err); + }); + }); + + it('should return an error message if the password does not contain at least a digit', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'nodigitpwd'; + + chai.request(app) + .post(`${prefix}/auth/login`) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal('Password must contain at least one digit.'); + done(err); + }); + }); + + it('should throw an error with a status of 400 if the password supplied is wrong', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'passw4567'; + + chai + .request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.be.eql(400); + expect(body.error.message).to + .equal('Sorry, the password entered is not correct.'); + done(err); + }); + }); + + it('should authenticate a user with a valid email and password', (done) => { + chai + .request(app) + .post(signinRoute) + .send(loginData) + .end((err, res) => { + const { body, status } = res; + expect(body.data).to.not.eql(null); + expect(status).to.be.eql(200); + done(err); + }); + }); + + it('should contain a token value in its response data object', (done) => { + chai.request(app) + .post(signinRoute) + .send(loginData) + .end((err, res) => { + const { data } = res.body; + expect(data).to.have.ownProperty('token'); + done(err); + }); + }); + }); +}); +// The test for the auth/login by email and paswword ends here... + +describe('Testing logout feature', () => { + const testuser = { + first_name: 'Emmatesto', + last_name: 'Koredetesto', + email: 'emmaff.ki@yahoo.com', + password: 'testing321', + }; + let token; + before((done) => { + chai + .request(app) + .post(`${prefix}/auth/signup`) + .send(testuser) + .end((err, res) => { + const { data } = res.body; + token = data.token; + done(); + }); + }); + + it('should return an error if token is not supplied', (done) => { + chai.request(app) + .post(`${prefix}/auth/logout`) + .end((err, res) => { + expect(res.status).to.equal(401); + done(); + }); + }); + it('should return an error if the token is invalid', (done) => { + chai.request(app) + .post(`${prefix}/auth/logout`) + .set('Authorization', 'Bearer hjgvju') + .end((err, res) => { + expect(res.status).to.equal(401); + done(); + }); + }); + it('should successfully logout a user', (done) => { + chai.request(app) + .post(`${prefix}/auth/logout`) + .set('Authorization', `Bearer ${token}`) + .end((err, res) => { + expect(res.status).to.equal(200); + done(); + }); + }); +}); + +describe('Send Password Reset', () => { + const testuser = { + first_name: 'Temi', + last_name: 'Bakar', + email: 'bakaretemitayo@gmail.com', + password: 'testing321', + }; + let email; + before((done) => { + chai + .request(app) + .post(`${prefix}/auth/signup`) + .send(testuser) + .end((err, res) => { + const { data } = res.body; + email = data.email; + passwordUserId = data.id; + done(); + }); + }); + + /* it('it should send token for resetting password', (done) => { + // eslint-disable-next-line quote-props + const user_email = { 'email': email }; + chai.request(app) + .post(`${prefix}/forgot`) + .send(user_email) + .end((err, res) => { + expect(res.status).to.equal(200); + expect(user_email).to.have.property('email'); + done(); + }); + }); */ + + + it('it should reset password via password reset link', (done) => { + const passwordResetData = { password: 'testpassword' }; + chai.request(app) + .post(`${prefix}/receive_new_password/${passwordUserId}/${passwordResetToken}`) + .send(passwordResetData) + .end((err, res) => { + expect(res.status).to.equal(202); + expect(passwordResetData).to.have.property('password'); + done(); + }); + }); +}); diff --git a/src/tests/mocks/users.js b/src/tests/mocks/users.js deleted file mode 100644 index 61a3f1a..0000000 --- a/src/tests/mocks/users.js +++ /dev/null @@ -1,10 +0,0 @@ -export default { - id: 1674946, - staff_id: 'ABD-111-8209', - first_name: 'Chidi', - last_name: 'Chuks', - email: 'chidiebere_chukwuma@yahoo.com', - password: 'every125', - dept_id: 15327458, - role: 'line_manager' -}; \ No newline at end of file diff --git a/src/utils/email.js b/src/utils/email.js index d7e8961..b67855b 100644 --- a/src/utils/email.js +++ b/src/utils/email.js @@ -1,44 +1,51 @@ require('dotenv').config(); const sendGrid = require('sendgrid').mail; -const sg = require('sendgrid')(process.env.SENDGRID_API_KEY); +const sg = require('sendgrid')(process.env.SENDGRID_API); let hostUrl; const devHostUrl = 'http://localhost:5000'; const prodHostUrl = 'https://archangel-backend-staging.herokuapp.com/'; const sendVerificationEmail = (to) => { - if (process.env.NODE_ENV === 'development') { - hostUrl = devHostUrl; - } else { - hostUrl = prodHostUrl; - } + if (process.env.NODE_ENV === 'development') { + hostUrl = devHostUrl; + } else { + hostUrl = prodHostUrl; + } const request = sg.emptyRequest({ - method: "POST", - path: "/v3/mail/send", - body: { - personalizations: [{ - to: [{ - email: to - }], - subject: "Verify Your Email" - }], - from: { - email: "barefoot.nomad.archangel@gmail.com" - }, - content: [{ - type: 'text/plain', - value: `Click on this link to verify your email ${hostUrl}` - }] - } + method: "POST", + path: "/v3/mail/send", + body: { + personalizations: [ + { + to: [ + { + email: to + } + ], + subject:"Verify Your Email" + } + ], + from: { + email: "barefoot.nomad.archangel@gmail.com" + }, + content: [ + { + type: 'text/plain', + value: `Click on this link to verify your email ${hostUrl}` + } + ] + } }); return new Promise((resolve, reject) => { - sg.API(request, (error, response) => { - if (error) { - return reject(error); - } else { - return resolve(response); - } - }); + sg.API(request, (error, response) => { + if (error) { + return reject(error); + } + else { + return resolve(response); + } + }); }); -}; + }; export default sendVerificationEmail; diff --git a/src/utils/messageUtils.js b/src/utils/messageUtils.js index 90f7519..72d7e5b 100644 --- a/src/utils/messageUtils.js +++ b/src/utils/messageUtils.js @@ -1,58 +1,49 @@ // This function handles messages export default { - defaultWelcome: [ - 'Welcome to Barefoot Nomad server.', - 'use /api/v1 as the base path url for the APIs of this app.', - ], - welcome: 'Welcome to Archangel Barefoot Nomad Web App API.', - signupSuccess: (email) => `You have successfully registered with this email, ${email}.`, - verificationMessage: (hostUrl) => `Click on this link to verify your email ${hostUrl}`, - oneWayTripCreated: 'Your request has been successfully created', - managerApproval: (pendingReq) => `You have ${pendingReq} requests requiring your approval`, - managerNotFound: "Manager's detail missing", - noEmail: 'Email cannot be empty.', - // sign-up validation messages - invalidEmail: 'Please, enter a valid email address.', - usedEmail: (email) => `User with this email (${email}) already exist.`, - shortPassword: 'The length of the password must be 8 and above.', - noDigitInPassword: 'Password must contain at least one digit.', - emptyFirstname: 'First name cannot be empty.', - emptyLastname: 'Last name cannot be empty.', - notifyUser: 'Your travel request has been successfully created and it is awaiting approval', - lineManager: 'Line manager must be present to continue', - emptyOrigin: 'You must state your current city.', - emptyDestination: 'You must state your destination', - emptyDepartureDate: 'You must state your departure date', - emptyReturnDate: 'You must state your return date', - emptyTravelPurpose: 'You must state your travel purpose', - lettersAlone: 'Only letters are allowed', - unauthorized: 'Not authorized.', - invalidToken: 'Invalid Token, please login.', - logoutSuccess: 'Logged out successfully.', - incorrectPassword: 'Sorry, the password entered is not correct.', - loginSuccess: 'You have been logged in sucessfully.', - userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, - userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.`, + defaultWelcome: [ + 'Welcome to Barefoot Nomad server.', + 'use /api/v1 as the base path url for the APIs of this app.', + ], + welcome: 'Welcome to Archangel Barefoot Nomad Web App API.', + signupSuccess: (email) => `You have successfully registered with this email, ${email}.`, + oneWayTripCreated: 'Your request has been successfully created', + managerApproval: (pendingReq) => `You have ${pendingReq} requests requiring your approval`, + managerNotFound: "Manager's detail missing", + noEmail: 'Email cannot be empty.', + // sign-up validation messages + invalidEmail: 'Please, enter a valid email address.', + usedEmail: (email) => `User with this email (${email}) already exist.`, + shortPassword: 'The length of the password must be 8 and above.', + noDigitInPassword: 'Password must contain at least one digit.', + emptyFirstname: 'First name cannot be empty.', + emptyLastname: 'Last name cannot be empty.', + emptyOrigin: 'You must state your current city.', + emptyDestination: 'You must state your destination', + emptyDepartureDate: 'You must state your departure date', + emptyReturnDate: 'You must state your return date', + emptyTravelPurpose: 'You must state your travel purpose', + lettersAlone: 'Only letters are allowed', + unauthorized: 'Not authorized.', + invalidToken: 'Invalid Token, please login.', + logoutSuccess: 'Logged out successfully.', + incorrectPassword: 'Sorry, the password entered is not correct.', + loginSuccess: 'You have been logged in sucessfully.', + userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, + userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.`, - noEmail: 'Email cannot be empty.', - // sign-up validation messages - invalidEmail: 'Please, enter a valid email address.', - usedEmail: (email) => `User with this email (${email}) already exist.`, - shortPassword: 'The length of the password must be 8 and above.', - noDigitInPassword: 'Password must contain at least one digit.', - emptyFirstname: 'First name cannot be empty.', - emptyLastname: 'Last name cannot be empty.', - emptyOrigin: 'You must state your current city.', - emptyDestination: 'You must state your destination', - emptyDepartureDate: 'You must state your departure date', - emptyReturnDate: 'You must state your return date', - emptyTravelPurpose: 'You must state your travel purpose', - lettersAlone: 'Only letters are allowed', - unauthorized: 'Not authorized.', - invalidToken: 'Invalid Token, please login.', - logoutSuccess: 'Logged out successfully.', - incorrectPassword: 'Sorry, the password entered is not correct.', - loginSuccess: 'You have been logged in successfully.', - userEmailNotFound: (email) => `Sorry, there is no user with email ${email} in the database.`, - userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.` + // comment messages + successComment: [ + 'You have successfully commented on a travel request.', + 'You have successfully retrieved all comments for this travel request.', + ], + unregisteredEmail: (email) => `User with this email (${email}) not found in our database.`, + emptyEmail: 'Email cannot be empty.', + invalidTravelId: 'The travel ID must be an integer value.', + travelNotFound: 'The travel request does not exist.', + unauthorizedAccessToTravel: + 'Access denied. Accessible only by travel requester or his/her line manager.', + emptyComment: 'comment cannot be empty.', + unauthorizedCommentDelete: "comment can only be deleted by it's author", + commentNotFound: 'The comment does not exist.', + deleteComment: 'Comment successfully deleted.', }; diff --git a/src/utils/notifyEmailUtils.js b/src/utils/notifyEmailUtils.js deleted file mode 100644 index 6187f0e..0000000 --- a/src/utils/notifyEmailUtils.js +++ /dev/null @@ -1,9 +0,0 @@ -const emailBody = (userDetails, travelInfo) => { - const { - first_name, - last_name - } = userDetails; - const { destination, departure_date, return_date } => { - - } -} diff --git a/src/utils/statusCode.js b/src/utils/statusCode.js index dfe48f5..8d3737e 100644 --- a/src/utils/statusCode.js +++ b/src/utils/statusCode.js @@ -1,9 +1,8 @@ export default { - success: 200, - created: 201, - badRequest: 400, - - notFound: 404, - unauthorized: 401, - serverError: 500 + success: 200, + created: 201, + badRequest: 400, + notFound: 404, + unauthorized: 401, + serverError: 500 }; From 250f35d1f584a31b28a6e09a5a4e66720a2ce665 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Fri, 13 Sep 2019 13:14:21 +0100 Subject: [PATCH 15/23] updating the database --- .vscode/settings.json | 5 + package-lock.json | 304 ++++++++++++++++++ package.json | 2 + src/controllers/index.js | 4 +- src/controllers/notifyControllers.js | 31 ++ .../20190912134053-create-notifications.js | 41 +++ src/database/models/notifications.js | 40 +++ src/database/seeders/20190908211400-users.js | 77 +++-- .../seeders/20190912140255-notifications.js | 31 ++ src/models/comment.js | 4 +- src/models/department.js | 4 +- src/models/index.js | 6 +- src/models/travel_request.js | 5 + 13 files changed, 506 insertions(+), 48 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/controllers/notifyControllers.js create mode 100644 src/database/migrations/20190912134053-create-notifications.js create mode 100644 src/database/models/notifications.js create mode 100644 src/database/seeders/20190912140255-notifications.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..73c42cb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "editor.formatOnSaveTimeout": 0, + "editor.tabSize": 2, + "editor.wordWrap": "on" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6ae0639..b7ce252 100644 --- a/package-lock.json +++ b/package-lock.json @@ -967,6 +967,11 @@ "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=" }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -1122,6 +1127,11 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -1169,6 +1179,11 @@ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, "async.ensureasync": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.ensureasync/-/async.ensureasync-0.5.2.tgz", @@ -1579,6 +1594,11 @@ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1639,6 +1659,16 @@ } } }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + }, "base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", @@ -1672,12 +1702,25 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "bluebird": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", @@ -1866,6 +1909,11 @@ "unset-value": "^1.0.0" } }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2092,11 +2140,21 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2553,6 +2611,89 @@ "once": "^1.4.0" } }, + "engine.io": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", + "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~6.1.0" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-client": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", + "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4242,6 +4383,26 @@ "ansi-regex": "^2.0.0" } }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -4387,6 +4548,11 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, "inflection": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", @@ -5723,6 +5889,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -6007,6 +6178,22 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -7135,6 +7322,100 @@ } } }, + "socket.io": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", + "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.3.1", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.2.0", + "socket.io-parser": "~3.3.0" + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7477,6 +7758,11 @@ "os-tmpdir": "~1.0.2" } }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -8067,12 +8353,25 @@ "signal-exit": "^3.0.2" } }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -8251,6 +8550,11 @@ } } } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } } } diff --git a/package.json b/package.json index e6a5021..158e123 100755 --- a/package.json +++ b/package.json @@ -55,6 +55,8 @@ "sendgrid": "^5.2.3", "sequelize": "^5.15.2", "sequelize-cli": "^5.5.0", + "socket.io": "^2.2.0", + "socket.io-client": "^2.2.0", "underscore": "^1.9.1" }, "devDependencies": { diff --git a/src/controllers/index.js b/src/controllers/index.js index ea10091..7668124 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -1,5 +1,5 @@ import { authControllers } from './authControllers'; export { -authControllers -}; \ No newline at end of file + authControllers, +}; diff --git a/src/controllers/notifyControllers.js b/src/controllers/notifyControllers.js new file mode 100644 index 0000000..ac9e4d0 --- /dev/null +++ b/src/controllers/notifyControllers.js @@ -0,0 +1,31 @@ +/* eslint-disable require-jsdoc */ +import models from '../database/models'; + +const { notifications } = models; + +export default { + + getAllNotification: async (req, res) => { + try { + const user_id = req.users.id; + const allRequests = await notifications.findAll({ where: { receiver: user_id } }); + return res.status(200).json({ status: 200, data: allRequests }); + } catch (error) { + res.status(500).json({ status: 500, error }); + } + }, + + readAllNotification: async (req, res) => { + try { + const user_id = req.user.id; + const allRequestsByUser = await notifications.update({ is_read: true }, { + where: { + receiver: user_id + } + }); + return res.status(200).json({ status: 200, data: allRequestsByUser }); + } catch (error) { + res.status(500).json({ status: 500, error }); + } + }, +}; diff --git a/src/database/migrations/20190912134053-create-notifications.js b/src/database/migrations/20190912134053-create-notifications.js new file mode 100644 index 0000000..c9ccffd --- /dev/null +++ b/src/database/migrations/20190912134053-create-notifications.js @@ -0,0 +1,41 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('notifications', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + user_id: { + type: Sequelize.INTEGER + }, + travel_id: { + type: Sequelize.INTEGER + }, + is_read: { + type: Sequelize.BOOLEAN + }, + line_manager_email: { + type: Sequelize.TEXT + }, + line_manager_id: { + type: Sequelize.INTEGER + }, + message: { + type: Sequelize.TEXT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('notifications'); + } +}; diff --git a/src/database/models/notifications.js b/src/database/models/notifications.js new file mode 100644 index 0000000..9cfcd81 --- /dev/null +++ b/src/database/models/notifications.js @@ -0,0 +1,40 @@ +module.exports = (sequelize, DataTypes) => { + const notifications = sequelize.define('notifications', { + user_id: DataTypes.INTEGER, + travel_id: DataTypes.INTEGER, + is_read: DataTypes.TEXT, + line_manager_email: DataTypes.TEXT, + line_manager_id: DataTypes.INTEGER, + message: { + type: DataTypes.TEXT, + allowNull: false, + validate: { + notEmpty: { + msg: 'notification content cannot be empty' + } + } + } + }, {}); + notifications.associate = (models) => { + notifications.belongsTo(models.users, { + foreignKey: 'user_id', + onDelete: 'CASCADE' + }); + + notifications.belongsTo(models.travel_requests, { + foreignKey: 'travel_id', + onDelete: 'CASCADE' + }); + + notifications.hasMany(models.departments, { + foreignKey: 'line_manager_id', + onDelete: 'CASCADE' + }); + + notifications.hasMany(models.departments, { + foreignKey: 'line_manager_email', + onDelete: 'CASCADE' + }); + }; + return notifications; +}; diff --git a/src/database/seeders/20190908211400-users.js b/src/database/seeders/20190908211400-users.js index bf4ed26..7701013 100644 --- a/src/database/seeders/20190908211400-users.js +++ b/src/database/seeders/20190908211400-users.js @@ -3,46 +3,43 @@ const { hashSync, genSaltSync } = require('bcryptjs'); module.exports = { up: function up(queryInterface, Sequelize) { return queryInterface.bulkInsert( - 'users', - [ - { - id: 1674946, - staff_id: 'ABD-111-8209', - first_name: 'Peter', - last_name: 'Chidi', - email: 'petchidi@yahoo.com', - password: hashSync('testing123', genSaltSync(10)), - dept_id: 15327458, - dob: '2019-08-09', - gender: 'Male', - address: 'Ok. This is my address', - preferred_lang: 'English', - preferred_currency: 'USD', - role: 'processed', - is_active: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: 1215739, - staff_id: 'GHD-123-9004', - first_name: 'Ngozi', - last_name: 'Nancy', - email: 'nancngo@gmail.com', - password: hashSync('testing123', genSaltSync(10)), - dept_id: 1536907, - dob: '2015-08-09', - gender: 'Female', - address: 'Ok. This is our address', - preferred_lang: 'English', - preferred_currency: 'USD', - role: 'processed', - is_active: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], - {} + 'users', [{ + id: 1674946, + staff_id: 'ABD-111-8209', + first_name: 'Peter', + last_name: 'Chidi', + email: 'petchidi@yahoo.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 15327458, + dob: '2019-08-09', + gender: 'Male', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'processed', + is_active: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 1215739, + staff_id: 'GHD-123-9004', + first_name: 'Ngozi', + last_name: 'Nancy', + email: 'nancngo@gmail.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 1536907, + dob: '2015-08-09', + gender: 'Female', + address: 'Ok. This is our address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'processed', + is_active: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + ], {} ); }, down: function down(queryInterface, Sequelize) { diff --git a/src/database/seeders/20190912140255-notifications.js b/src/database/seeders/20190912140255-notifications.js new file mode 100644 index 0000000..a5af6de --- /dev/null +++ b/src/database/seeders/20190912140255-notifications.js @@ -0,0 +1,31 @@ +module.exports = { + up: function up(queryInterface, Sequelize) { + return queryInterface.bulkInsert('notifications', [{ + id: 333, + user_id: 1674946, + travel_id: 1898451, + line_manager_id: 6453673, + line_manager_email: 'chidiebere_chukwuma@yahoo.com', + is_read: false, + message: 'Your travel request has been created', + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: 1627, + user_id: 1215739, + travel_id: 1891029, + line_manager_id: 3640773, + line_manager_email: 'chukschiboy@gmail.com', + is_read: false, + message: 'Your travel request has been created', + createdAt: new Date(), + updatedAt: new Date() + } + ], {}); + }, + + down: function down(queryInterface, Sequelize) { + return queryInterface.bulkDelete('notifications', null, {}); + } +}; diff --git a/src/models/comment.js b/src/models/comment.js index 0a70fa0..417176c 100644 --- a/src/models/comment.js +++ b/src/models/comment.js @@ -1,5 +1,5 @@ export default (sequelize, DataTypes) => { - const comment = sequelize.define('comments', { + const comment = sequelize.define('comments', { travel_id: DataTypes.INTEGER, comment: DataTypes.TEXT, author_name: DataTypes.TEXT, @@ -10,5 +10,5 @@ export default (sequelize, DataTypes) => { foreignKey: 'travel_id' }); }; - return comment; + return comment; }; diff --git a/src/models/department.js b/src/models/department.js index 38b961c..cf4be61 100644 --- a/src/models/department.js +++ b/src/models/department.js @@ -2,7 +2,9 @@ module.exports = (sequelize, DataTypes) => { const departments = sequelize.define('departments', { dept_name: DataTypes.TEXT, line_manager: DataTypes.TEXT, - manager_staff_id: DataTypes.STRING + manager_staff_id: DataTypes.STRING, + line_manager_email: DataTypes.TEXT, + line_manager_id: DataTypes.INTEGER, }, {}); departments.associate = (models) => { diff --git a/src/models/index.js b/src/models/index.js index e9297f3..388c05d 100644 --- a/src/models/index.js +++ b/src/models/index.js @@ -5,10 +5,10 @@ import dotenv from 'dotenv'; dotenv.config(); -let env = process.env.NODE_ENV || 'development'; -let config = require('../database/config')[env]; +const env = process.env.NODE_ENV || 'development'; +const config = require('../config')[env]; -let db = {}; +const db = {}; let sequelize; diff --git a/src/models/travel_request.js b/src/models/travel_request.js index dabfb93..7960156 100644 --- a/src/models/travel_request.js +++ b/src/models/travel_request.js @@ -34,6 +34,11 @@ module.exports = (sequelize, DataTypes) => { foreignKey: 'travel_id', onDelete: 'CASCADE' }); + + travel_request.hasMany(models.notifications, { + foreignKey: 'travel_id', + onDelete: 'CASCADE' + }); }; return travel_request; }; From 41bb90f12c98f94e7cefff8f352d577f04ec5f12 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Fri, 13 Sep 2019 13:36:58 +0100 Subject: [PATCH 16/23] changing folder structure --- src/models/index.js | 38 +++++++++---------- src/{database => }/models/notifications.js | 0 src/routes/travelRoute.js | 11 ++---- .../travelRoute.js => travelRoute.js~HEAD} | 11 ++++-- src/routes/users.js | 0 5 files changed, 30 insertions(+), 30 deletions(-) rename src/{database => }/models/notifications.js (100%) rename src/routes/{api/travelRoute.js => travelRoute.js~HEAD} (53%) create mode 100644 src/routes/users.js diff --git a/src/models/index.js b/src/models/index.js index 388c05d..3b6b743 100644 --- a/src/models/index.js +++ b/src/models/index.js @@ -13,31 +13,31 @@ const db = {}; let sequelize; if (config.use_env_variable) { - sequelize = new Sequelize(process.env[config.use_env_variable], config); + sequelize = new Sequelize(process.env[config.use_env_variable], config); } else { - sequelize = new Sequelize( - config.database, - config.username, - config.password, - config, - ); + sequelize = new Sequelize( + config.database, + config.username, + config.password, + config, + ); } fs.readdirSync(__dirname) - .filter( - file => file.indexOf('.') !== 0 && - file !== 'index.js' && - file.slice(-3) === '.js', - ) - .forEach((file) => { - const model = sequelize.import(path.join(__dirname, file)); - db[model.name] = model; - }); + .filter( + file => file.indexOf('.') !== 0 + && file !== 'index.js' + && file.slice(-3) === '.js', + ) + .forEach((file) => { + const model = sequelize.import(path.join(__dirname, file)); + db[model.name] = model; + }); Object.keys(db).forEach((modelName) => { - if (db[modelName].associate) { - db[modelName].associate(db); - } + if (db[modelName].associate) { + db[modelName].associate(db); + } }); db.sequelize = sequelize; diff --git a/src/database/models/notifications.js b/src/models/notifications.js similarity index 100% rename from src/database/models/notifications.js rename to src/models/notifications.js diff --git a/src/routes/travelRoute.js b/src/routes/travelRoute.js index 268b495..b49f7e8 100644 --- a/src/routes/travelRoute.js +++ b/src/routes/travelRoute.js @@ -1,11 +1,11 @@ import { Router } from 'express'; -import travelControllers from '../controllers/travelControllers'; -import travelValidator from '../validation/travelValidation'; -import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; +import travelControllers from '../../controllers/travelControllers'; +import travelValidator from '../../validation/travelValidation'; +import { getToken, verifyToken } from '../../middlewares/tokenMiddleware'; const route = Router(); -const { createOneWayTrip, pendingManagerApproval, getUserTravelStatus } = travelControllers; +const { createOneWayTrip, pendingManagerApproval } = travelControllers; const { validateTravelRequest, validateResult } = travelValidator; // handles the api home route... @@ -14,7 +14,4 @@ route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validate // handles manager pending req approvals route route.get('/requests/pending/:manager', getToken, verifyToken, pendingManagerApproval); -route.get('/user/status', getToken, verifyToken, getUserTravelStatus); - - export default route; diff --git a/src/routes/api/travelRoute.js b/src/routes/travelRoute.js~HEAD similarity index 53% rename from src/routes/api/travelRoute.js rename to src/routes/travelRoute.js~HEAD index b49f7e8..268b495 100644 --- a/src/routes/api/travelRoute.js +++ b/src/routes/travelRoute.js~HEAD @@ -1,11 +1,11 @@ import { Router } from 'express'; -import travelControllers from '../../controllers/travelControllers'; -import travelValidator from '../../validation/travelValidation'; -import { getToken, verifyToken } from '../../middlewares/tokenMiddleware'; +import travelControllers from '../controllers/travelControllers'; +import travelValidator from '../validation/travelValidation'; +import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; const route = Router(); -const { createOneWayTrip, pendingManagerApproval } = travelControllers; +const { createOneWayTrip, pendingManagerApproval, getUserTravelStatus } = travelControllers; const { validateTravelRequest, validateResult } = travelValidator; // handles the api home route... @@ -14,4 +14,7 @@ route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validate // handles manager pending req approvals route route.get('/requests/pending/:manager', getToken, verifyToken, pendingManagerApproval); +route.get('/user/status', getToken, verifyToken, getUserTravelStatus); + + export default route; diff --git a/src/routes/users.js b/src/routes/users.js new file mode 100644 index 0000000..e69de29 From 3fae1046ffd2cb9114ce69ea100439fa6e5a1a61 Mon Sep 17 00:00:00 2001 From: Chukwunonso Orjiakor Date: Thu, 12 Sep 2019 16:59:13 +0100 Subject: [PATCH 17/23] feature(approve-travel-request):enable manager to approve travel request - enable a manager to approve a travel request of his/her direct report - test the endpoint to ensure it works, even on Postman - add Mock data for testing in the test folder [Finishes #168437115] --- src/controllers/authControllers.js | 2 +- src/controllers/travelControllers.js | 127 ++++++++------ .../20190823125926-create-department.js | 18 +- .../20190823140019-create-travel.js | 8 - .../20190902110720-create-comments.js | 9 - .../20190908184324-create-travel-request.js | 4 + .../seeders/20190824033354-department.js | 10 +- src/database/seeders/20190908211400-users.js | 44 ++++- .../seeders/20190908212920-travel_requests.js | 2 + src/middlewares/index.js | 0 src/middlewares/travelsMiddleware.js | 41 +++++ src/middlewares/userMiddlewares.js | 13 +- src/models/comment.js | 4 +- src/models/department.js | 2 +- src/models/travel_request.js | 1 + src/routes/travelRoute.js | 26 ++- src/services/departmentServices.js | 19 ++ src/services/travelServices.js | 18 +- src/tests/mockData.js | 18 ++ src/tests/travel.test.js | 165 +++++++++++++----- src/utils/messageUtils.js | 5 + src/validation/travelValidation.js | 57 +++--- 22 files changed, 420 insertions(+), 173 deletions(-) delete mode 100644 src/database/migrations/20190823140019-create-travel.js delete mode 100644 src/database/migrations/20190902110720-create-comments.js delete mode 100644 src/middlewares/index.js create mode 100644 src/middlewares/travelsMiddleware.js create mode 100644 src/services/departmentServices.js diff --git a/src/controllers/authControllers.js b/src/controllers/authControllers.js index 271126f..da4b52b 100644 --- a/src/controllers/authControllers.js +++ b/src/controllers/authControllers.js @@ -31,7 +31,7 @@ export default { password, }; - userObj.role = req.body.role || 'user'; + userObj.role = req.body.role || 'requester'; const user = await signupService(userObj); // eslint-disable-next-line no-unused-vars diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index 2de9619..4c25eee 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,74 +1,95 @@ import { onewayTripService, - showManagerPendingAppr, - showUsertravelsStatus + showManagerPendingAppr, + showUsertravelsStatus, + approveTravel, } from '../services/travelServices'; +import { findUserByEmail } from '../services/authServices'; import { successResponseWithData, errorResponse } from '../utils/response'; import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; -export default { - createOneWayTrip: async (req, res) => { - try { - const { - origin, destination, departure_date, accommodation_id, travel_purpose - } = req.body; - const userId = req.userData.id; +export const createOneWayTrip = async (req, res) => { + try { + const user = await findUserByEmail(req.userData.email); + const { id, dept_id } = user.dataValues; - const travelObj = { - user_id: userId, - travel_type: 'one-way', - origin, - destination, - departure_date, - travel_purpose, - accommodation_id, - }; + const data = await onewayTripService({ + user_id: id, + travel_type: 'one-way', + ...req.body, + dept_id, + }); - const data = await onewayTripService(travelObj); + successResponseWithData( + res, + statusCode.created, + message.oneWayTripCreated, + data + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; - successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, +export const pendingManagerApproval = async (req, res) => { + const { role } = req.userData; - pendingManagerApproval: async (req, res) => { - const { role } = req.userData; + const { manager } = req.params; - const { manager } = req.params; + if (role !== 'manager') { + errorResponse(res, statusCode.unauthorized, message.unauthorized); + } - if (role === 'user') { - errorResponse(res, statusCode.unauthorized, message.unauthorized); - } + try { + const requestsPending = await showManagerPendingAppr(manager); - try { - const requestsPending = await showManagerPendingAppr(manager); + const filteredRequests = requestsPending + .filter((request) => request['user.department.line_manager'] !== null); + const requestNumbers = filteredRequests.length; - const filteredRequests = requestsPending.filter(request => request['user.department.line_manager'] !== null); + successResponseWithData( + res, + statusCode.success, + message.managerApproval(requestNumbers), + filteredRequests + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; - const requestNumbers = filteredRequests.length; +export const getUserTravelStatus = async (req, res) => { + const { role, id } = req.userData; - // eslint-disable-next-line max-len - successResponseWithData(res, statusCode.success, message.managerApproval(requestNumbers), filteredRequests); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, + if (role === 'manager') { + return errorResponse(res, statusCode.unauthorized, message.unauthorized); + } + try { + const data = await showUsertravelsStatus(id); + return successResponseWithData( + res, + statusCode.success, + message.userApproval, + data + ); + } catch (error) { + errorResponse(res, statusCode.serverError, error); + } +}; - getUserTravelStatus: async(req, res) => { - const { role, id } = req.userData; +export const approveTravelRequest = async (req, res) => { + try { + const updatedTravel = await approveTravel(req.params.travel_id); - if (role === 'admin') { - return errorResponse(res, statusCode.unauthorized, message.unauthorized); - } else { - try { - const data = await showUsertravelsStatus(id); - return successResponseWithData(res, statusCode.success, message.userApproval, data); - } catch (error) { - errorResponse(res, statusCode.serverError, error); - } - } - } + successResponseWithData( + res, + statusCode.success, + message.successfullyApproval(req.body.requesterName), + updatedTravel[1][0] + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } }; diff --git a/src/database/migrations/20190823125926-create-department.js b/src/database/migrations/20190823125926-create-department.js index 97e5494..c8950ec 100644 --- a/src/database/migrations/20190823125926-create-department.js +++ b/src/database/migrations/20190823125926-create-department.js @@ -5,28 +5,28 @@ module.exports = { allowNull: false, autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.INTEGER, }, dept_name: { - type: Sequelize.TEXT + type: Sequelize.TEXT, }, line_manager: { - type: Sequelize.TEXT + type: Sequelize.TEXT, }, - manager_staff_id: { - type: Sequelize.STRING + manager_user_id: { + type: Sequelize.INTEGER, }, createdAt: { allowNull: false, - type: Sequelize.DATE + type: Sequelize.DATE, }, updatedAt: { allowNull: false, - type: Sequelize.DATE - } + type: Sequelize.DATE, + }, }); }, down: function down(queryInterface, Sequelize) { return queryInterface.dropTable('departments'); - } + }, }; diff --git a/src/database/migrations/20190823140019-create-travel.js b/src/database/migrations/20190823140019-create-travel.js deleted file mode 100644 index 94251f3..0000000 --- a/src/database/migrations/20190823140019-create-travel.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - up: function(queryInterface, Sequelize) { - return Promise.resolve(); - }, - down: function(queryInterface) { - return Promise.resolve(); - } -}; diff --git a/src/database/migrations/20190902110720-create-comments.js b/src/database/migrations/20190902110720-create-comments.js deleted file mode 100644 index c8bd1d4..0000000 --- a/src/database/migrations/20190902110720-create-comments.js +++ /dev/null @@ -1,9 +0,0 @@ - -module.exports = { - up: function(queryInterface, Sequelize) { - return Promise.resolve(); - }, - down: function(queryInterface) { - return Promise.resolve(); - } -}; diff --git a/src/database/migrations/20190908184324-create-travel-request.js b/src/database/migrations/20190908184324-create-travel-request.js index a5e54ed..92a6c4c 100644 --- a/src/database/migrations/20190908184324-create-travel-request.js +++ b/src/database/migrations/20190908184324-create-travel-request.js @@ -66,6 +66,10 @@ module.exports = { key: 'id' } }, + dept_id: { + type: Sequelize.INTEGER, + allowNull: false, + }, approval_status: { type: Sequelize.ENUM, allowNull: true, diff --git a/src/database/seeders/20190824033354-department.js b/src/database/seeders/20190824033354-department.js index b208731..fb72bc2 100644 --- a/src/database/seeders/20190824033354-department.js +++ b/src/database/seeders/20190824033354-department.js @@ -1,18 +1,18 @@ module.exports = { up: function up(queryInterface, Sequelize) { return queryInterface.bulkInsert('departments', [{ - id: 15327458, + id: 1532745, dept_name: 'Business Admin', - line_manager: 'Mr. Benchfort', - manager_staff_id: 'GHJ-378-2838', + line_manager: 'Marshal Benchfort', + manager_user_id: 3433434, createdAt: new Date(), updatedAt: new Date(), }, { id: 1536907, dept_name: 'Software Engr', - line_manager: 'Ms. Querty', - manager_staff_id: 'RDS-256-5787', + line_manager: 'Rose Querty', + manager_user_id: 6749460, createdAt: new Date(), updatedAt: new Date(), }, diff --git a/src/database/seeders/20190908211400-users.js b/src/database/seeders/20190908211400-users.js index bf4ed26..09c0bdb 100644 --- a/src/database/seeders/20190908211400-users.js +++ b/src/database/seeders/20190908211400-users.js @@ -12,13 +12,13 @@ module.exports = { last_name: 'Chidi', email: 'petchidi@yahoo.com', password: hashSync('testing123', genSaltSync(10)), - dept_id: 15327458, + dept_id: 1532745, dob: '2019-08-09', gender: 'Male', address: 'Ok. This is my address', preferred_lang: 'English', preferred_currency: 'USD', - role: 'processed', + role: 'requester', is_active: false, createdAt: new Date(), updatedAt: new Date(), @@ -36,8 +36,44 @@ module.exports = { address: 'Ok. This is our address', preferred_lang: 'English', preferred_currency: 'USD', - role: 'processed', - is_active: false, + role: 'requester', + is_active: true, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 6749460, + staff_id: 'RDS-256-5787', + first_name: 'Rose', + last_name: 'Querty', + email: 'rose.querty@yahoo.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 1536907, + dob: '2019-08-09', + gender: 'Female', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'manager', + is_active: true, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 3433434, + staff_id: 'RDS-256-5782', + first_name: 'Marshal', + last_name: 'Benchfort', + email: 'm.benchfort@yahoo.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 1532745, + dob: '2019-08-09', + gender: 'Male', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'manager', + is_active: true, createdAt: new Date(), updatedAt: new Date(), }, diff --git a/src/database/seeders/20190908212920-travel_requests.js b/src/database/seeders/20190908212920-travel_requests.js index 68a086d..3cd1767 100644 --- a/src/database/seeders/20190908212920-travel_requests.js +++ b/src/database/seeders/20190908212920-travel_requests.js @@ -10,6 +10,7 @@ module.exports = { return_date: new Date(), travel_purpose: 'This is the reason for my travel', accommodation_id: 1653453, + dept_id: 1536907, multi_city: false, createdAt: new Date(), updatedAt: new Date() @@ -24,6 +25,7 @@ module.exports = { return_date: new Date(), travel_purpose: 'This is the most important reason for my travel', accommodation_id: 1653453, + dept_id: 1536907, multi_city: true, createdAt: new Date(), updatedAt: new Date() diff --git a/src/middlewares/index.js b/src/middlewares/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/middlewares/travelsMiddleware.js b/src/middlewares/travelsMiddleware.js new file mode 100644 index 0000000..63a49a6 --- /dev/null +++ b/src/middlewares/travelsMiddleware.js @@ -0,0 +1,41 @@ +import { findUserById } from '../services/authServices'; +import { findTravelById } from '../services/travelServices'; +import { errorResponse } from '../utils/response'; + +import message from '../utils/messageUtils'; +import statusCode from '../utils/statusCode'; + +export const verifyDeptManagerAndRequestStatus = async (req, res, next) => { + try { + const { travel_id } = req.params; + const manager = await findUserById(req.userData.id); + const travel = await findTravelById(travel_id); + + if (travel === null) { + return errorResponse(res, statusCode.notFound, message.travelNotFound); + } + const requester = await findUserById(travel.dataValues.user_id); + const { first_name, last_name, dept_id } = requester.dataValues; + if (dept_id !== manager.dataValues.dept_id) { + return errorResponse( + res, + statusCode.unauthorized, + message.diffDepartment + ); + } + if (travel.dataValues.approval_status !== 'pending') { + return errorResponse( + res, + statusCode.unauthorized, + message.requestNotPending + ); + } + req.body.requesterName = `${first_name} ${last_name}`; + return next(); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; + +export const verifyDeptManager = () => {}; +export const verifyRequestStatus = () => {}; diff --git a/src/middlewares/userMiddlewares.js b/src/middlewares/userMiddlewares.js index a5529ed..58fd257 100644 --- a/src/middlewares/userMiddlewares.js +++ b/src/middlewares/userMiddlewares.js @@ -1,6 +1,7 @@ import { findUserByEmail } from '../services/authServices'; import { findTravelById } from '../services/travelServices'; import { getAComment } from '../services/commentServices'; +import { getADepartment } from '../services/departmentServices'; import { errorResponse } from '../utils/response'; import message from '../utils/messageUtils'; @@ -37,7 +38,10 @@ export const verifyTravelOwner = async (req, res, next) => { return errorResponse(res, statusCode.notFound, message.travelNotFound); } const travel = travelObj.dataValues; - if (parseInt(travel.user_id, 10) !== req.userData.id) { + const dept = await getADepartment(travel.dept_id); + + if (parseInt(travel.user_id, 10) !== req.userData.id + && dept.dataValues.manager_user_id !== req.userData.id) { return errorResponse( res, statusCode.unauthorized, @@ -71,3 +75,10 @@ export const verifyCommentOwner = async (req, res, next) => { errorResponse(res, statusCode.serverError, err); } }; + +export const verifyRole = (role) => (req, res, next) => { + if (role !== req.userData.role) { + return errorResponse(res, statusCode.unauthorized, message.wrongRole(role)); + } + return next(); +}; diff --git a/src/models/comment.js b/src/models/comment.js index 0a70fa0..417176c 100644 --- a/src/models/comment.js +++ b/src/models/comment.js @@ -1,5 +1,5 @@ export default (sequelize, DataTypes) => { - const comment = sequelize.define('comments', { + const comment = sequelize.define('comments', { travel_id: DataTypes.INTEGER, comment: DataTypes.TEXT, author_name: DataTypes.TEXT, @@ -10,5 +10,5 @@ export default (sequelize, DataTypes) => { foreignKey: 'travel_id' }); }; - return comment; + return comment; }; diff --git a/src/models/department.js b/src/models/department.js index 38b961c..c9029b9 100644 --- a/src/models/department.js +++ b/src/models/department.js @@ -2,7 +2,7 @@ module.exports = (sequelize, DataTypes) => { const departments = sequelize.define('departments', { dept_name: DataTypes.TEXT, line_manager: DataTypes.TEXT, - manager_staff_id: DataTypes.STRING + manager_user_id: DataTypes.INTEGER, }, {}); departments.associate = (models) => { diff --git a/src/models/travel_request.js b/src/models/travel_request.js index dabfb93..dd8c1f0 100644 --- a/src/models/travel_request.js +++ b/src/models/travel_request.js @@ -12,6 +12,7 @@ module.exports = (sequelize, DataTypes) => { return_date: DataTypes.DATE, travel_purpose: DataTypes.TEXT, accommodation_id: DataTypes.INTEGER, + dept_id: DataTypes.INTEGER, approval_status: { type: DataTypes.ENUM, values: ['accepted', 'pending', 'rejected'], diff --git a/src/routes/travelRoute.js b/src/routes/travelRoute.js index 268b495..f3dc077 100644 --- a/src/routes/travelRoute.js +++ b/src/routes/travelRoute.js @@ -1,20 +1,36 @@ import { Router } from 'express'; -import travelControllers from '../controllers/travelControllers'; -import travelValidator from '../validation/travelValidation'; +import { + createOneWayTrip, + pendingManagerApproval, + getUserTravelStatus, + approveTravelRequest, +} from '../controllers/travelControllers'; +import { + validateTravelRequest, + validateResult, +} from '../validation/travelValidation'; +import { verifyDeptManagerAndRequestStatus } from '../middlewares/travelsMiddleware'; +import { verifyRole } from '../middlewares/userMiddlewares'; import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; const route = Router(); -const { createOneWayTrip, pendingManagerApproval, getUserTravelStatus } = travelControllers; -const { validateTravelRequest, validateResult } = travelValidator; // handles the api home route... -route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); +route.post('/travel/one_way_trip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); // handles manager pending req approvals route route.get('/requests/pending/:manager', getToken, verifyToken, pendingManagerApproval); route.get('/user/status', getToken, verifyToken, getUserTravelStatus); +route.patch( + '/travel/approve_request/:travel_id', + getToken, + verifyToken, + verifyRole('manager'), + verifyDeptManagerAndRequestStatus, + approveTravelRequest, +); export default route; diff --git a/src/services/departmentServices.js b/src/services/departmentServices.js new file mode 100644 index 0000000..c0f38a8 --- /dev/null +++ b/src/services/departmentServices.js @@ -0,0 +1,19 @@ +/* eslint-disable no-useless-catch */ +import 'core-js/stable'; +import 'regenerator-runtime/runtime'; + +import models from '../models'; + +const { departments } = models; + +export const createDepartment = async (comment) => {}; + +export const getADepartment = async (id) => { + try { + return await departments.findOne({ + where: { id }, + }); + } catch (err) { + throw err; + } +}; diff --git a/src/services/travelServices.js b/src/services/travelServices.js index 076c952..ee59224 100644 --- a/src/services/travelServices.js +++ b/src/services/travelServices.js @@ -16,8 +16,7 @@ export const onewayTripService = async (travelObj) => { export const findTravelById = async (id) => { try { return await travel_requests.findOne({ - attributes: ['id', 'user_id'], - where: { id }, + where: { id } }); } catch (err) { throw err; @@ -56,10 +55,21 @@ export const showUsertravelsStatus = async (userId) => { try { return await travel_requests.findAll({ where: { - user_id: userId - } + user_id: userId, + }, }); } catch (error) { throw error; } }; + +export const approveTravel = async (id) => { + try { + return await travel_requests.update( + { approval_status: 'accepted' }, + { returning: true, where: { id } } + ); + } catch (err) { + throw err; + } +}; diff --git a/src/tests/mockData.js b/src/tests/mockData.js index 67e730a..fa66d8c 100644 --- a/src/tests/mockData.js +++ b/src/tests/mockData.js @@ -17,6 +17,24 @@ export const testUser2 = { password: 'testing123', }; +export const testManager1 = { + email: 'rose.querty@yahoo.com', + password: 'testing123', +}; + +export const testManager2 = { + email: 'm.benchfort@yahoo.com', + password: 'testing123', +}; + +// Test Travel Request +export const testTravelRequest = { + origin: 'Lagos', + destination: 'Kigali', + departure_date: '2019-12-12', + travel_purpose: 'This is a one way trip', + accommodation_id: 1653453, +}; export const validTravelId = '1891029'; // Test comment diff --git a/src/tests/travel.test.js b/src/tests/travel.test.js index cd1b0ae..46a8e7f 100644 --- a/src/tests/travel.test.js +++ b/src/tests/travel.test.js @@ -2,13 +2,23 @@ import chai, { expect } from 'chai'; import chaiHttp from 'chai-http'; import dotenv from 'dotenv'; + import message from '../utils/messageUtils'; -import { travelRequest } from './mockData'; +import { + testUser2, + testTravelRequest, + testManager1, + testManager2, + validTravelId, +} from './mockData'; import app from '../index'; const prefix = '/api/v1'; const signupRoute = `${prefix}/auth/signup`; -const onewayRoute = `${prefix}/onewaytrip`; +const loginRoute = `${prefix}/auth/login`; +const onewayRoute = `${prefix}/travel/one_way_trip`; +const approveRequestRoute = `${prefix}/travel/approve_request/${validTravelId}`; + dotenv.config(); chai.use(chaiHttp); @@ -16,20 +26,12 @@ chai.use(chaiHttp); let token; describe('Testing one way ticket feature', () => { - const user = { - first_name: 'myname', - last_name: 'mylastname', - email: 'mygmailis@gmail.com', - password: 'protected123pass', - }; - - it('should successfully create a user', (done) => { + before((done) => { chai .request(app) - .post(signupRoute) - .send(user) + .post(loginRoute) + .send(testUser2) .end((err, res) => { - expect(res).to.have.status(201); const { data } = res.body; token = data.token; done(); @@ -41,7 +43,7 @@ describe('Testing one way ticket feature', () => { .request(app) .post(onewayRoute) .set('Authorization', token) - .send(travelRequest) + .send(testTravelRequest) .end((err, res) => { expect(res).to.have.status(201); done(); @@ -49,9 +51,10 @@ describe('Testing one way ticket feature', () => { }); it('should return an error if the token is invalid', (done) => { - chai.request(app) + chai + .request(app) .post(onewayRoute) - .send(travelRequest) + .send(testTravelRequest) .end((err, res) => { expect(res.status).to.equal(401); done(); @@ -59,91 +62,92 @@ describe('Testing one way ticket feature', () => { }); it('should return an error if origin is empty', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.origin = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyOrigin); + expect(res.body.error[0]).to.equal(message.emptyOrigin); done(); }); }); it('should return an error message if origin contains integers', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.origin = '4Lag12'; - chai.request(app) + + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.lettersAlone); + expect(res.body.error[0]).to.equal(message.lettersAlone); done(); }); }); it('should return an error message if the destination is empty', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.destination = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyDestination); + expect(res.body.error[0]).to.equal(message.emptyDestination); done(); }); }); it('should return an error message if the destination contains integers', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.destination = '4Kigs23'; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.lettersAlone); + expect(res.body.error[0]).to.equal(message.lettersAlone); done(); }); }); it('should return an error message if the departure date is empty', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.departure_date = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyDepartureDate); + expect(res.body.error[0]).to.equal(message.emptyDepartureDate); done(); }); }); it('should return an error message if travel_purpose', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.travel_purpose = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyTravelPurpose); + expect(res.body.error[0]).to.equal(message.emptyTravelPurpose); done(); }); }); @@ -158,7 +162,7 @@ describe('Testing Avail request for approval', () => { last_name: 'mylastnoamep', email: 'mygmailisj@gomail.com', password: 'protected123pass', - role: 'admin' + role: 'manager', }; it('should successfully create an admin user', (done) => { @@ -199,10 +203,10 @@ describe('Testing Avail request for approval', () => { // Get users request status -describe('Testing for users request status', ()=> { - it('should successfully return user request status', (done)=> { +describe('Testing for users request status', () => { + it('should successfully return user request status', (done) => { chai - .request(app) + .request(app) .get(`${prefix}/user/status`) .set('Authorization', token) .end((err, res) => { @@ -210,9 +214,9 @@ describe('Testing for users request status', ()=> { done(); }); }); - it('should return error when role is admin', (done) => { + it('should return error when role is a manager', (done) => { chai - .request(app) + .request(app) .get(`${prefix}/user/status`) .set('Authorization', adminToken) .end((err, res) => { @@ -221,3 +225,72 @@ describe('Testing for users request status', ()=> { }); }); }); + +describe('Testing the travel approval route', () => { + let managerToken1, managerToken2; + + before((done) => { + chai + .request(app) + .post(`${prefix}/auth/login`) + .send(testManager1) + .end((err, res) => { + const { data } = res.body; + managerToken1 = data.token; + done(); + }); + }); + before((done) => { + chai + .request(app) + .post(`${prefix}/auth/login`) + .send(testManager2) + .end((err, res) => { + const { data } = res.body; + managerToken2 = data.token; + done(); + }); + }); + + it('should not allow a manager to approve travel in another department', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken2) + .end((err, res) => { + expect(res).to.have.status(401); + expect(res.body.error).to.equal(message.diffDepartment); + done(); + }); + }); + it('should successfully approve a travel request', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken1) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + it('should return error if the travel request is not pending', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken1) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); + it('should not allow a normal user to approve a travel request', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', token) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); +}); diff --git a/src/utils/messageUtils.js b/src/utils/messageUtils.js index 0d19aaa..ae3f721 100644 --- a/src/utils/messageUtils.js +++ b/src/utils/messageUtils.js @@ -47,4 +47,9 @@ export default { unauthorizedCommentDelete: "comment can only be deleted by it's author", commentNotFound: 'The comment does not exist.', deleteComment: 'Comment successfully deleted.', + + requestNotPending: 'This Travel Request is not Pending.', + diffDepartment: 'You are not in the same department as the Travel Requester.', + wrongRole: (role) => `Sorry, you are not a/an ${role}.`, + successfullyApproval: (requester) => `You have successfully approved a travel request from ${requester}.`, }; diff --git a/src/validation/travelValidation.js b/src/validation/travelValidation.js index 44cdaf0..6fad15b 100644 --- a/src/validation/travelValidation.js +++ b/src/validation/travelValidation.js @@ -1,33 +1,40 @@ import { check, validationResult } from 'express-validator'; - import { errorResponse } from '../utils/response'; import statusCode from '../utils/statusCode'; import message from '../utils/messageUtils'; -export default { - validateTravelRequest: [ - check('origin').not().isEmpty() - .withMessage(message.emptyOrigin) - .isAlpha() - .withMessage(message.lettersAlone), - check('destination').not().isEmpty() - .withMessage(message.emptyDestination) - .isAlpha() - .withMessage(message.lettersAlone), - check('departure_date').not().isEmpty().withMessage(message.emptyDepartureDate), - check('travel_purpose').not().isEmpty().withMessage(message.emptyTravelPurpose), - ], - validateResult: (req, res, next) => { - const errors = validationResult(req); - if (!errors.isEmpty()) { - const error = []; - errors.array().forEach((err) => { - error.push(err.msg); - }); - return errorResponse(res, statusCode.badRequest, error); - } - return next(); - }, +export const validateTravelRequest = [ + check('origin') + .not() + .isEmpty() + .withMessage(message.emptyOrigin) + .isAlpha() + .withMessage(message.lettersAlone), + check('destination') + .not() + .isEmpty() + .withMessage(message.emptyDestination) + .isAlpha() + .withMessage(message.lettersAlone), + check('departure_date') + .not() + .isEmpty() + .withMessage(message.emptyDepartureDate), + check('travel_purpose') + .not() + .isEmpty() + .withMessage(message.emptyTravelPurpose), +]; +export const validateResult = (req, res, next) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + const error = []; + errors.array().forEach((err) => { + error.push(err.msg); + }); + return errorResponse(res, statusCode.badRequest, error); + } + return next(); }; From 6f9953ba4a203ebda5449373004cdc2d6b999e02 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Fri, 13 Sep 2019 17:14:28 +0100 Subject: [PATCH 18/23] brute force of merged PR --- src/config/config.js | 37 +- src/config/passport.js | 4 +- src/controllers/authControllers.js | 2 +- src/controllers/index.js | 4 +- src/controllers/notifyControllers.js | 31 -- src/controllers/travelControllers.js | 131 ++++-- src/database/config.js | 66 +-- .../20190823125926-create-department.js | 18 +- .../20190823140019-create-travel.js | 8 - .../20190902110720-create-comments.js | 9 - .../20190908184324-create-travel-request.js | 4 + .../20190912134053-create-notifications.js | 41 -- .../seeders/20190824033354-department.js | 10 +- src/database/seeders/20190908211400-users.js | 113 +++-- .../seeders/20190908212920-travel_requests.js | 2 + .../seeders/20190912140255-notifications.js | 31 -- src/index.js | 2 +- src/middlewares/index.js | 0 src/middlewares/travelsMiddleware.js | 41 ++ src/middlewares/userMiddlewares.js | 13 +- src/models/department.js | 4 +- src/models/index.js | 44 +- src/models/notifications.js | 40 -- src/models/travel_request.js | 6 +- src/routes/authRoutes.js | 8 +- src/routes/travelRoute.js | 31 +- src/routes/travelRoute.js~HEAD | 20 - src/routes/users.js | 0 src/services/departmentServices.js | 19 + src/services/emailServices.js | 56 +-- src/services/travelServices.js | 18 +- src/tests/auth.test.js | 402 ++++++++++-------- src/tests/authTest.js | 357 ---------------- src/tests/mockData.js | 18 + src/tests/travel.test.js | 165 +++++-- src/utils/messageUtils.js | 6 + src/validation/travelValidation.js | 57 +-- 37 files changed, 807 insertions(+), 1011 deletions(-) delete mode 100644 src/controllers/notifyControllers.js delete mode 100644 src/database/migrations/20190823140019-create-travel.js delete mode 100644 src/database/migrations/20190902110720-create-comments.js delete mode 100644 src/database/migrations/20190912134053-create-notifications.js delete mode 100644 src/database/seeders/20190912140255-notifications.js delete mode 100644 src/middlewares/index.js create mode 100644 src/middlewares/travelsMiddleware.js delete mode 100644 src/models/notifications.js delete mode 100644 src/routes/travelRoute.js~HEAD delete mode 100644 src/routes/users.js create mode 100644 src/services/departmentServices.js delete mode 100644 src/tests/authTest.js diff --git a/src/config/config.js b/src/config/config.js index 7fa7e60..ea2ea06 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -3,33 +3,34 @@ import dotenv from 'dotenv'; dotenv.config(); const { - DB_USERNAME, - DATABASE, - DB_PASSWORD, - DB_HOST, - DB_PORT, - PORT, - DB_DIALECT + DB_USERNAME, + DATABASE, + DB_PASSWORD, + DB_HOST, + DB_PORT, + PORT, + DB_DIALECT } = process.env; export const db = { - DB_USERNAME, - DATABASE, - DB_PASSWORD, - DB_HOST, - DB_PORT, - PORT, - DB_DIALECT + DB_USERNAME, + DATABASE, + DB_PASSWORD, + DB_HOST, + DB_PORT, + PORT, + DB_DIALECT }; let connection; if (process.env.NODE_ENV === 'test') { - connection = { - connectionString: process.env.TESTDB_URL - }; + connection = { + connectionString: process.env.TESTDB_URL + } } connection = { - connectionString: process.env.DATABASE_URL + connectionString: process.env.DATABASE_URL }; + diff --git a/src/config/passport.js b/src/config/passport.js index e331fc1..0f2eb1e 100755 --- a/src/config/passport.js +++ b/src/config/passport.js @@ -3,7 +3,7 @@ import { Strategy } from 'passport-google-oauth20'; import dotenv from 'dotenv'; import { signupService, findUserById } from '../services/authServices'; -dotenv.config(); +dotenv.config() const fbStrategy = new FacebookStrategy({ clientID: '521471335085949', @@ -13,7 +13,7 @@ const fbStrategy = new FacebookStrategy({ async (accessToken, refreshToken, profile, cb) => { try { - const email = profile.emails ? profile.emails[0].value : null; + const email = profile.emails? profile.emails[0].value : null; const { id } = profile; const userExists = await findUserById(id); diff --git a/src/controllers/authControllers.js b/src/controllers/authControllers.js index 271126f..da4b52b 100644 --- a/src/controllers/authControllers.js +++ b/src/controllers/authControllers.js @@ -31,7 +31,7 @@ export default { password, }; - userObj.role = req.body.role || 'user'; + userObj.role = req.body.role || 'requester'; const user = await signupService(userObj); // eslint-disable-next-line no-unused-vars diff --git a/src/controllers/index.js b/src/controllers/index.js index 7668124..ea10091 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -1,5 +1,5 @@ import { authControllers } from './authControllers'; export { - authControllers, -}; +authControllers +}; \ No newline at end of file diff --git a/src/controllers/notifyControllers.js b/src/controllers/notifyControllers.js deleted file mode 100644 index ac9e4d0..0000000 --- a/src/controllers/notifyControllers.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable require-jsdoc */ -import models from '../database/models'; - -const { notifications } = models; - -export default { - - getAllNotification: async (req, res) => { - try { - const user_id = req.users.id; - const allRequests = await notifications.findAll({ where: { receiver: user_id } }); - return res.status(200).json({ status: 200, data: allRequests }); - } catch (error) { - res.status(500).json({ status: 500, error }); - } - }, - - readAllNotification: async (req, res) => { - try { - const user_id = req.user.id; - const allRequestsByUser = await notifications.update({ is_read: true }, { - where: { - receiver: user_id - } - }); - return res.status(200).json({ status: 200, data: allRequestsByUser }); - } catch (error) { - res.status(500).json({ status: 500, error }); - } - }, -}; diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index 1eb72e2..4c25eee 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,58 +1,95 @@ import { onewayTripService, showManagerPendingAppr, + showUsertravelsStatus, + approveTravel, } from '../services/travelServices'; +import { findUserByEmail } from '../services/authServices'; import { successResponseWithData, errorResponse } from '../utils/response'; import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; -export default { - createOneWayTrip: async (req, res) => { - try { - const { - origin, destination, departure_date, accommodation_id, travel_purpose - } = req.body; - const userId = req.userData.id; - - const travelObj = { - user_id: userId, - travel_type: 'one-way', - origin, - destination, - departure_date, - travel_purpose, - accommodation_id, - }; - - const data = await onewayTripService(travelObj); - - successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } - }, - - pendingManagerApproval: async (req, res) => { - const { role } = req.userData; - - const { manager } = req.params; - - if (role === 'user') { - errorResponse(res, statusCode.unauthorized, message.unauthorized); - } - - try { - const requestsPending = await showManagerPendingAppr(manager); - - const filteredRequests = requestsPending.filter(request => request['user.department.line_manager'] !== null); - - const requestNumbers = filteredRequests.length; - - // eslint-disable-next-line max-len - successResponseWithData(res, statusCode.success, message.managerApproval(requestNumbers), filteredRequests); - } catch (err) { - errorResponse(res, statusCode.serverError, err); - } +export const createOneWayTrip = async (req, res) => { + try { + const user = await findUserByEmail(req.userData.email); + const { id, dept_id } = user.dataValues; + + const data = await onewayTripService({ + user_id: id, + travel_type: 'one-way', + ...req.body, + dept_id, + }); + + successResponseWithData( + res, + statusCode.created, + message.oneWayTripCreated, + data + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; + +export const pendingManagerApproval = async (req, res) => { + const { role } = req.userData; + + const { manager } = req.params; + + if (role !== 'manager') { + errorResponse(res, statusCode.unauthorized, message.unauthorized); + } + + try { + const requestsPending = await showManagerPendingAppr(manager); + + const filteredRequests = requestsPending + .filter((request) => request['user.department.line_manager'] !== null); + const requestNumbers = filteredRequests.length; + + successResponseWithData( + res, + statusCode.success, + message.managerApproval(requestNumbers), + filteredRequests + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; + +export const getUserTravelStatus = async (req, res) => { + const { role, id } = req.userData; + + if (role === 'manager') { + return errorResponse(res, statusCode.unauthorized, message.unauthorized); + } + try { + const data = await showUsertravelsStatus(id); + return successResponseWithData( + res, + statusCode.success, + message.userApproval, + data + ); + } catch (error) { + errorResponse(res, statusCode.serverError, error); + } +}; + +export const approveTravelRequest = async (req, res) => { + try { + const updatedTravel = await approveTravel(req.params.travel_id); + + successResponseWithData( + res, + statusCode.success, + message.successfullyApproval(req.body.requesterName), + updatedTravel[1][0] + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); } }; diff --git a/src/database/config.js b/src/database/config.js index d85a733..d9e43b0 100644 --- a/src/database/config.js +++ b/src/database/config.js @@ -1,40 +1,40 @@ require('dotenv').config(); const { - /* DATABASE_URL, */ - DB_USERNAME, - DB_PASSWORD, - DB_HOST, - DB_PORT, - DATABASE, + /* DATABASE_URL, */ + DB_USERNAME, + DB_PASSWORD, + DB_HOST, + DB_PORT, + DATABASE, } = process.env; module.exports = { - development: { - // use_env_variable: DATABASE_URL, - username: DB_USERNAME, - password: DB_PASSWORD, - database: DATABASE, - host: DB_HOST, - port: DB_PORT, - dialect: 'postgres', - }, - test: { - // use_env_variable: DATABASE_URL, - username: DB_USERNAME, - password: DB_PASSWORD, - database: DATABASE, - host: DB_HOST, - port: DB_PORT, - dialect: 'postgres', - }, - production: { - // use_env_variable: DATABASE_URL, - username: DB_USERNAME, - password: DB_PASSWORD, - database: DATABASE, - host: DB_HOST, - port: DB_PORT, - dialect: 'postgres', - }, + development: { + // use_env_variable: DATABASE_URL, + username: DB_USERNAME, + password: DB_PASSWORD, + database: DATABASE, + host: DB_HOST, + port: DB_PORT, + dialect: 'postgres', + }, + test: { + // use_env_variable: DATABASE_URL, + username: DB_USERNAME, + password: DB_PASSWORD, + database: DATABASE, + host: DB_HOST, + port: DB_PORT, + dialect: 'postgres', + }, + production: { + // use_env_variable: DATABASE_URL, + username: DB_USERNAME, + password: DB_PASSWORD, + database: DATABASE, + host: DB_HOST, + port: DB_PORT, + dialect: 'postgres', + }, }; diff --git a/src/database/migrations/20190823125926-create-department.js b/src/database/migrations/20190823125926-create-department.js index 97e5494..c8950ec 100644 --- a/src/database/migrations/20190823125926-create-department.js +++ b/src/database/migrations/20190823125926-create-department.js @@ -5,28 +5,28 @@ module.exports = { allowNull: false, autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.INTEGER, }, dept_name: { - type: Sequelize.TEXT + type: Sequelize.TEXT, }, line_manager: { - type: Sequelize.TEXT + type: Sequelize.TEXT, }, - manager_staff_id: { - type: Sequelize.STRING + manager_user_id: { + type: Sequelize.INTEGER, }, createdAt: { allowNull: false, - type: Sequelize.DATE + type: Sequelize.DATE, }, updatedAt: { allowNull: false, - type: Sequelize.DATE - } + type: Sequelize.DATE, + }, }); }, down: function down(queryInterface, Sequelize) { return queryInterface.dropTable('departments'); - } + }, }; diff --git a/src/database/migrations/20190823140019-create-travel.js b/src/database/migrations/20190823140019-create-travel.js deleted file mode 100644 index 94251f3..0000000 --- a/src/database/migrations/20190823140019-create-travel.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - up: function(queryInterface, Sequelize) { - return Promise.resolve(); - }, - down: function(queryInterface) { - return Promise.resolve(); - } -}; diff --git a/src/database/migrations/20190902110720-create-comments.js b/src/database/migrations/20190902110720-create-comments.js deleted file mode 100644 index c8bd1d4..0000000 --- a/src/database/migrations/20190902110720-create-comments.js +++ /dev/null @@ -1,9 +0,0 @@ - -module.exports = { - up: function(queryInterface, Sequelize) { - return Promise.resolve(); - }, - down: function(queryInterface) { - return Promise.resolve(); - } -}; diff --git a/src/database/migrations/20190908184324-create-travel-request.js b/src/database/migrations/20190908184324-create-travel-request.js index a5e54ed..92a6c4c 100644 --- a/src/database/migrations/20190908184324-create-travel-request.js +++ b/src/database/migrations/20190908184324-create-travel-request.js @@ -66,6 +66,10 @@ module.exports = { key: 'id' } }, + dept_id: { + type: Sequelize.INTEGER, + allowNull: false, + }, approval_status: { type: Sequelize.ENUM, allowNull: true, diff --git a/src/database/migrations/20190912134053-create-notifications.js b/src/database/migrations/20190912134053-create-notifications.js deleted file mode 100644 index c9ccffd..0000000 --- a/src/database/migrations/20190912134053-create-notifications.js +++ /dev/null @@ -1,41 +0,0 @@ -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.createTable('notifications', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - user_id: { - type: Sequelize.INTEGER - }, - travel_id: { - type: Sequelize.INTEGER - }, - is_read: { - type: Sequelize.BOOLEAN - }, - line_manager_email: { - type: Sequelize.TEXT - }, - line_manager_id: { - type: Sequelize.INTEGER - }, - message: { - type: Sequelize.TEXT - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }); - }, - down: (queryInterface, Sequelize) => { - return queryInterface.dropTable('notifications'); - } -}; diff --git a/src/database/seeders/20190824033354-department.js b/src/database/seeders/20190824033354-department.js index b208731..fb72bc2 100644 --- a/src/database/seeders/20190824033354-department.js +++ b/src/database/seeders/20190824033354-department.js @@ -1,18 +1,18 @@ module.exports = { up: function up(queryInterface, Sequelize) { return queryInterface.bulkInsert('departments', [{ - id: 15327458, + id: 1532745, dept_name: 'Business Admin', - line_manager: 'Mr. Benchfort', - manager_staff_id: 'GHJ-378-2838', + line_manager: 'Marshal Benchfort', + manager_user_id: 3433434, createdAt: new Date(), updatedAt: new Date(), }, { id: 1536907, dept_name: 'Software Engr', - line_manager: 'Ms. Querty', - manager_staff_id: 'RDS-256-5787', + line_manager: 'Rose Querty', + manager_user_id: 6749460, createdAt: new Date(), updatedAt: new Date(), }, diff --git a/src/database/seeders/20190908211400-users.js b/src/database/seeders/20190908211400-users.js index 7701013..09c0bdb 100644 --- a/src/database/seeders/20190908211400-users.js +++ b/src/database/seeders/20190908211400-users.js @@ -3,43 +3,82 @@ const { hashSync, genSaltSync } = require('bcryptjs'); module.exports = { up: function up(queryInterface, Sequelize) { return queryInterface.bulkInsert( - 'users', [{ - id: 1674946, - staff_id: 'ABD-111-8209', - first_name: 'Peter', - last_name: 'Chidi', - email: 'petchidi@yahoo.com', - password: hashSync('testing123', genSaltSync(10)), - dept_id: 15327458, - dob: '2019-08-09', - gender: 'Male', - address: 'Ok. This is my address', - preferred_lang: 'English', - preferred_currency: 'USD', - role: 'processed', - is_active: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: 1215739, - staff_id: 'GHD-123-9004', - first_name: 'Ngozi', - last_name: 'Nancy', - email: 'nancngo@gmail.com', - password: hashSync('testing123', genSaltSync(10)), - dept_id: 1536907, - dob: '2015-08-09', - gender: 'Female', - address: 'Ok. This is our address', - preferred_lang: 'English', - preferred_currency: 'USD', - role: 'processed', - is_active: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], {} + 'users', + [ + { + id: 1674946, + staff_id: 'ABD-111-8209', + first_name: 'Peter', + last_name: 'Chidi', + email: 'petchidi@yahoo.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 1532745, + dob: '2019-08-09', + gender: 'Male', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'requester', + is_active: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 1215739, + staff_id: 'GHD-123-9004', + first_name: 'Ngozi', + last_name: 'Nancy', + email: 'nancngo@gmail.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 1536907, + dob: '2015-08-09', + gender: 'Female', + address: 'Ok. This is our address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'requester', + is_active: true, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 6749460, + staff_id: 'RDS-256-5787', + first_name: 'Rose', + last_name: 'Querty', + email: 'rose.querty@yahoo.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 1536907, + dob: '2019-08-09', + gender: 'Female', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'manager', + is_active: true, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: 3433434, + staff_id: 'RDS-256-5782', + first_name: 'Marshal', + last_name: 'Benchfort', + email: 'm.benchfort@yahoo.com', + password: hashSync('testing123', genSaltSync(10)), + dept_id: 1532745, + dob: '2019-08-09', + gender: 'Male', + address: 'Ok. This is my address', + preferred_lang: 'English', + preferred_currency: 'USD', + role: 'manager', + is_active: true, + createdAt: new Date(), + updatedAt: new Date(), + }, + ], + {} ); }, down: function down(queryInterface, Sequelize) { diff --git a/src/database/seeders/20190908212920-travel_requests.js b/src/database/seeders/20190908212920-travel_requests.js index 68a086d..3cd1767 100644 --- a/src/database/seeders/20190908212920-travel_requests.js +++ b/src/database/seeders/20190908212920-travel_requests.js @@ -10,6 +10,7 @@ module.exports = { return_date: new Date(), travel_purpose: 'This is the reason for my travel', accommodation_id: 1653453, + dept_id: 1536907, multi_city: false, createdAt: new Date(), updatedAt: new Date() @@ -24,6 +25,7 @@ module.exports = { return_date: new Date(), travel_purpose: 'This is the most important reason for my travel', accommodation_id: 1653453, + dept_id: 1536907, multi_city: true, createdAt: new Date(), updatedAt: new Date() diff --git a/src/database/seeders/20190912140255-notifications.js b/src/database/seeders/20190912140255-notifications.js deleted file mode 100644 index a5af6de..0000000 --- a/src/database/seeders/20190912140255-notifications.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = { - up: function up(queryInterface, Sequelize) { - return queryInterface.bulkInsert('notifications', [{ - id: 333, - user_id: 1674946, - travel_id: 1898451, - line_manager_id: 6453673, - line_manager_email: 'chidiebere_chukwuma@yahoo.com', - is_read: false, - message: 'Your travel request has been created', - createdAt: new Date(), - updatedAt: new Date() - }, - { - id: 1627, - user_id: 1215739, - travel_id: 1891029, - line_manager_id: 3640773, - line_manager_email: 'chukschiboy@gmail.com', - is_read: false, - message: 'Your travel request has been created', - createdAt: new Date(), - updatedAt: new Date() - } - ], {}); - }, - - down: function down(queryInterface, Sequelize) { - return queryInterface.bulkDelete('notifications', null, {}); - } -}; diff --git a/src/index.js b/src/index.js index 1dd13c3..c2ed93f 100755 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,7 @@ import { fbStrategy, googleStrategy } from './config/passport'; import message from './utils/messageUtils'; import response from './utils/response'; import statusCode from './utils/statusCode'; -import routes from './routes/api'; +import routes from './routes'; dotenv.config(); const debugLog = debug('web-app'); diff --git a/src/middlewares/index.js b/src/middlewares/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/middlewares/travelsMiddleware.js b/src/middlewares/travelsMiddleware.js new file mode 100644 index 0000000..63a49a6 --- /dev/null +++ b/src/middlewares/travelsMiddleware.js @@ -0,0 +1,41 @@ +import { findUserById } from '../services/authServices'; +import { findTravelById } from '../services/travelServices'; +import { errorResponse } from '../utils/response'; + +import message from '../utils/messageUtils'; +import statusCode from '../utils/statusCode'; + +export const verifyDeptManagerAndRequestStatus = async (req, res, next) => { + try { + const { travel_id } = req.params; + const manager = await findUserById(req.userData.id); + const travel = await findTravelById(travel_id); + + if (travel === null) { + return errorResponse(res, statusCode.notFound, message.travelNotFound); + } + const requester = await findUserById(travel.dataValues.user_id); + const { first_name, last_name, dept_id } = requester.dataValues; + if (dept_id !== manager.dataValues.dept_id) { + return errorResponse( + res, + statusCode.unauthorized, + message.diffDepartment + ); + } + if (travel.dataValues.approval_status !== 'pending') { + return errorResponse( + res, + statusCode.unauthorized, + message.requestNotPending + ); + } + req.body.requesterName = `${first_name} ${last_name}`; + return next(); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; + +export const verifyDeptManager = () => {}; +export const verifyRequestStatus = () => {}; diff --git a/src/middlewares/userMiddlewares.js b/src/middlewares/userMiddlewares.js index a5529ed..58fd257 100644 --- a/src/middlewares/userMiddlewares.js +++ b/src/middlewares/userMiddlewares.js @@ -1,6 +1,7 @@ import { findUserByEmail } from '../services/authServices'; import { findTravelById } from '../services/travelServices'; import { getAComment } from '../services/commentServices'; +import { getADepartment } from '../services/departmentServices'; import { errorResponse } from '../utils/response'; import message from '../utils/messageUtils'; @@ -37,7 +38,10 @@ export const verifyTravelOwner = async (req, res, next) => { return errorResponse(res, statusCode.notFound, message.travelNotFound); } const travel = travelObj.dataValues; - if (parseInt(travel.user_id, 10) !== req.userData.id) { + const dept = await getADepartment(travel.dept_id); + + if (parseInt(travel.user_id, 10) !== req.userData.id + && dept.dataValues.manager_user_id !== req.userData.id) { return errorResponse( res, statusCode.unauthorized, @@ -71,3 +75,10 @@ export const verifyCommentOwner = async (req, res, next) => { errorResponse(res, statusCode.serverError, err); } }; + +export const verifyRole = (role) => (req, res, next) => { + if (role !== req.userData.role) { + return errorResponse(res, statusCode.unauthorized, message.wrongRole(role)); + } + return next(); +}; diff --git a/src/models/department.js b/src/models/department.js index cf4be61..c9029b9 100644 --- a/src/models/department.js +++ b/src/models/department.js @@ -2,9 +2,7 @@ module.exports = (sequelize, DataTypes) => { const departments = sequelize.define('departments', { dept_name: DataTypes.TEXT, line_manager: DataTypes.TEXT, - manager_staff_id: DataTypes.STRING, - line_manager_email: DataTypes.TEXT, - line_manager_id: DataTypes.INTEGER, + manager_user_id: DataTypes.INTEGER, }, {}); departments.associate = (models) => { diff --git a/src/models/index.js b/src/models/index.js index 3b6b743..e9297f3 100644 --- a/src/models/index.js +++ b/src/models/index.js @@ -5,39 +5,39 @@ import dotenv from 'dotenv'; dotenv.config(); -const env = process.env.NODE_ENV || 'development'; -const config = require('../config')[env]; +let env = process.env.NODE_ENV || 'development'; +let config = require('../database/config')[env]; -const db = {}; +let db = {}; let sequelize; if (config.use_env_variable) { - sequelize = new Sequelize(process.env[config.use_env_variable], config); + sequelize = new Sequelize(process.env[config.use_env_variable], config); } else { - sequelize = new Sequelize( - config.database, - config.username, - config.password, - config, - ); + sequelize = new Sequelize( + config.database, + config.username, + config.password, + config, + ); } fs.readdirSync(__dirname) - .filter( - file => file.indexOf('.') !== 0 - && file !== 'index.js' - && file.slice(-3) === '.js', - ) - .forEach((file) => { - const model = sequelize.import(path.join(__dirname, file)); - db[model.name] = model; - }); + .filter( + file => file.indexOf('.') !== 0 && + file !== 'index.js' && + file.slice(-3) === '.js', + ) + .forEach((file) => { + const model = sequelize.import(path.join(__dirname, file)); + db[model.name] = model; + }); Object.keys(db).forEach((modelName) => { - if (db[modelName].associate) { - db[modelName].associate(db); - } + if (db[modelName].associate) { + db[modelName].associate(db); + } }); db.sequelize = sequelize; diff --git a/src/models/notifications.js b/src/models/notifications.js deleted file mode 100644 index 9cfcd81..0000000 --- a/src/models/notifications.js +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = (sequelize, DataTypes) => { - const notifications = sequelize.define('notifications', { - user_id: DataTypes.INTEGER, - travel_id: DataTypes.INTEGER, - is_read: DataTypes.TEXT, - line_manager_email: DataTypes.TEXT, - line_manager_id: DataTypes.INTEGER, - message: { - type: DataTypes.TEXT, - allowNull: false, - validate: { - notEmpty: { - msg: 'notification content cannot be empty' - } - } - } - }, {}); - notifications.associate = (models) => { - notifications.belongsTo(models.users, { - foreignKey: 'user_id', - onDelete: 'CASCADE' - }); - - notifications.belongsTo(models.travel_requests, { - foreignKey: 'travel_id', - onDelete: 'CASCADE' - }); - - notifications.hasMany(models.departments, { - foreignKey: 'line_manager_id', - onDelete: 'CASCADE' - }); - - notifications.hasMany(models.departments, { - foreignKey: 'line_manager_email', - onDelete: 'CASCADE' - }); - }; - return notifications; -}; diff --git a/src/models/travel_request.js b/src/models/travel_request.js index 7960156..dd8c1f0 100644 --- a/src/models/travel_request.js +++ b/src/models/travel_request.js @@ -12,6 +12,7 @@ module.exports = (sequelize, DataTypes) => { return_date: DataTypes.DATE, travel_purpose: DataTypes.TEXT, accommodation_id: DataTypes.INTEGER, + dept_id: DataTypes.INTEGER, approval_status: { type: DataTypes.ENUM, values: ['accepted', 'pending', 'rejected'], @@ -34,11 +35,6 @@ module.exports = (sequelize, DataTypes) => { foreignKey: 'travel_id', onDelete: 'CASCADE' }); - - travel_request.hasMany(models.notifications, { - foreignKey: 'travel_id', - onDelete: 'CASCADE' - }); }; return travel_request; }; diff --git a/src/routes/authRoutes.js b/src/routes/authRoutes.js index 962f070..71000d1 100644 --- a/src/routes/authRoutes.js +++ b/src/routes/authRoutes.js @@ -1,10 +1,10 @@ import { Router } from 'express'; import passport from 'passport'; -import authControllers from '../../controllers/authControllers'; -import resetPassword from '../../controllers/resetPassword'; -import authValidator from '../../validation/authValidation'; -import { getToken, verifyToken } from '../../middlewares/tokenMiddleware'; +import authControllers from '../controllers/authControllers'; +import resetPassword from '../controllers/resetPassword'; +import authValidator from '../validation/authValidation'; +import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; const { sendPasswordResetEmail, receiveNewPassword } = resetPassword; diff --git a/src/routes/travelRoute.js b/src/routes/travelRoute.js index b49f7e8..f3dc077 100644 --- a/src/routes/travelRoute.js +++ b/src/routes/travelRoute.js @@ -1,17 +1,36 @@ import { Router } from 'express'; -import travelControllers from '../../controllers/travelControllers'; -import travelValidator from '../../validation/travelValidation'; -import { getToken, verifyToken } from '../../middlewares/tokenMiddleware'; +import { + createOneWayTrip, + pendingManagerApproval, + getUserTravelStatus, + approveTravelRequest, +} from '../controllers/travelControllers'; +import { + validateTravelRequest, + validateResult, +} from '../validation/travelValidation'; +import { verifyDeptManagerAndRequestStatus } from '../middlewares/travelsMiddleware'; +import { verifyRole } from '../middlewares/userMiddlewares'; +import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; const route = Router(); -const { createOneWayTrip, pendingManagerApproval } = travelControllers; -const { validateTravelRequest, validateResult } = travelValidator; // handles the api home route... -route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); +route.post('/travel/one_way_trip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); // handles manager pending req approvals route route.get('/requests/pending/:manager', getToken, verifyToken, pendingManagerApproval); +route.get('/user/status', getToken, verifyToken, getUserTravelStatus); + +route.patch( + '/travel/approve_request/:travel_id', + getToken, + verifyToken, + verifyRole('manager'), + verifyDeptManagerAndRequestStatus, + approveTravelRequest, +); + export default route; diff --git a/src/routes/travelRoute.js~HEAD b/src/routes/travelRoute.js~HEAD deleted file mode 100644 index 268b495..0000000 --- a/src/routes/travelRoute.js~HEAD +++ /dev/null @@ -1,20 +0,0 @@ -import { Router } from 'express'; - -import travelControllers from '../controllers/travelControllers'; -import travelValidator from '../validation/travelValidation'; -import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; - -const route = Router(); -const { createOneWayTrip, pendingManagerApproval, getUserTravelStatus } = travelControllers; -const { validateTravelRequest, validateResult } = travelValidator; - -// handles the api home route... -route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); - -// handles manager pending req approvals route -route.get('/requests/pending/:manager', getToken, verifyToken, pendingManagerApproval); - -route.get('/user/status', getToken, verifyToken, getUserTravelStatus); - - -export default route; diff --git a/src/routes/users.js b/src/routes/users.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/services/departmentServices.js b/src/services/departmentServices.js new file mode 100644 index 0000000..c0f38a8 --- /dev/null +++ b/src/services/departmentServices.js @@ -0,0 +1,19 @@ +/* eslint-disable no-useless-catch */ +import 'core-js/stable'; +import 'regenerator-runtime/runtime'; + +import models from '../models'; + +const { departments } = models; + +export const createDepartment = async (comment) => {}; + +export const getADepartment = async (id) => { + try { + return await departments.findOne({ + where: { id }, + }); + } catch (err) { + throw err; + } +}; diff --git a/src/services/emailServices.js b/src/services/emailServices.js index 1753773..1aa1fee 100644 --- a/src/services/emailServices.js +++ b/src/services/emailServices.js @@ -7,25 +7,25 @@ const { users } = models; * Helper function to find a user by email * @param {String} email - user's email * @returns {Promise} - sequelize response +*/ +const queryByEmail = async (email) => { + try{ + return await users.findOne({ where: { email } }); + }catch(err){ + throw err; + } +} +/** + * Helper function to find a user by id + * @param {String} id - user's id + * @returns {Promise} - sequelize response */ -const queryByEmail = async(email) => { - try { - return await users.findOne({ where: { email } }); - } catch (err) { - throw err; - } - } - /** - * Helper function to find a user by id - * @param {String} id - user's id - * @returns {Promise} - sequelize response - */ -const queryById = async(id) => { - try { - return await users.findOne({ where: { id } }); - } catch (err) { - throw err - } +const queryById = async (id) => { + try{ + return await users.findOne({ where: { id } }); + }catch(err){ + throw err + } } /** @@ -34,16 +34,16 @@ const queryById = async(id) => { * @param {String} id - user's id * @returns {Promise} - sequelize response */ -const updatePassword = async(hash, id) => { - try { - return await users.update(hash, { where: { id } }); - } catch (err) { - throw err - } +const updatePassword = async (hash, id) =>{ + try{ + return await users.update(hash, { where: { id } }); + }catch(err){ + throw err + } } export default { - queryByEmail, - queryById, - updatePassword -}; + queryByEmail, + queryById, + updatePassword +} diff --git a/src/services/travelServices.js b/src/services/travelServices.js index 076c952..ee59224 100644 --- a/src/services/travelServices.js +++ b/src/services/travelServices.js @@ -16,8 +16,7 @@ export const onewayTripService = async (travelObj) => { export const findTravelById = async (id) => { try { return await travel_requests.findOne({ - attributes: ['id', 'user_id'], - where: { id }, + where: { id } }); } catch (err) { throw err; @@ -56,10 +55,21 @@ export const showUsertravelsStatus = async (userId) => { try { return await travel_requests.findAll({ where: { - user_id: userId - } + user_id: userId, + }, }); } catch (error) { throw error; } }; + +export const approveTravel = async (id) => { + try { + return await travel_requests.update( + { approval_status: 'accepted' }, + { returning: true, where: { id } } + ); + } catch (err) { + throw err; + } +}; diff --git a/src/tests/auth.test.js b/src/tests/auth.test.js index 9c9d898..5f3b6ba 100644 --- a/src/tests/auth.test.js +++ b/src/tests/auth.test.js @@ -14,6 +14,7 @@ const passwordResetToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjM let passwordUserId; + chai.use(chaiHttp); describe('Test for the Auth controller functions', () => { @@ -23,13 +24,15 @@ describe('Test for the Auth controller functions', () => { email: 'emma.k@yahoo.com', password: 'testing123', }; + it('should successfully sign up a user', (done) => { chai .request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(user) .end((err, res) => { const { data } = res.body; + expect(res).to.have.status(201); expect(data).to.include({ first_name: 'Emma', @@ -39,17 +42,18 @@ describe('Test for the Auth controller functions', () => { done(); }); }); + it('should return an error message if the email is empty', (done) => { const mutatedUser = Object.assign({}, user); delete mutatedUser.email; chai.request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal('Email cannot be empty.'); + .equal(message.noEmail); done(); }); }); @@ -58,23 +62,23 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'invalid@yahoo'; chai.request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal('Please, enter a valid email address.'); + .equal(message.invalidEmail); done(); }); }); it('should return an error message if the email already exists', (done) => { chai.request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(user) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal(`User with this email (${user.email}) already exist.`); + .equal(message.usedEmail(user.email)); done(); }); }); @@ -84,12 +88,12 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal('The length of the password must be 8 and above.'); + .equal(message.shortPassword); done(); }); }); @@ -99,12 +103,12 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal('Password must contain at least one digit.'); + .equal(message.noDigitInPassword); done(); }); }); @@ -114,12 +118,12 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal('First name cannot be empty.'); + .equal(message.emptyFirstname); done(); }); }); @@ -129,176 +133,224 @@ describe('Test for the Auth controller functions', () => { mutatedUser.email = 'valid@yahoo.com'; chai.request(app) - .post(`${prefix}/auth/signup`) + .post(signupRoute) .send(mutatedUser) .end((err, res) => { expect(res.status).to.equal(400); expect(res.body.error[0]).to - .equal('Last name cannot be empty.'); + .equal(message.emptyLastname); done(); }); }); +}); - // This is the tests that will run for the user signin with username and password.. - describe('TEST USER LOGIN ROUTE', () => { - let signinRoute = `${prefix}/auth/login`; - - const loginData = { - email: 'emma.k@yahoo.com', - password: 'testing123' - }; - - it('should throw an error with a status of 400 if the email supplied is invalid', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.email = 'invalidemail'; - - chai.request(app) - .post(`${prefix}/auth/login`) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal('Please, enter a valid email address.'); - done(); - }); - }); - - it('should throw an error with a status of 404 if the email supplied does not exist', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.email = 'testerroremail@yahoo.com'; - - chai - .request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { status } = res; - expect(status).to.be.eql(404); - done(err); - }); - }); - - it('should return an error message if the password length is less than 8', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'pwdless'; - - chai.request(app) - .post(`${prefix}/auth/login`) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal('The length of the password must be 8 and above.'); - done(err); - }); - }); - - it('should return an error message if the password does not contain at least a digit', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'nodigitpwd'; - - chai.request(app) - .post(`${prefix}/auth/login`) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal('Password must contain at least one digit.'); - done(err); - }); - }); - - it('should throw an error with a status of 400 if the password supplied is wrong', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'passw4567'; - - chai - .request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.be.eql(400); - expect(body.error.message).to - .equal('Sorry, the password entered is not correct.'); - done(err); - }); - }); - - it('should authenticate a user with a valid email and password', (done) => { - chai - .request(app) - .post(signinRoute) - .send(loginData) - .end((err, res) => { - const { body, status } = res; - expect(body.data).to.not.eql(null); - expect(status).to.be.eql(200); - done(err); - }); - }); - - it('should contain a token value in its response data object', (done) => { - chai.request(app) - .post(signinRoute) - .send(loginData) - .end((err, res) => { - const { data } = res.body; - expect(data).to.have.ownProperty('token'); - done(err); - }); - }); +// This is the tests that will run for the user signin with username and password.. +describe('TEST USER LOGIN ROUTE', () => { + + + const loginData = { + email: 'emma.k@yahoo.com', + password: 'testing123' + }; + + it('should throw an error with a status of 400 if the email supplied is invalid', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.email = 'invalidemail'; + + chai.request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal(message.invalidEmail); + done(); + }); }); - // The test for the auth/login by email and paswword ends here... - - - describe('Testing logout feature', () => { - const testuser = { - first_name: 'Emmatest', - last_name: 'Koredetest', - email: 'emmaff.k@yahoo.com', - password: 'testing321', - }; - let token; - before((done) => { - chai - .request(app) - .post(`${prefix}/auth/signup`) - .send(testuser) - .end((err, res) => { - const { data } = res.body; - token = data.token; - done(); - }); - }); - it('should return an error if token is not supplied', (done) => { - chai.request(app) - .post(`${prefix}/auth/logout`) - .end((err, res) => { - expect(res.status).to.equal(401); - done(); - }); - }); - it('should return an error if the token is invalid', (done) => { - chai.request(app) - .post(`${prefix}/auth/logout`) - .set('Authorization', 'Bearer hjgvju') - .end((err, res) => { - expect(res.status).to.equal(401); - done(); - }); - }); - it('should successfully logout a user', (done) => { - chai.request(app) - .post(`${prefix}/auth/logout`) - .set('Authorization', `Bearer ${token}`) - .end((err, res) => { - expect(res.status).to.equal(200); - done(); - }); - }); + + it('should throw an error with a status of 404 if the email supplied does not exist', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.email = 'testerroremail@yahoo.com'; + + chai + .request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { status } = res; + expect(status).to.be.eql(404); + done(err); + }); + }); + + it('should return an error message if the password length is less than 8', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'pwdless'; + + chai.request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal(message.shortPassword); + done(err); + }); + }); + + it('should return an error message if the password does not contain at least a digit', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'nodigitpwd'; + + chai.request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error[0]).to + .equal(message.noDigitInPassword); + done(err); + }); + }); + + it('should throw an error with a status of 400 if the password supplied is wrong', (done) => { + const invalidData = Object.assign({}, loginData); + invalidData.password = 'passw4567'; + + chai + .request(app) + .post(signinRoute) + .send(invalidData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.be.eql(400); + expect(body.error.message).to + .equal(message.incorrectPassword); + done(err); + }); + }); + + it('should authenticate a user with a valid email and password', (done) => { + chai + .request(app) + .post(signinRoute) + .send(loginData) + .end((err, res) => { + const { body, status } = res; + expect(body.data).to.not.eql(null); + expect(status).to.be.eql(200); + done(err); + }); + }); + + it('should contain a token value in its response data object', (done) => { + chai.request(app) + .post(signinRoute) + .send(loginData) + .end((err, res) => { + const { data } = res.body; + expect(data).to.have.ownProperty('token'); + done(err); + }); + }); +}); +// The test for the auth/login by email and paswword ends here... + +describe('Testing logout feature', () => { + const testuser = { + first_name: 'Emmatesto', + last_name: 'Koredetesto', + email: 'emmaff.ki@yahoo.com', + password: 'testing321', + }; + let token; + before((done) => { + chai + .request(app) + .post(signupRoute) + .send(testuser) + .end((err, res) => { + const { data } = res.body; + token = data.token; + done(); + }); + }); + + it('should return an error if token is not supplied', (done) => { + chai.request(app) + .post(logoutRoute) + .end((err, res) => { + expect(res.status).to.equal(401); + done(); + }); + }); + it('should return an error if the token is invalid', (done) => { + chai.request(app) + .post(logoutRoute) + .set('Authorization', 'Bearer hjgvju') + .end((err, res) => { + expect(res.status).to.equal(401); + done(); + }); + }); + it('should successfully logout a user', (done) => { + chai.request(app) + .post(logoutRoute) + .set('Authorization', token) + .end((err, res) => { + expect(res.status).to.equal(200); + done(); + }); + }); +}); + +describe('Send Password Reset', () => { + const testuser = { + first_name: 'Temi', + last_name: 'Bakar', + email: 'bakaretemitayo@gmail.com', + password: 'testing321', + }; + let email; + before((done) => { + chai + .request(app) + .post(signupRoute) + .send(testuser) + .end((err, res) => { + const { data } = res.body; + email = data.email; + passwordUserId = data.id; + done(); + }); + }); + + /* it('it should send token for resetting password', (done) => { + // eslint-disable-next-line quote-props + const user_email = { 'email': email }; + chai.request(app) + .post(`${prefix}/forgot`) + .send(user_email) + .end((err, res) => { + expect(res.status).to.equal(200); + expect(user_email).to.have.property('email'); + done(); + }); + }); */ + + + it('it should reset password via password reset link', (done) => { + const passwordResetData = { password: 'testpassword' }; + chai.request(app) + .post(`${prefix}/receive_new_password/${passwordUserId}/${passwordResetToken}`) + .send(passwordResetData) + .end((err, res) => { + expect(res.status).to.equal(202); + expect(passwordResetData).to.have.property('password'); + done(); + }); }); }); diff --git a/src/tests/authTest.js b/src/tests/authTest.js deleted file mode 100644 index 6e618bf..0000000 --- a/src/tests/authTest.js +++ /dev/null @@ -1,357 +0,0 @@ -/* eslint-disable prefer-object-spread */ -import chai, { expect } from 'chai'; -import chaiHttp from 'chai-http'; -import dotenv from 'dotenv'; - -import app from '../index'; - -const prefix = '/api/v1'; - -let passwordUserId; -const passwordResetToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImlhdCI6MTU2NzUzNzkwNSwiZXhwIjoxNTY3NTQxNTA1fQ.nPMaVY0-y_FhF9eVroUIe08PXW9kqnmmqUvAcu8uD74'; - - -dotenv.config(); - -chai.use(chaiHttp); - -describe('Test for the Auth controller functions', () => { - const user = { - first_name: 'Emma', - last_name: 'Korede', - email: 'emma.k@yahoo.com', - password: 'testing123', - }; - - it('should successfully sign up a user', (done) => { - chai - .request(app) - .post(`${prefix}/auth/signup`) - .send(user) - .end((err, res) => { - const { data } = res.body; - - expect(res).to.have.status(201); - expect(data).to.include({ - first_name: 'Emma', - last_name: 'Korede', - email: 'emma.k@yahoo.com', - }); - done(); - }); - }); - - it('should return an error message if the email is empty', (done) => { - const mutatedUser = Object.assign({}, user); - delete mutatedUser.email; - - chai.request(app) - .post(`${prefix}/auth/signup`) - .send(mutatedUser) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal('Email cannot be empty.'); - done(); - }); - }); - it('should return an error message if the email is invalid', (done) => { - const mutatedUser = Object.assign({}, user); - mutatedUser.email = 'invalid@yahoo'; - - chai.request(app) - .post(`${prefix}/auth/signup`) - .send(mutatedUser) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal('Please, enter a valid email address.'); - done(); - }); - }); - it('should return an error message if the email already exists', (done) => { - chai.request(app) - .post(`${prefix}/auth/signup`) - .send(user) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(`User with this email (${user.email}) already exist.`); - done(); - }); - }); - it('should return an error message if the password length is less than 8', (done) => { - const mutatedUser = Object.assign({}, user); - mutatedUser.password = 'test'; - mutatedUser.email = 'valid@yahoo.com'; - - chai.request(app) - .post(`${prefix}/auth/signup`) - .send(mutatedUser) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal('The length of the password must be 8 and above.'); - done(); - }); - }); - it('should return an error message if the password does not contain at least a digit', (done) => { - const mutatedUser = Object.assign({}, user); - mutatedUser.password = 'testingit'; - mutatedUser.email = 'valid@yahoo.com'; - - chai.request(app) - .post(`${prefix}/auth/signup`) - .send(mutatedUser) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal('Password must contain at least one digit.'); - done(); - }); - }); - it('should return an error message if the first name is empty', (done) => { - const mutatedUser = Object.assign({}, user); - mutatedUser.first_name = ''; - mutatedUser.email = 'valid@yahoo.com'; - - chai.request(app) - .post(`${prefix}/auth/signup`) - .send(mutatedUser) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal('First name cannot be empty.'); - done(); - }); - }); - it('should return an error message if the last name is empty', (done) => { - const mutatedUser = Object.assign({}, user); - mutatedUser.last_name = ''; - mutatedUser.email = 'valid@yahoo.com'; - - chai.request(app) - .post(`${prefix}/auth/signup`) - .send(mutatedUser) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal('Last name cannot be empty.'); - done(); - }); - }); -}); - - -describe('Testing logout feature', () => { - // This is the tests that will run for the user signin with username and password.. - describe('TEST USER LOGIN ROUTE', () => { - const signinRoute = `${prefix}/auth/login`; - - const loginData = { - email: 'emma.k@yahoo.com', - password: 'testing123' - }; - - it('should throw an error with a status of 400 if the email supplied is invalid', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.email = 'invalidemail'; - - chai.request(app) - .post(`${prefix}/auth/login`) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal('Please, enter a valid email address.'); - done(); - }); - }); - - it('should throw an error with a status of 404 if the email supplied does not exist', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.email = 'testerroremail@yahoo.com'; - - chai - .request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { status } = res; - expect(status).to.be.eql(404); - done(err); - }); - }); - - it('should return an error message if the password length is less than 8', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'pwdless'; - - chai.request(app) - .post(`${prefix}/auth/login`) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal('The length of the password must be 8 and above.'); - done(err); - }); - }); - - it('should return an error message if the password does not contain at least a digit', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'nodigitpwd'; - - chai.request(app) - .post(`${prefix}/auth/login`) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error[0]).to - .equal('Password must contain at least one digit.'); - done(err); - }); - }); - - it('should throw an error with a status of 400 if the password supplied is wrong', (done) => { - const invalidData = Object.assign({}, loginData); - invalidData.password = 'passw4567'; - - chai - .request(app) - .post(signinRoute) - .send(invalidData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.be.eql(400); - expect(body.error.message).to - .equal('Sorry, the password entered is not correct.'); - done(err); - }); - }); - - it('should authenticate a user with a valid email and password', (done) => { - chai - .request(app) - .post(signinRoute) - .send(loginData) - .end((err, res) => { - const { body, status } = res; - expect(body.data).to.not.eql(null); - expect(status).to.be.eql(200); - done(err); - }); - }); - - it('should contain a token value in its response data object', (done) => { - chai.request(app) - .post(signinRoute) - .send(loginData) - .end((err, res) => { - const { data } = res.body; - expect(data).to.have.ownProperty('token'); - done(err); - }); - }); - }); -}); -// The test for the auth/login by email and paswword ends here... - -describe('Testing logout feature', () => { - const testuser = { - first_name: 'Emmatesto', - last_name: 'Koredetesto', - email: 'emmaff.ki@yahoo.com', - password: 'testing321', - }; - let token; - before((done) => { - chai - .request(app) - .post(`${prefix}/auth/signup`) - .send(testuser) - .end((err, res) => { - const { data } = res.body; - token = data.token; - done(); - }); - }); - - it('should return an error if token is not supplied', (done) => { - chai.request(app) - .post(`${prefix}/auth/logout`) - .end((err, res) => { - expect(res.status).to.equal(401); - done(); - }); - }); - it('should return an error if the token is invalid', (done) => { - chai.request(app) - .post(`${prefix}/auth/logout`) - .set('Authorization', 'Bearer hjgvju') - .end((err, res) => { - expect(res.status).to.equal(401); - done(); - }); - }); - it('should successfully logout a user', (done) => { - chai.request(app) - .post(`${prefix}/auth/logout`) - .set('Authorization', `Bearer ${token}`) - .end((err, res) => { - expect(res.status).to.equal(200); - done(); - }); - }); -}); - -describe('Send Password Reset', () => { - const testuser = { - first_name: 'Temi', - last_name: 'Bakar', - email: 'bakaretemitayo@gmail.com', - password: 'testing321', - }; - let email; - before((done) => { - chai - .request(app) - .post(`${prefix}/auth/signup`) - .send(testuser) - .end((err, res) => { - const { data } = res.body; - email = data.email; - passwordUserId = data.id; - done(); - }); - }); - - /* it('it should send token for resetting password', (done) => { - // eslint-disable-next-line quote-props - const user_email = { 'email': email }; - chai.request(app) - .post(`${prefix}/forgot`) - .send(user_email) - .end((err, res) => { - expect(res.status).to.equal(200); - expect(user_email).to.have.property('email'); - done(); - }); - }); */ - - - it('it should reset password via password reset link', (done) => { - const passwordResetData = { password: 'testpassword' }; - chai.request(app) - .post(`${prefix}/receive_new_password/${passwordUserId}/${passwordResetToken}`) - .send(passwordResetData) - .end((err, res) => { - expect(res.status).to.equal(202); - expect(passwordResetData).to.have.property('password'); - done(); - }); - }); -}); diff --git a/src/tests/mockData.js b/src/tests/mockData.js index 67e730a..fa66d8c 100644 --- a/src/tests/mockData.js +++ b/src/tests/mockData.js @@ -17,6 +17,24 @@ export const testUser2 = { password: 'testing123', }; +export const testManager1 = { + email: 'rose.querty@yahoo.com', + password: 'testing123', +}; + +export const testManager2 = { + email: 'm.benchfort@yahoo.com', + password: 'testing123', +}; + +// Test Travel Request +export const testTravelRequest = { + origin: 'Lagos', + destination: 'Kigali', + departure_date: '2019-12-12', + travel_purpose: 'This is a one way trip', + accommodation_id: 1653453, +}; export const validTravelId = '1891029'; // Test comment diff --git a/src/tests/travel.test.js b/src/tests/travel.test.js index cd1b0ae..46a8e7f 100644 --- a/src/tests/travel.test.js +++ b/src/tests/travel.test.js @@ -2,13 +2,23 @@ import chai, { expect } from 'chai'; import chaiHttp from 'chai-http'; import dotenv from 'dotenv'; + import message from '../utils/messageUtils'; -import { travelRequest } from './mockData'; +import { + testUser2, + testTravelRequest, + testManager1, + testManager2, + validTravelId, +} from './mockData'; import app from '../index'; const prefix = '/api/v1'; const signupRoute = `${prefix}/auth/signup`; -const onewayRoute = `${prefix}/onewaytrip`; +const loginRoute = `${prefix}/auth/login`; +const onewayRoute = `${prefix}/travel/one_way_trip`; +const approveRequestRoute = `${prefix}/travel/approve_request/${validTravelId}`; + dotenv.config(); chai.use(chaiHttp); @@ -16,20 +26,12 @@ chai.use(chaiHttp); let token; describe('Testing one way ticket feature', () => { - const user = { - first_name: 'myname', - last_name: 'mylastname', - email: 'mygmailis@gmail.com', - password: 'protected123pass', - }; - - it('should successfully create a user', (done) => { + before((done) => { chai .request(app) - .post(signupRoute) - .send(user) + .post(loginRoute) + .send(testUser2) .end((err, res) => { - expect(res).to.have.status(201); const { data } = res.body; token = data.token; done(); @@ -41,7 +43,7 @@ describe('Testing one way ticket feature', () => { .request(app) .post(onewayRoute) .set('Authorization', token) - .send(travelRequest) + .send(testTravelRequest) .end((err, res) => { expect(res).to.have.status(201); done(); @@ -49,9 +51,10 @@ describe('Testing one way ticket feature', () => { }); it('should return an error if the token is invalid', (done) => { - chai.request(app) + chai + .request(app) .post(onewayRoute) - .send(travelRequest) + .send(testTravelRequest) .end((err, res) => { expect(res.status).to.equal(401); done(); @@ -59,91 +62,92 @@ describe('Testing one way ticket feature', () => { }); it('should return an error if origin is empty', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.origin = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyOrigin); + expect(res.body.error[0]).to.equal(message.emptyOrigin); done(); }); }); it('should return an error message if origin contains integers', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.origin = '4Lag12'; - chai.request(app) + + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.lettersAlone); + expect(res.body.error[0]).to.equal(message.lettersAlone); done(); }); }); it('should return an error message if the destination is empty', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.destination = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyDestination); + expect(res.body.error[0]).to.equal(message.emptyDestination); done(); }); }); it('should return an error message if the destination contains integers', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.destination = '4Kigs23'; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.lettersAlone); + expect(res.body.error[0]).to.equal(message.lettersAlone); done(); }); }); it('should return an error message if the departure date is empty', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.departure_date = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyDepartureDate); + expect(res.body.error[0]).to.equal(message.emptyDepartureDate); done(); }); }); it('should return an error message if travel_purpose', (done) => { - const mutatedtravelRequest = Object.assign({}, travelRequest); + const mutatedtravelRequest = { ...testTravelRequest }; mutatedtravelRequest.travel_purpose = ''; - chai.request(app) + chai + .request(app) .post(onewayRoute) .set('Authorization', token) .send(mutatedtravelRequest) .end((err, res) => { expect(res.status).to.equal(400); - expect(res.body.error[0]).to - .equal(message.emptyTravelPurpose); + expect(res.body.error[0]).to.equal(message.emptyTravelPurpose); done(); }); }); @@ -158,7 +162,7 @@ describe('Testing Avail request for approval', () => { last_name: 'mylastnoamep', email: 'mygmailisj@gomail.com', password: 'protected123pass', - role: 'admin' + role: 'manager', }; it('should successfully create an admin user', (done) => { @@ -199,10 +203,10 @@ describe('Testing Avail request for approval', () => { // Get users request status -describe('Testing for users request status', ()=> { - it('should successfully return user request status', (done)=> { +describe('Testing for users request status', () => { + it('should successfully return user request status', (done) => { chai - .request(app) + .request(app) .get(`${prefix}/user/status`) .set('Authorization', token) .end((err, res) => { @@ -210,9 +214,9 @@ describe('Testing for users request status', ()=> { done(); }); }); - it('should return error when role is admin', (done) => { + it('should return error when role is a manager', (done) => { chai - .request(app) + .request(app) .get(`${prefix}/user/status`) .set('Authorization', adminToken) .end((err, res) => { @@ -221,3 +225,72 @@ describe('Testing for users request status', ()=> { }); }); }); + +describe('Testing the travel approval route', () => { + let managerToken1, managerToken2; + + before((done) => { + chai + .request(app) + .post(`${prefix}/auth/login`) + .send(testManager1) + .end((err, res) => { + const { data } = res.body; + managerToken1 = data.token; + done(); + }); + }); + before((done) => { + chai + .request(app) + .post(`${prefix}/auth/login`) + .send(testManager2) + .end((err, res) => { + const { data } = res.body; + managerToken2 = data.token; + done(); + }); + }); + + it('should not allow a manager to approve travel in another department', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken2) + .end((err, res) => { + expect(res).to.have.status(401); + expect(res.body.error).to.equal(message.diffDepartment); + done(); + }); + }); + it('should successfully approve a travel request', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken1) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + it('should return error if the travel request is not pending', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken1) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); + it('should not allow a normal user to approve a travel request', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', token) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); +}); diff --git a/src/utils/messageUtils.js b/src/utils/messageUtils.js index 72d7e5b..ae3f721 100644 --- a/src/utils/messageUtils.js +++ b/src/utils/messageUtils.js @@ -10,6 +10,7 @@ export default { managerApproval: (pendingReq) => `You have ${pendingReq} requests requiring your approval`, managerNotFound: "Manager's detail missing", noEmail: 'Email cannot be empty.', + userApproval: 'Here are your request status', // sign-up validation messages invalidEmail: 'Please, enter a valid email address.', usedEmail: (email) => `User with this email (${email}) already exist.`, @@ -46,4 +47,9 @@ export default { unauthorizedCommentDelete: "comment can only be deleted by it's author", commentNotFound: 'The comment does not exist.', deleteComment: 'Comment successfully deleted.', + + requestNotPending: 'This Travel Request is not Pending.', + diffDepartment: 'You are not in the same department as the Travel Requester.', + wrongRole: (role) => `Sorry, you are not a/an ${role}.`, + successfullyApproval: (requester) => `You have successfully approved a travel request from ${requester}.`, }; diff --git a/src/validation/travelValidation.js b/src/validation/travelValidation.js index 44cdaf0..6fad15b 100644 --- a/src/validation/travelValidation.js +++ b/src/validation/travelValidation.js @@ -1,33 +1,40 @@ import { check, validationResult } from 'express-validator'; - import { errorResponse } from '../utils/response'; import statusCode from '../utils/statusCode'; import message from '../utils/messageUtils'; -export default { - validateTravelRequest: [ - check('origin').not().isEmpty() - .withMessage(message.emptyOrigin) - .isAlpha() - .withMessage(message.lettersAlone), - check('destination').not().isEmpty() - .withMessage(message.emptyDestination) - .isAlpha() - .withMessage(message.lettersAlone), - check('departure_date').not().isEmpty().withMessage(message.emptyDepartureDate), - check('travel_purpose').not().isEmpty().withMessage(message.emptyTravelPurpose), - ], - validateResult: (req, res, next) => { - const errors = validationResult(req); - if (!errors.isEmpty()) { - const error = []; - errors.array().forEach((err) => { - error.push(err.msg); - }); - return errorResponse(res, statusCode.badRequest, error); - } - return next(); - }, +export const validateTravelRequest = [ + check('origin') + .not() + .isEmpty() + .withMessage(message.emptyOrigin) + .isAlpha() + .withMessage(message.lettersAlone), + check('destination') + .not() + .isEmpty() + .withMessage(message.emptyDestination) + .isAlpha() + .withMessage(message.lettersAlone), + check('departure_date') + .not() + .isEmpty() + .withMessage(message.emptyDepartureDate), + check('travel_purpose') + .not() + .isEmpty() + .withMessage(message.emptyTravelPurpose), +]; +export const validateResult = (req, res, next) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + const error = []; + errors.array().forEach((err) => { + error.push(err.msg); + }); + return errorResponse(res, statusCode.badRequest, error); + } + return next(); }; From a6a3cfc6a8cd0b175d5d89b11573d3dbd54bc75b Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Fri, 13 Sep 2019 17:55:53 +0100 Subject: [PATCH 19/23] implementation of notification features --- package-lock.json | 27 ++++++++++ package.json | 1 + src/controllers/client.js | 54 +++++++++++++++++++ src/controllers/notifyControllers.js | 31 +++++++++++ .../20190912134053-create-notifications.js | 43 +++++++++++++++ .../seeders/20190912140255-notifications.js | 31 +++++++++++ src/index.js | 24 +++++++-- src/models/notifications.js | 30 +++++++++++ src/routes/notifyRoutes.js | 33 ++++++++++++ src/services/notifyServices.js | 27 ++++++++++ src/services/websocket.js | 33 ++++++++++++ src/utils/notifyEmailUtils.js | 9 ++++ 12 files changed, 339 insertions(+), 4 deletions(-) create mode 100644 src/controllers/client.js create mode 100644 src/controllers/notifyControllers.js create mode 100644 src/database/migrations/20190912134053-create-notifications.js create mode 100644 src/database/seeders/20190912140255-notifications.js create mode 100644 src/models/notifications.js create mode 100644 src/routes/notifyRoutes.js create mode 100644 src/services/notifyServices.js create mode 100644 src/services/websocket.js create mode 100644 src/utils/notifyEmailUtils.js diff --git a/package-lock.json b/package-lock.json index b7ce252..5b3db28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -911,6 +911,20 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==" }, + "@types/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-f8JzJNWVhKtc9dg/dyDNfliTKNOJSLa7Oht/ElZdF/UbMUmAH3rLmAk3ODNjw0mZajDEgatA03tRjB4+Dp/tzA==" + }, + "@types/react": { + "version": "16.9.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.2.tgz", + "integrity": "sha512-jYP2LWwlh+FTqGd9v7ynUKZzjj98T8x7Yclz479QdRhHfuW9yQ+0jjnD31eXSXutmBpppj5PYNLYLRfnZJvcfg==", + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, "@types/request": { "version": "2.48.3", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.3.tgz", @@ -1268,6 +1282,14 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "auto-bind": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-2.1.0.tgz", + "integrity": "sha512-qZuFvkes1eh9lB2mg8/HG18C+5GIO51r+RrCSst/lh+i5B1CtVlkhTE488M805Nr3dKl0sM/pIFKSKUIlg3zUg==", + "requires": { + "@types/react": "^16.8.12" + } + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -2359,6 +2381,11 @@ "type-fest": "^0.5.2" } }, + "csstype": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz", + "integrity": "sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==" + }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", diff --git a/package.json b/package.json index 158e123..f3a1549 100755 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "dependencies": { "@babel/runtime": "^7.5.5", "@sendgrid/mail": "^6.4.0", + "auto-bind": "^2.1.0", "bcryptjs": "^2.4.3", "chai": "^4.2.0", "chai-http": "^4.3.0", diff --git a/src/controllers/client.js b/src/controllers/client.js new file mode 100644 index 0000000..8d7866d --- /dev/null +++ b/src/controllers/client.js @@ -0,0 +1,54 @@ +/* eslint-disable import/named */ +/* eslint-disable require-jsdoc */ + +class ClientController { + /** + * @param {Object} req + * @param {Object} res + * @returns {Object} the new user + * @description register a new client + */ + static async getClient(req, res) { + const { user_id } = req.params; + + const message = ` + + + + + + Chat App + + + + +
+

Notify User Travels

+ +
+ + + + + `; + + res.send(message); + } +} + +export default ClientController; diff --git a/src/controllers/notifyControllers.js b/src/controllers/notifyControllers.js new file mode 100644 index 0000000..0840aae --- /dev/null +++ b/src/controllers/notifyControllers.js @@ -0,0 +1,31 @@ +/* eslint-disable require-jsdoc */ +import models from '../models'; + +const { notifications } = models; + +export default { + + getAllNotification: async (req, res) => { + try { + const user_id = req.users.id; + const allRequests = await notifications.findAll({ where: { receiver: user_id } }); + return res.status(200).json({ status: 200, data: allRequests }); + } catch (error) { + res.status(500).json({ status: 500, error }); + } + }, + + readAllNotification: async (req, res) => { + try { + const user_id = req.user.id; + const allRequestsByUser = await notifications.update({ is_read: true }, { + where: { + receiver: user_id + } + }); + return res.status(200).json({ status: 200, data: allRequestsByUser }); + } catch (error) { + res.status(500).json({ status: 500, error }); + } + }, +}; diff --git a/src/database/migrations/20190912134053-create-notifications.js b/src/database/migrations/20190912134053-create-notifications.js new file mode 100644 index 0000000..10343a2 --- /dev/null +++ b/src/database/migrations/20190912134053-create-notifications.js @@ -0,0 +1,43 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('notifications', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + user_id: { + type: Sequelize.INTEGER + }, + travel_id: { + type: Sequelize.INTEGER + }, + is_read: { + type: Sequelize.BOOLEAN + }, + line_manager_id: { + allowNull: false, + type: Sequelize.INTEGER + }, + line_manager_email: { + allowNull: false, + type: Sequelize.STRING + }, + message: { + type: Sequelize.TEXT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('notifications'); + } +}; diff --git a/src/database/seeders/20190912140255-notifications.js b/src/database/seeders/20190912140255-notifications.js new file mode 100644 index 0000000..a5af6de --- /dev/null +++ b/src/database/seeders/20190912140255-notifications.js @@ -0,0 +1,31 @@ +module.exports = { + up: function up(queryInterface, Sequelize) { + return queryInterface.bulkInsert('notifications', [{ + id: 333, + user_id: 1674946, + travel_id: 1898451, + line_manager_id: 6453673, + line_manager_email: 'chidiebere_chukwuma@yahoo.com', + is_read: false, + message: 'Your travel request has been created', + createdAt: new Date(), + updatedAt: new Date() + }, + { + id: 1627, + user_id: 1215739, + travel_id: 1891029, + line_manager_id: 3640773, + line_manager_email: 'chukschiboy@gmail.com', + is_read: false, + message: 'Your travel request has been created', + createdAt: new Date(), + updatedAt: new Date() + } + ], {}); + }, + + down: function down(queryInterface, Sequelize) { + return queryInterface.bulkDelete('notifications', null, {}); + } +}; diff --git a/src/index.js b/src/index.js index c2ed93f..5a53246 100755 --- a/src/index.js +++ b/src/index.js @@ -6,17 +6,23 @@ import logger from 'morgan'; import debug from 'debug'; import cors from 'cors'; import methodOverride from 'method-override'; - +import http from 'http'; +import socketIo from 'socket.io'; import { fbStrategy, googleStrategy } from './config/passport'; import message from './utils/messageUtils'; import response from './utils/response'; import statusCode from './utils/statusCode'; import routes from './routes'; +import socketEmission from './services/websocket'; dotenv.config(); const debugLog = debug('web-app'); // Create global app object const app = express(); +const server = http.createServer(app); + +const io = socketIo(server); +const emission = new socketEmission(io); const PORT = process.env.PORT || 5000; @@ -46,7 +52,7 @@ passport.deserializeUser((user, cb) => { // serve the api endpoints built in routes folder -routes(prefix, app); +routes(prefix, app, io); // handles the api home route... app.all('/', (req, res) => response.successResponse(res, statusCode.success, message.defaultWelcome)); // serve the api endpoints built in routes folder @@ -115,9 +121,19 @@ app.use((err, req, res, next) => { next(); }); -app.listen(PORT, () => { +server.listen(PORT, () => { debugLog(`Barefoot-Nomad [Backend] Server is running on port ${PORT}`); }); +// Creating the client connection of Socket.io +io.on('connection', (client) => { + logger(`A client connected ${client.id}`); + client.emit('confirmation', 'We are successfully connected'); + + client.on('disconnect', () => { + logger(`A user connected ${client.id}`); + }); +}); + // for testing -export default app; +module.exports = server; diff --git a/src/models/notifications.js b/src/models/notifications.js new file mode 100644 index 0000000..146ff07 --- /dev/null +++ b/src/models/notifications.js @@ -0,0 +1,30 @@ +module.exports = (sequelize, DataTypes) => { + const notifications = sequelize.define('notifications', { + user_id: DataTypes.INTEGER, + travel_id: DataTypes.INTEGER, + line_manager_email: DataTypes.TEXT, + line_manager_id: DataTypes.INTEGER, + is_read: DataTypes.BOOLEAN, + message: { + type: DataTypes.TEXT, + allowNull: false, + validate: { + notEmpty: { + msg: 'notification content cannot be empty' + } + } + } + }, {}); + notifications.associate = (models) => { + notifications.belongsTo(models.users, { + foreignKey: 'user_id', + onDelete: 'CASCADE' + }); + + notifications.belongsTo(models.travel_requests, { + foreignKey: 'travel_id', + onDelete: 'CASCADE' + }); + }; + return notifications; +}; diff --git a/src/routes/notifyRoutes.js b/src/routes/notifyRoutes.js new file mode 100644 index 0000000..7095835 --- /dev/null +++ b/src/routes/notifyRoutes.js @@ -0,0 +1,33 @@ +import { Router } from 'express'; +// import { notifyControllers } from '../../controllers'; +import ClientController from '../controllers/client'; +// import tokenMiddleware from '../../middlewares/tokenMiddleware'; + + +const router = Router(); +const { getClient } = ClientController; +// const { getToken, verifyToken } = tokenMiddleware; + +// api/v1/notification is already prepended to the request +// router.get('/notify', notificationController.getAllNotification); +// router.patch('/notify', notificationController.readAllNotification); + + +// router.use('/auth', auth); +router.get('/notify/:user_id', getClient); +// router.use('/onewaytrip', getToken, verifyToken); + +router.use((err, req, res, next) => { + if (err.name === 'Validation Error') { + return res.status(422).json({ + errors: Object.keys(err.errors).reduce((errors, key) => { + errors[key] = err.errors[key].message; + return errors; + }, {}) + }); + } + return next(err); +}); + + +export default router; diff --git a/src/services/notifyServices.js b/src/services/notifyServices.js new file mode 100644 index 0000000..d5caa2c --- /dev/null +++ b/src/services/notifyServices.js @@ -0,0 +1,27 @@ +import Model from '../models'; + +const { notifications } = Model; + +// eslint-disable-next-line import/prefer-default-export +export default { + + createNotification: async () => { + try { + const makeNotification = await notifications.create(notifications); + return makeNotification; + } catch (error) { + return false; + } + }, + + getSpecificTrips: async (id) => { + try { + const theTravels = await notifications.findOne({ + where: { line_manager_id: id } + }); + return theTravels; + } catch (error) { + return false; + } + }, +}; diff --git a/src/services/websocket.js b/src/services/websocket.js new file mode 100644 index 0000000..156f436 --- /dev/null +++ b/src/services/websocket.js @@ -0,0 +1,33 @@ +import autoBind from 'auto-bind'; + +let socketPlug = null; +/** + * + * + * @class socketEmission + */ +class socketEmission { + // eslint-disable-next-line valid-jsdoc + /** + *Creates an instance of socketEmission. + @param {} io + * @memberof socketEmission + */ + constructor(io) { + socketPlug = io; + autoBind(this); + } + + /** + *@description A function that handles multicity travel request by a user + * @static + * @param {Object} eventName + * @param {Object} eventMessage + * @returns {object} Details of booked trips + * @memberof Trips + */ + static async emission(eventName, eventMessage) { + return socketPlug.emit(eventName, eventMessage); + } +} +export default socketEmission; diff --git a/src/utils/notifyEmailUtils.js b/src/utils/notifyEmailUtils.js new file mode 100644 index 0000000..6187f0e --- /dev/null +++ b/src/utils/notifyEmailUtils.js @@ -0,0 +1,9 @@ +const emailBody = (userDetails, travelInfo) => { + const { + first_name, + last_name + } = userDetails; + const { destination, departure_date, return_date } => { + + } +} From d8ecdcfc4a742e0b1cde18dacf08892a703f85fc Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Fri, 13 Sep 2019 18:48:00 +0100 Subject: [PATCH 20/23] feature(notify-new-request): new travel requests - The push notification - The email notification Create a notifications table Install dependencies socket.io and auto-bind Prepare the server Set-up the project Display New travel Requests Add Notifications Send Push and Email Notifications [Finishes: #167730641] --- src/utils/messageUtils.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/messageUtils.js b/src/utils/messageUtils.js index ae3f721..501e05c 100644 --- a/src/utils/messageUtils.js +++ b/src/utils/messageUtils.js @@ -23,6 +23,8 @@ export default { emptyDepartureDate: 'You must state your departure date', emptyReturnDate: 'You must state your return date', emptyTravelPurpose: 'You must state your travel purpose', + notifyUser: 'Your travel request has been successfully created and it is awaiting approval', + lineManager: 'Line manager must be present to continue', lettersAlone: 'Only letters are allowed', unauthorized: 'Not authorized.', invalidToken: 'Invalid Token, please login.', @@ -41,8 +43,7 @@ export default { emptyEmail: 'Email cannot be empty.', invalidTravelId: 'The travel ID must be an integer value.', travelNotFound: 'The travel request does not exist.', - unauthorizedAccessToTravel: - 'Access denied. Accessible only by travel requester or his/her line manager.', + unauthorizedAccessToTravel: 'Access denied. Accessible only by travel requester or his/her line manager.', emptyComment: 'comment cannot be empty.', unauthorizedCommentDelete: "comment can only be deleted by it's author", commentNotFound: 'The comment does not exist.', From a64e64caaf530844eef0fcda3d3e6dc0b20621ee Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Fri, 13 Sep 2019 23:20:51 +0100 Subject: [PATCH 21/23] feature(notify-new-request): new travel requests - The push notification - The email notification - Create a notifications table - Install dependencies socket.io and auto-bind - Prepare the server - Set-up the project - Display New travel Requests - Add Notifications - Send Push and Email Notifications [Finishes: #167730641] --- src/controllers/travelControllers.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index 7cd2ae3..87c358e 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,3 +1,4 @@ +import socketEmission from '../services/websocket'; import { onewayTripService, showManagerPendingAppr, @@ -6,14 +7,21 @@ import { } from '../services/travelServices'; import { findUserByEmail } from '../services/authServices'; import { successResponseWithData, errorResponse } from '../utils/response'; +import sendVerificationEmail from '../utils/email'; import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; +const { emission } = socketEmission; + export const createOneWayTrip = async(req, res) => { try { const user = await findUserByEmail(req.userData.email); - const { id, dept_id } = user.dataValues; + const { id, email, dept_id } = user.dataValues; + + if (!dept_id) { + errorResponse(res, statusCode.badRequest, message.lineManager); + } const data = await onewayTripService({ user_id: id, @@ -22,10 +30,15 @@ export const createOneWayTrip = async(req, res) => { dept_id, }); + const emailVerify = await sendVerificationEmail(email, + 'Travel Confirmation', message.notifyUser); + emission('here', 'we made it'); + successResponseWithData( res, statusCode.created, message.oneWayTripCreated, + message.oneWayTripCreated, data ); } catch (err) { From 63b418405cf4e4ffd9ca56a8ff9cec154a656427 Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Fri, 13 Sep 2019 23:39:18 +0100 Subject: [PATCH 22/23] feature(notify-new-request): new travel requests - The push notification - The email notification - Create a notifications table - Install dependencies socket.io and auto-bind - Prepare the server - Set-up the project - Display New travel Requests - Add Notifications - Send Push and Email Notifications [Finishes: #167730641] --- src/routes/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/routes/index.js b/src/routes/index.js index 727e9ea..184b39b 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,10 +1,12 @@ import auth from './authRoutes'; import travel from './travelRoute'; import comment from './commentRoutes'; +import notify from './notifyRoutes'; export default (prefix, app) => { - app.use(prefix, auth); - app.use(prefix, travel); - app.use(prefix, comment); + app.use(prefix, auth); + app.use(prefix, travel); + app.use(prefix, comment); + app.use(prefix, notify); }; From eeda180e93e615526f1c2936e16a8a8c959341ca Mon Sep 17 00:00:00 2001 From: ChidiChuks Date: Sat, 14 Sep 2019 23:30:36 +0100 Subject: [PATCH 23/23] resolved conflicts --- .../accommodationFeedbackControllers.js | 52 + src/controllers/travelControllers.js | 33 +- ...13100511-create-accommodation-feedbacks.js | 45 + .../20190913101432-accommodation_feedbacks.js | 30 + src/middlewares/userMiddlewares.js | 7 +- src/models/accommodation_feedbacks.js | 15 + src/routes/accommodationFeedbackRoutes.js | 37 + src/routes/index.js | 11 +- src/routes/travelRoute.js | 67 +- src/services/accommodationServices.js | 19 + src/services/accomodationFeedbackServices.js | 25 + src/services/travelServices.js | 237 ++-- src/tests/accommodation.Feedbacks.test.js | 125 ++ src/tests/mockData.js | 9 +- src/tests/travel.test.js | 1084 ++++++++--------- src/utils/messageUtils.js | 18 +- src/validation/feedbackValidation.js | 40 + 17 files changed, 1120 insertions(+), 734 deletions(-) create mode 100644 src/controllers/accommodationFeedbackControllers.js create mode 100644 src/database/migrations/20190913100511-create-accommodation-feedbacks.js create mode 100644 src/database/seeders/20190913101432-accommodation_feedbacks.js create mode 100644 src/models/accommodation_feedbacks.js create mode 100644 src/routes/accommodationFeedbackRoutes.js create mode 100644 src/services/accommodationServices.js create mode 100644 src/services/accomodationFeedbackServices.js create mode 100644 src/tests/accommodation.Feedbacks.test.js create mode 100644 src/validation/feedbackValidation.js diff --git a/src/controllers/accommodationFeedbackControllers.js b/src/controllers/accommodationFeedbackControllers.js new file mode 100644 index 0000000..c5f7aab --- /dev/null +++ b/src/controllers/accommodationFeedbackControllers.js @@ -0,0 +1,52 @@ +import { + createFeedback, + getAllFeedbacks, +} from '../services/accomodationFeedbackServices'; +import { + successResponseWithData, + errorResponse, +} from '../utils/response'; + +import message from '../utils/messageUtils'; +import statusCode from '../utils/statusCode'; + +export const createAccommodtionFeedback = async (req, res) => { + try { + const { accommodation_id } = req.params; + const { + accommodation_name, email, full_name, feedback, + } = req.body; + const accommodationData = await createFeedback({ + accommodation_id: parseInt(accommodation_id, 10), + accommodation_name, + author_email: email, + author_name: full_name, + feedback, + }); + const returnedFeedback = accommodationData.dataValues; + + successResponseWithData( + res, + statusCode.created, + message.newFeedback(accommodation_name), + returnedFeedback + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; + +export const getAccommodtionFeedbacks = async (req, res) => { + try { + const feedbacks = await getAllFeedbacks(req.params.accommodation_id); + + successResponseWithData( + res, + statusCode.success, + message.getFeedback(req.body.accommodation_name), + feedbacks + ); + } catch (err) { + errorResponse(res, statusCode.serverError, err); + } +}; diff --git a/src/controllers/travelControllers.js b/src/controllers/travelControllers.js index 5c412ae..917472d 100644 --- a/src/controllers/travelControllers.js +++ b/src/controllers/travelControllers.js @@ -1,7 +1,6 @@ -import socketEmission from '../services/websocket'; /* eslint-disable no-else-return */ +import socketEmission from '../services/websocket'; import { - onewayTripService, createTripService, showManagerPendingAppr, showUsertravelsStatus, @@ -13,38 +12,28 @@ import { import { findUserByEmail } from '../services/authServices'; import { successResponseWithData, errorResponse } from '../utils/response'; -import sendVerificationEmail from '../utils/email'; - import message from '../utils/messageUtils'; import statusCode from '../utils/statusCode'; +import sendVerificationEmail from '../utils/email'; const { emission } = socketEmission; const createOneWayTrip = async(req, res) => { try { const user = await findUserByEmail(req.userData.email); - const { id, email, dept_id } = user.dataValues; - - if (!dept_id) { - errorResponse(res, statusCode.badRequest, message.lineManager); - } + const { id, dept_id } = user.dataValues; - const data = await onewayTripService({ + const data = await createTripService({ user_id: id, travel_type: 'one-way', ...req.body, dept_id, }); - const emailVerify = await sendVerificationEmail(email, - 'Travel Confirmation', message.notifyUser); - emission('here', 'we made it'); - successResponseWithData( res, statusCode.created, message.oneWayTripCreated, - message.oneWayTripCreated, data ); } catch (err) { @@ -52,6 +41,8 @@ const createOneWayTrip = async(req, res) => { } }; + + const createReturnTrip = async(req, res) => { try { const user = await findUserByEmail(req.userData.email); @@ -123,8 +114,6 @@ const getUserTravelStatus = async(req, res) => { }; const approveTravelRequest = async(req, res) => { - const { role, id } = req.userData; - try { const updatedTravel = await approveTravel(req.params.travel_id); @@ -136,16 +125,6 @@ const approveTravelRequest = async(req, res) => { ); } catch (err) { errorResponse(res, statusCode.serverError, err); - if (role === 'admin') { - return errorResponse(res, statusCode.unauthorized, message.unauthorized); - } else { - try { - const data = await showUsertravelsStatus(id); - return successResponseWithData(res, statusCode.success, message.userApproval, data); - } catch (error) { - errorResponse(res, statusCode.serverError, error); - } - } } }; diff --git a/src/database/migrations/20190913100511-create-accommodation-feedbacks.js b/src/database/migrations/20190913100511-create-accommodation-feedbacks.js new file mode 100644 index 0000000..654d9d6 --- /dev/null +++ b/src/database/migrations/20190913100511-create-accommodation-feedbacks.js @@ -0,0 +1,45 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('accommodation_feedbacks', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + accommodation_id: { + type: Sequelize.INTEGER, + allowNull: false, + onDelete: 'CASCADE', + references: { + model: 'accommodations', + key: 'id', + as: 'accommodation_id', + }, + }, + accommodation_name: { + type: Sequelize.TEXT, + }, + feedback: { + type: Sequelize.TEXT, + }, + author_name: { + type: Sequelize.TEXT, + }, + author_email: { + type: Sequelize.TEXT, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + }, + down: (queryInterface) => { + return queryInterface.dropTable('accommodation_feedbacks'); + } +}; diff --git a/src/database/seeders/20190913101432-accommodation_feedbacks.js b/src/database/seeders/20190913101432-accommodation_feedbacks.js new file mode 100644 index 0000000..6a0cd23 --- /dev/null +++ b/src/database/seeders/20190913101432-accommodation_feedbacks.js @@ -0,0 +1,30 @@ +module.exports = { + up: (queryInterface) => queryInterface.bulkInsert( + 'accommodation_feedbacks', + [ + { + id: 556655, + accommodation_id: 1653453, + accommodation_name: 'Sheraton Protea', + author_email: 'nancngo@gmail.com', + author_name: 'Ngozi Nancy', + feedback: 'Its great working from this location.', + updatedAt: new Date(), + createdAt: new Date(), + }, + { + id: 554455, + accommodation_id: 1653453, + accommodation_name: 'Sheraton Protea', + author_email: 'nancngo@gmail.com', + author_name: 'Ngozi Nancy', + feedback: 'Sample feedback on accommodation facility for testing.', + updatedAt: new Date(), + createdAt: new Date(), + }, + ], + {} + ), + + down: (queryInterface) => queryInterface.bulkDelete('accommodation_feedbacks', null, {}), +}; diff --git a/src/middlewares/userMiddlewares.js b/src/middlewares/userMiddlewares.js index 58fd257..2318c2e 100644 --- a/src/middlewares/userMiddlewares.js +++ b/src/middlewares/userMiddlewares.js @@ -32,11 +32,16 @@ export const confirmUserEmail = async (req, res, next) => { export const verifyTravelOwner = async (req, res, next) => { try { - const travelObj = await findTravelById(req.params.travel_id); + const { travel_id } = req.params; + if (travel_id && travel_id.match(/\D/)) { + return errorResponse(res, statusCode.badRequest, message.invalidTravelId); + } + const travelObj = await findTravelById(req.params.travel_id); if (travelObj === null) { return errorResponse(res, statusCode.notFound, message.travelNotFound); } + const travel = travelObj.dataValues; const dept = await getADepartment(travel.dept_id); diff --git a/src/models/accommodation_feedbacks.js b/src/models/accommodation_feedbacks.js new file mode 100644 index 0000000..5450452 --- /dev/null +++ b/src/models/accommodation_feedbacks.js @@ -0,0 +1,15 @@ +module.exports = (sequelize, DataTypes) => { + const accommodation_feedbacks = sequelize.define('accommodation_feedbacks', { + accommodation_id: DataTypes.INTEGER, + accommodation_name: DataTypes.TEXT, + feedback: DataTypes.TEXT, + author_name: DataTypes.TEXT, + author_email: DataTypes.TEXT + }, {}); + accommodation_feedbacks.associate = (models) => { + accommodation_feedbacks.belongsTo(models.accommodations, { + foreignKey: 'accommodation_id', + }); + }; + return accommodation_feedbacks; +}; diff --git a/src/routes/accommodationFeedbackRoutes.js b/src/routes/accommodationFeedbackRoutes.js new file mode 100644 index 0000000..3524eef --- /dev/null +++ b/src/routes/accommodationFeedbackRoutes.js @@ -0,0 +1,37 @@ +import { Router } from 'express'; + +import { + createAccommodtionFeedback, + getAccommodtionFeedbacks +} from '../controllers/accommodationFeedbackControllers'; +import { + validateFeedback, + validateAccommodationId, + validateResult, +} from '../validation/feedbackValidation'; +import { confirmUserEmail } from '../middlewares/userMiddlewares'; +import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; + +const route = Router(); + +// handles the api home route... +route.post( + '/accommodation/:accommodation_id/feedback', + getToken, + verifyToken, + confirmUserEmail, + validateFeedback, + validateResult, + createAccommodtionFeedback +); + +route.get( + '/accommodation/:accommodation_id/feedback', + getToken, + verifyToken, + validateAccommodationId, + validateResult, + getAccommodtionFeedbacks +); + +export default route; diff --git a/src/routes/index.js b/src/routes/index.js index 184b39b..8f9c542 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,12 +1,11 @@ import auth from './authRoutes'; import travel from './travelRoute'; import comment from './commentRoutes'; -import notify from './notifyRoutes'; - +import accommodationFeedback from './accommodationFeedbackRoutes'; export default (prefix, app) => { - app.use(prefix, auth); - app.use(prefix, travel); - app.use(prefix, comment); - app.use(prefix, notify); + app.use(prefix, auth); + app.use(prefix, travel); + app.use(prefix, comment); + app.use(prefix, accommodationFeedback); }; diff --git a/src/routes/travelRoute.js b/src/routes/travelRoute.js index e98f785..b004d1c 100644 --- a/src/routes/travelRoute.js +++ b/src/routes/travelRoute.js @@ -1,24 +1,24 @@ import { Router } from 'express'; import { - createOneWayTrip, - getUserTravelStatus, - approveTravelRequest, - createReturnTrip, - mostTravelledDest, - userCanEditOpenRequest, - pendingManagerApproval + approveTravelRequest, + createOneWayTrip, + createReturnTrip, + getUserTravelStatus, + mostTravelledDest, + userCanEditOpenRequest, + pendingManagerApproval } from '../controllers/travelControllers'; import { - validateTravelRequest, - validateReturnTrip, - validateResult, + validateReturnTrip, + validateTravelRequest, + validateResult, } from '../validation/travelValidation'; import { - departureDateValidator, - futureDateValidator + departureDateValidator, + futureDateValidator } from '../validation/dateValidator'; import { verifyDeptManagerAndRequestStatus } from '../middlewares/travelsMiddleware'; @@ -27,20 +27,19 @@ import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; const route = Router(); - // handles the api home route... route.post('/travel/one_way_trip', getToken, verifyToken, validateTravelRequest, validateResult, createOneWayTrip); // This is the route that will handle the request to create a valid return trip for a user.... route.post( - '/travel/return_trip', - getToken, - verifyToken, - validateReturnTrip, - validateResult, - departureDateValidator, - futureDateValidator, - createReturnTrip + '/travel/return_trip', + getToken, + verifyToken, + validateReturnTrip, + validateResult, + departureDateValidator, + futureDateValidator, + createReturnTrip ); // handles manager pending req approvals route @@ -50,22 +49,24 @@ route.get('/travel/pending_request/:manager', getToken, verifyToken, pendingMana route.get('/user/status', getToken, verifyToken, getUserTravelStatus); route.patch( - '/travel/approve_request/:travel_id', - getToken, - verifyToken, - verifyRole('manager'), - verifyDeptManagerAndRequestStatus, - approveTravelRequest, + '/travel/approve_request/:travel_id', + getToken, + verifyToken, + verifyRole('manager'), + verifyDeptManagerAndRequestStatus, + approveTravelRequest, ); +// Most travelled to destinations +route.get('/most', getToken, verifyToken, mostTravelledDest); // handles editing of user's pending request route.put( - '/travel/update_request/:travel_id', - getToken, - verifyToken, - validateTravelRequest, - validateResult, - userCanEditOpenRequest + '/travel/update_request/:travel_id', + getToken, + verifyToken, + validateTravelRequest, + validateResult, + userCanEditOpenRequest ); export default route; diff --git a/src/services/accommodationServices.js b/src/services/accommodationServices.js new file mode 100644 index 0000000..6b0a9b7 --- /dev/null +++ b/src/services/accommodationServices.js @@ -0,0 +1,19 @@ +/* eslint-disable no-useless-catch */ +import 'core-js/stable'; +import 'regenerator-runtime/runtime'; + +import models from '../models'; + +const { accommodations } = models; + +export const createAccommodation = async (accommodation) => {}; + +export const getAnAccommodation = async (id) => { + try { + return await accommodations.findOne({ + where: { id }, + }); + } catch (err) { + throw err; + } +}; diff --git a/src/services/accomodationFeedbackServices.js b/src/services/accomodationFeedbackServices.js new file mode 100644 index 0000000..133b13b --- /dev/null +++ b/src/services/accomodationFeedbackServices.js @@ -0,0 +1,25 @@ +/* eslint-disable no-useless-catch */ +import 'core-js/stable'; +import 'regenerator-runtime/runtime'; + +import models from '../models'; + +const { accommodation_feedbacks } = models; + +export const createFeedback = async (comment) => { + try { + return await accommodation_feedbacks.create(comment); + } catch (err) { + throw err; + } +}; + +export const getAllFeedbacks = async (accommodation_id) => { + try { + return await accommodation_feedbacks.findAll({ + where: { accommodation_id }, + }); + } catch (err) { + throw err; + } +}; diff --git a/src/services/travelServices.js b/src/services/travelServices.js index 799f9b0..2179c62 100644 --- a/src/services/travelServices.js +++ b/src/services/travelServices.js @@ -7,140 +7,147 @@ import models from '../models'; const { travel_requests, departments, users } = models; /** - *This function will create a new return trip in the database... - *@param {Object} travelRequest - the data of the travel request the user is making.. - *@return {Object} - response of sequelize after creating the request. - */ -const createTripService = async(travelRequest) => { - try { - return await travel_requests.create(travelRequest); - } catch (err) { - throw err; - } +*This function will create a new return trip in the database... +*@param {Object} travelRequest - the data of the travel request the user is making.. +*@return {Object} - response of sequelize after creating the request. +*/ +const createTripService = async (travelRequest) => { + try { + return await travel_requests.create(travelRequest); + } catch (err) { + throw err; + } }; -const findTravelById = async(id) => { - try { - return await travel_requests.findOne({ - where: { id } - }); - } catch (err) { - throw err; - } +const findTravelById = async (id) => { + try { + return await travel_requests.findOne({ + where: { id } + }); + } catch (err) { + throw err; + } }; -const showManagerPendingAppr = async(manager) => { - try { - return await travel_requests.findAll({ - where: { - approval_status: 'pending', +const showManagerPendingAppr = async (manager) => { + try { + return await travel_requests.findAll({ + where: { + approval_status: 'pending', + }, + include: [ + { + model: users, + attributes: ['first_name', 'last_name'], + include: [ + { + model: departments, + attributes: ['dept_name', 'line_manager'], + where: { + line_manager: manager, + }, }, - include: [{ - model: users, - attributes: ['first_name', 'last_name'], - include: [{ - model: departments, - attributes: ['dept_name', 'line_manager'], - where: { - line_manager: manager, - }, - }, ], - }, ], - raw: true, - }); - } catch (err) { - throw err; - } + ], + }, + ], + raw: true, + }); + } catch (err) { + throw err; + } }; -const checkApprovalStatus = async(id, userId) => { - try { - return await travel_requests.findAll({ - attributes: ['approval_status'], - where: { id, user_id: userId }, - raw: true - }); - } catch (err) { - throw err; - } +const checkApprovalStatus = async (id, userId) => { + try { + return await travel_requests.findAll({ + attributes: ['approval_status'], + where: { id, user_id: userId }, + raw: true + }); + } catch (err) { + throw err; + } }; -const editOpenRequests = async({ - travel_type = 'one-way', - origin, - destination, - departure_date = null, - return_date, - travel_purpose, - accommodation_id, - approval_status = 'pending', - multi_city = false +const editOpenRequests = async ({ + travel_type = 'one-way', + origin, + destination, + departure_date = null, + return_date, + travel_purpose, + accommodation_id, + approval_status = 'pending', + multi_city = false }, userId, id) => { - try { - return await travel_requests.update({ - user_id: userId, - travel_type, - origin, - destination, - departure_date, - return_date, - travel_purpose, - accommodation_id, - approval_status, - multi_city - }, { - where: { id }, - returning: true, - raw: true - }); - } catch (error) { - throw error; - } + try { + return await travel_requests.update({ + user_id: userId, + travel_type, + origin, + destination, + departure_date, + return_date, + travel_purpose, + accommodation_id, + approval_status, + multi_city + }, { + where: { id }, + returning: true, + raw: true + }); + } catch (error) { + throw error; + } }; -const showUsertravelsStatus = async(userId) => { - try { - return await travel_requests.findAll({ - where: { - user_id: userId, - }, - }); - } catch (error) { - throw error; - } +const showUsertravelsStatus = async (userId) => { + try { + return await travel_requests.findAll({ + where: { + user_id: userId, + }, + }); + } catch (error) { + throw error; + } }; -const approveTravel = async(id) => { - try { - return await travel_requests.update({ approval_status: 'accepted' }, { returning: true, where: { id } }); - } catch (err) { - throw err; - } +const approveTravel = async (id) => { + try { + return await travel_requests.update( + { approval_status: 'accepted' }, + { returning: true, where: { id } } + ); + } catch (err) { + throw err; + } }; -const mostTraveled = async() => { - try { - return await travel_requests.findAll({ - attributes: ['destination', [sequelize.fn('count', sequelize.col('destination')), 'count']], - group: ['destination'], - raw: true, - order: sequelize.literal('count DESC'), - limit: 3 - }); - } catch (error) { - throw error; - } +const mostTraveled = async () => { + try { + return await travel_requests.findAll({ + attributes: ['destination', [sequelize.fn('count', sequelize.col('destination')), 'count']], + group: ['destination'], + raw: true, + order: sequelize.literal('count DESC'), + limit: 3 + }); + } catch (error) { + throw error; + } }; export { - createTripService, - findTravelById, - showManagerPendingAppr, - editOpenRequests, - checkApprovalStatus, - showUsertravelsStatus, - approveTravel, - mostTraveled, + createTripService, + findTravelById, + showManagerPendingAppr, + editOpenRequests, + checkApprovalStatus, + showUsertravelsStatus, + approveTravel, + mostTraveled, }; diff --git a/src/tests/accommodation.Feedbacks.test.js b/src/tests/accommodation.Feedbacks.test.js new file mode 100644 index 0000000..7801b39 --- /dev/null +++ b/src/tests/accommodation.Feedbacks.test.js @@ -0,0 +1,125 @@ +import chai, { expect } from 'chai'; +import chaiHttp from 'chai-http'; +import dotenv from 'dotenv'; + +import message from '../utils/messageUtils'; +import { + testUser1, + testFeedback, + validAccommodationId, +} from './mockData'; +import app from '../index'; + +const prefix = '/api/v1'; +const signinRoute = `${prefix}/auth/login`; +const feedbackRoute = `${prefix}/accommodation/${validAccommodationId}/feedback`; + +dotenv.config(); +chai.use(chaiHttp); + +describe('Testing Commenting on Accommodation Facilities', () => { + let user1AuthToken; + + before((done) => { + chai + .request(app) + .post(signinRoute) + .send(testUser1) + .end((err, res) => { + const { data } = res.body; + user1AuthToken = data.token; + done(); + }); + }); + + describe('Testing the POST route', () => { + it('should successfully post a comment/feedback', (done) => { + chai + .request(app) + .post(feedbackRoute) + .set('Authorization', user1AuthToken) + .send(testFeedback) + .end((err, res) => { + expect(res).to.have.status(201); + expect(res.body.message).to + .equal(message.newFeedback(res.body.data.accommodation_name)); + done(); + }); + }); + it('should return an error if the authentication token is invalid', (done) => { + chai + .request(app) + .post(feedbackRoute) + .set('Authorization', 'Bearer fjdi8553fdfji988ifjf') + .send(testFeedback) + .end((err, res) => { + expect(res).to.have.status(401); + expect(res.body.error).to.equal(message.invalidToken); + done(); + }); + }); + it('should return an error if the accommodation does not exist', (done) => { + chai + .request(app) + .post(`${prefix}/accommodation/4556/feedback`) + .set('Authorization', user1AuthToken) + .send(testFeedback) + .end((err, res) => { + expect(res).to.have.status(400); + expect(res.body.error).to.equal(message.accommodationNotFound); + done(); + }); + }); + it('should return an error if the accommodation ID is invalid', (done) => { + chai + .request(app) + .post(`${prefix}/accommodation/455rttr3/feedback`) + .set('Authorization', user1AuthToken) + .send(testFeedback) + .end((err, res) => { + expect(res).to.have.status(400); + expect(res.body.error).to.equal(message.invalidAccommodationId); + done(); + }); + }); + it('should return an error if the feedback field is empty', (done) => { + const mutatedFeedback = { ...testFeedback }; + mutatedFeedback.feedback = ''; + chai + .request(app) + .post(feedbackRoute) + .set('Authorization', user1AuthToken) + .send(mutatedFeedback) + .end((err, res) => { + expect(res).to.have.status(400); + expect(res.body.error).to.equal(message.emptyFeedback); + done(); + }); + }); + }); + + describe('Testing the GET route', () => { + it('should return a list of feedback on an accommodation facility', (done) => { + chai + .request(app) + .get(feedbackRoute) + .set('Authorization', user1AuthToken) + .end((err, res) => { + expect(res).to.have.status(200); + expect(res.body.data.length).to.equal(3); + done(); + }); + }); + it('should return an error if the accommodation does not exist', (done) => { + chai + .request(app) + .get(`${prefix}/accommodation/911/feedback`) + .set('Authorization', user1AuthToken) + .end((err, res) => { + expect(res).to.have.status(400); + expect(res.body.error).to.equal(message.accommodationNotFound); + done(); + }); + }); + }); +}); diff --git a/src/tests/mockData.js b/src/tests/mockData.js index 117ee13..74bb664 100644 --- a/src/tests/mockData.js +++ b/src/tests/mockData.js @@ -81,6 +81,11 @@ const approvedRequest = { approval_status: 'accepted' }; +const validAccommodationId = '1653453'; + +const testFeedback = { + feedback: 'sample feedback back on an accommodation facility.', +}; export { newUser, testUser1, @@ -92,5 +97,7 @@ export { validTravelId, validCommentId, returnTripTestData, - approvedRequest + approvedRequest, + validAccommodationId, + testFeedback, }; diff --git a/src/tests/travel.test.js b/src/tests/travel.test.js index 6a4b6d0..fcced1c 100644 --- a/src/tests/travel.test.js +++ b/src/tests/travel.test.js @@ -5,14 +5,14 @@ import dotenv from 'dotenv'; import message from '../utils/messageUtils'; import { - testUser1, - returnTripTestData, - testUser2, - testTravelRequest, - testManager1, - testManager2, - validTravelId, - approvedRequest, + testUser1, + returnTripTestData, + testUser2, + testTravelRequest, + testManager1, + testManager2, + validTravelId, + approvedRequest, } from './mockData'; import app from '../index'; @@ -33,540 +33,540 @@ chai.use(chaiHttp); let token, token2, approvedReqId; describe('TEST FOR TRAVEL REQUEST FUNCTIONS', () => { - describe('Testing one way ticket feature', () => { - before((done) => { - chai - .request(app) - .post(loginRoute) - .send(testUser2) - .end((err, res) => { - const { data } = res.body; - token = data.token; - done(); - }); - }); - - it('should successfully create a one way trip', (done) => { - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(testTravelRequest) - .end((err, res) => { - expect(res).to.have.status(201); - done(); - }); - }); - - it('should return an error if the token is invalid', (done) => { - chai - .request(app) - .post(onewayRoute) - .send(testTravelRequest) - .end((err, res) => { - expect(res.status).to.equal(401); - done(); - }); - }); - - it('should return an error if origin is empty', (done) => { - const mutatedtravelRequest = {...testTravelRequest }; - mutatedtravelRequest.origin = ''; - - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(mutatedtravelRequest) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to.equal(message.emptyOrigin); - done(); - }); - }); - it('should return an error message if origin contains integers', (done) => { - const mutatedtravelRequest = {...testTravelRequest }; - mutatedtravelRequest.origin = '4Lag12'; - - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(mutatedtravelRequest) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to.equal(message.lettersAlone); - done(); - }); - }); - it('should return an error message if the destination is empty', (done) => { - const mutatedtravelRequest = {...testTravelRequest }; - mutatedtravelRequest.destination = ''; - - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(mutatedtravelRequest) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to.equal(message.emptyDestination); - done(); - }); - }); - it('should return an error message if the destination contains integers', (done) => { - const mutatedtravelRequest = {...testTravelRequest }; - mutatedtravelRequest.destination = '4Kigs23'; - - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(mutatedtravelRequest) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to.equal(message.lettersAlone); - done(); - }); - }); - it('should return an error message if the departure date is empty', (done) => { - const mutatedtravelRequest = {...testTravelRequest }; - mutatedtravelRequest.departure_date = ''; - - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(mutatedtravelRequest) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to.equal(message.emptyDepartureDate); - done(); - }); - }); - it('should return an error message if travel_purpose', (done) => { - const mutatedtravelRequest = {...testTravelRequest }; - mutatedtravelRequest.travel_purpose = ''; - - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(mutatedtravelRequest) - .end((err, res) => { - expect(res.status).to.equal(400); - expect(res.body.error[0]).to.equal(message.emptyTravelPurpose); - done(); - }); - }); - }); - - // return trip route tests starts here..................... - describe('Test for return trip travel request route', () => { - it('Should throw an error if the request header does not have authorization token', (done) => { - chai - .request(app) - .post(returnTripRoute) - .send(returnTripTestData) - .end((err, res) => { - expect(res).to.have.status(401); - done(err); - }); - }); - - it('should authenticate a user with a valid email and password', (done) => { - chai - .request(app) - .post(loginRoute) - .send(testUser2) - .end((err, res) => { - const { body, status } = res; - expect(body.data).to.not.eql(null); - expect(status).to.be.eql(200); - token = body.data.token; - done(err); - }); - }); - - it('Should throw an error if the request body travel_type is empty or not return-trip', (done) => { - const mutatedReturnTripTestData = {...returnTripTestData }; - mutatedReturnTripTestData.travel_type = ''; - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(mutatedReturnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error).to - .include(message.emptyTravelType); - done(err); - }); - }); - - it('Should throw an error if the request body origin is empty', (done) => { - const mutatedReturnTripTestData = {...returnTripTestData }; - mutatedReturnTripTestData.origin = ''; - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(mutatedReturnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error).to - .include(message.emptyOrigin); - done(err); - }); - }); - - it('Should throw an error if the request body departure_date is not the ISO standard', (done) => { - const mutatedReturnTripTestData = {...returnTripTestData }; - mutatedReturnTripTestData.departure_date = '2010-1-02'; - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(mutatedReturnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error).to - .include(message.isNotISODate); - done(err); - }); - }); - - it('Should throw an error if the request body departure_date is a past date', (done) => { - const mutatedReturnTripTestData = {...returnTripTestData }; - mutatedReturnTripTestData.departure_date = '2010-01-02'; - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(mutatedReturnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error).to - .equal(message.dateForToday); - done(err); - }); - }); - - it('Should throw an error if the request body return_date is not the ISO standard', (done) => { - const mutatedReturnTripTestData = {...returnTripTestData }; - mutatedReturnTripTestData.return_date = '2010-1-02'; - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(mutatedReturnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error).to - .include(message.isNotISODate); - done(err); - }); - }); - - it('Should throw an error if the request body return_date is equal to or less than departure_date', (done) => { - const mutatedReturnTripTestData = {...returnTripTestData }; - mutatedReturnTripTestData.return_date = returnTripTestData.departure_date; - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(mutatedReturnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error).to - .equal(message.dateForFuture); - done(err); - }); - }); - - it('Should throw an error if the request body accommodation_id is empty', (done) => { - const mutatedReturnTripTestData = {...returnTripTestData }; - mutatedReturnTripTestData.accommodation_id = null; - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(mutatedReturnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(400); - expect(body.error).to - .include(message.emptyAccommodation); - done(err); - }); - }); - - it('Should create a new return trip request', (done) => { - chai - .request(app) - .post(returnTripRoute) - .set('Authorization', token) - .send(returnTripTestData) - .end((err, res) => { - const { body, status } = res; - expect(status).to.equal(201); - expect(body.message).to - .equal(message.returnTripCreated); - done(err); - }); - }); - }); - // return trip tests route ends here................. - - // Avail request for approval - let adminToken; - - describe('Testing Avail request for approval', () => { - const adminUser = { - first_name: 'firstoname', - last_name: 'mylastnoamep', - email: 'mygmailisj@gomail.com', - password: 'protected123pass', - role: 'manager' - }; - - it('should successfully create an admin user', (done) => { - chai - .request(app) - .post(signupRoute) - .send(adminUser) - .end((err, res) => { - expect(res).to.have.status(201); - const { data } = res.body; - adminToken = data.token; - done(); - }); - }); - - it('should successfully return manager pending requests', (done) => { - chai - .request(app) - .get(`${prefix}/travel/pending_request/Mr. Benchfort`) - .set('Authorization', adminToken) - .end((err, res) => { - expect(res).to.have.status(200); - done(); - }); - }); - - it('should return an error if requester does not have admin privileges', (done) => { - chai - .request(app) - .get(`${prefix}/travel/pending_request/Mr. Benchfort`) - .set('Authorization', token) - .end((err, res) => { - expect(res).to.have.status(401); - done(); - }); - }); - }); - - // Get users request status - describe('Testing for users request status', () => { - it('should successfully return user request status', (done) => { - chai - .request(app) - .get(`${prefix}/user/status`) - .set('Authorization', token) - .end((err, res) => { - expect(res).to.have.status(200); - done(); - }); - }); - it('should return error when role is manager', (done) => { - chai - .request(app) - .get(`${prefix}/user/status`) - .set('Authorization', adminToken) - .end((err, res) => { - expect(res).to.have.status(401); - done(); - }); - }); - }); - - // Testing travel approval... - describe('Testing the travel approval route', () => { - let managerToken1, managerToken2; - - before((done) => { - chai - .request(app) - .post(loginRoute) - .send(testManager1) - .end((err, res) => { - const { data } = res.body; - managerToken1 = data.token; - done(); - }); - }); - before((done) => { - chai - .request(app) - .post(loginRoute) - .send(testManager2) - .end((err, res) => { - const { data } = res.body; - managerToken2 = data.token; - done(); - }); - }); - - it('should not allow a manager to approve travel in another department', (done) => { - chai - .request(app) - .patch(approveRequestRoute) - .set('Authorization', managerToken2) - .end((err, res) => { - expect(res).to.have.status(401); - expect(res.body.error).to.equal(message.diffDepartment); - done(); - }); - }); - - it('should successfully approve a travel request', (done) => { - chai - .request(app) - .patch(approveRequestRoute) - .set('Authorization', managerToken1) - .end((err, res) => { - expect(res).to.have.status(200); - done(); - }); - }); - - it('should return error if the travel request is not pending', (done) => { - chai - .request(app) - .patch(approveRequestRoute) - .set('Authorization', managerToken1) - .end((err, res) => { - expect(res).to.have.status(401); - done(); - }); - }); - - it('should not allow a normal user to approve a travel request', (done) => { - chai - .request(app) - .patch(approveRequestRoute) - .set('Authorization', token) - .end((err, res) => { - expect(res).to.have.status(401); - done(); - }); - }); - }); - // Most travelled to destinations - describe('Testing for most travelled destinations', () => { - it('should successfully return most travelled destination', (done) => { - chai - .request(app) - .get(`${prefix}/most`) - .set('Authorization', token) - .end((err, res) => { - expect(res).to.have.status(200); - done(); - }); - }); - }); - - // Users can edit pending requests - describe('Testing users can edit pending requests', () => { - before((done) => { - chai - .request(app) - .post(onewayRoute) - .set('Authorization', token) - .send(approvedRequest) - .end((err, res) => { - const { data } = res.body; - approvedReqId = data.id; - expect(res).to.have.status(201); - done(); - }); - }); - - before((done) => { - chai - .request(app) - .post(loginRoute) - .send(testUser1) - .end((err, res) => { - const { data } = res.body; - token2 = data.token; - done(); - }); - }); - - it('should successfully edit pending requests', (done) => { - chai - .request(app) - .put(rightUpdateRoute) - .set('Authorization', token) - .send(testTravelRequest) - .end((err, res) => { - expect(res).to.have.status(200); - done(); - }); - }); - - it('should return an error if token is not valid', (done) => { - chai - .request(app) - .put(rightUpdateRoute) - .send(testTravelRequest) - .end((err, res) => { - expect(res).to.have.status(401); - done(); - }); - }); - - it('should return an error if modifier is not the requester', (done) => { - chai - .request(app) - .put(rightUpdateRoute) - .set('Authorization', token2) - .send(testTravelRequest) - .end((err, res) => { - expect(res).to.have.status(500); - done(); - }); - }); - - it('should return an error if travel id not specified', (done) => { - chai - .request(app) - .put(wrongUpdateRoute) - .set('Authorization', token) - .send(testTravelRequest) - .end((err, res) => { - expect(res).to.have.status(404); - done(); - }); - }); - - it('should return an error if request has been approved', (done) => { - chai - .request(app) - .put(`${prefix}/travel/update_request/${approvedReqId}`) - .set('Authorization', token) - .send(approvedRequest) - .end((err, res) => { - expect(res).to.have.status(400); - done(); - }); + describe('Testing one way ticket feature', () => { + before((done) => { + chai + .request(app) + .post(loginRoute) + .send(testUser2) + .end((err, res) => { + const { data } = res.body; + token = data.token; + done(); }); }); + + it('should successfully create a one way trip', (done) => { + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(testTravelRequest) + .end((err, res) => { + expect(res).to.have.status(201); + done(); + }); + }); + + it('should return an error if the token is invalid', (done) => { + chai + .request(app) + .post(onewayRoute) + .send(testTravelRequest) + .end((err, res) => { + expect(res.status).to.equal(401); + done(); + }); + }); + + it('should return an error if origin is empty', (done) => { + const mutatedtravelRequest = { ...testTravelRequest }; + mutatedtravelRequest.origin = ''; + + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(mutatedtravelRequest) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to.equal(message.emptyOrigin); + done(); + }); + }); + it('should return an error message if origin contains integers', (done) => { + const mutatedtravelRequest = { ...testTravelRequest }; + mutatedtravelRequest.origin = '4Lag12'; + + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(mutatedtravelRequest) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to.equal(message.lettersAlone); + done(); + }); + }); + it('should return an error message if the destination is empty', (done) => { + const mutatedtravelRequest = { ...testTravelRequest }; + mutatedtravelRequest.destination = ''; + + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(mutatedtravelRequest) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to.equal(message.emptyDestination); + done(); + }); + }); + it('should return an error message if the destination contains integers', (done) => { + const mutatedtravelRequest = { ...testTravelRequest }; + mutatedtravelRequest.destination = '4Kigs23'; + + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(mutatedtravelRequest) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to.equal(message.lettersAlone); + done(); + }); + }); + it('should return an error message if the departure date is empty', (done) => { + const mutatedtravelRequest = { ...testTravelRequest }; + mutatedtravelRequest.departure_date = ''; + + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(mutatedtravelRequest) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to.equal(message.emptyDepartureDate); + done(); + }); + }); + it('should return an error message if travel_purpose', (done) => { + const mutatedtravelRequest = { ...testTravelRequest }; + mutatedtravelRequest.travel_purpose = ''; + + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(mutatedtravelRequest) + .end((err, res) => { + expect(res.status).to.equal(400); + expect(res.body.error[0]).to.equal(message.emptyTravelPurpose); + done(); + }); + }); + }); + + // return trip route tests starts here..................... + describe('Test for return trip travel request route', () => { + it('Should throw an error if the request header does not have authorization token', (done) => { + chai + .request(app) + .post(returnTripRoute) + .send(returnTripTestData) + .end((err, res) => { + expect(res).to.have.status(401); + done(err); + }); + }); + + it('should authenticate a user with a valid email and password', (done) => { + chai + .request(app) + .post(loginRoute) + .send(testUser2) + .end((err, res) => { + const { body, status } = res; + expect(body.data).to.not.eql(null); + expect(status).to.be.eql(200); + token = body.data.token; + done(err); + }); + }); + + it('Should throw an error if the request body travel_type is empty or not return-trip', (done) => { + const mutatedReturnTripTestData = { ...returnTripTestData }; + mutatedReturnTripTestData.travel_type = ''; + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(mutatedReturnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error).to + .include(message.emptyTravelType); + done(err); + }); + }); + + it('Should throw an error if the request body origin is empty', (done) => { + const mutatedReturnTripTestData = { ...returnTripTestData }; + mutatedReturnTripTestData.origin = ''; + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(mutatedReturnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error).to + .include(message.emptyOrigin); + done(err); + }); + }); + + it('Should throw an error if the request body departure_date is not the ISO standard', (done) => { + const mutatedReturnTripTestData = { ...returnTripTestData }; + mutatedReturnTripTestData.departure_date = '2010-1-02'; + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(mutatedReturnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error).to + .include(message.isNotISODate); + done(err); + }); + }); + + it('Should throw an error if the request body departure_date is a past date', (done) => { + const mutatedReturnTripTestData = { ...returnTripTestData }; + mutatedReturnTripTestData.departure_date = '2010-01-02'; + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(mutatedReturnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error).to + .equal(message.dateForToday); + done(err); + }); + }); + + it('Should throw an error if the request body return_date is not the ISO standard', (done) => { + const mutatedReturnTripTestData = { ...returnTripTestData }; + mutatedReturnTripTestData.return_date = '2010-1-02'; + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(mutatedReturnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error).to + .include(message.isNotISODate); + done(err); + }); + }); + + it('Should throw an error if the request body return_date is equal to or less than departure_date', (done) => { + const mutatedReturnTripTestData = { ...returnTripTestData }; + mutatedReturnTripTestData.return_date = returnTripTestData.departure_date; + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(mutatedReturnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error).to + .equal(message.dateForFuture); + done(err); + }); + }); + + it('Should throw an error if the request body accommodation_id is empty', (done) => { + const mutatedReturnTripTestData = { ...returnTripTestData }; + mutatedReturnTripTestData.accommodation_id = null; + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(mutatedReturnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(400); + expect(body.error).to + .include(message.emptyAccommodation); + done(err); + }); + }); + + it('Should create a new return trip request', (done) => { + chai + .request(app) + .post(returnTripRoute) + .set('Authorization', token) + .send(returnTripTestData) + .end((err, res) => { + const { body, status } = res; + expect(status).to.equal(201); + expect(body.message).to + .equal(message.returnTripCreated); + done(err); + }); + }); + }); + // return trip tests route ends here................. + + // Avail request for approval + let adminToken; + + describe('Testing Avail request for approval', () => { + const adminUser = { + first_name: 'firstoname', + last_name: 'mylastnoamep', + email: 'mygmailisj@gomail.com', + password: 'protected123pass', + role: 'manager' + }; + + it('should successfully create an admin user', (done) => { + chai + .request(app) + .post(signupRoute) + .send(adminUser) + .end((err, res) => { + expect(res).to.have.status(201); + const { data } = res.body; + adminToken = data.token; + done(); + }); + }); + + it('should successfully return manager pending requests', (done) => { + chai + .request(app) + .get(`${prefix}/travel/pending_request/Mr. Benchfort`) + .set('Authorization', adminToken) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + + it('should return an error if requester does not have admin privileges', (done) => { + chai + .request(app) + .get(`${prefix}/travel/pending_request/Mr. Benchfort`) + .set('Authorization', token) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); + }); + + // Get users request status + describe('Testing for users request status', () => { + it('should successfully return user request status', (done) => { + chai + .request(app) + .get(`${prefix}/user/status`) + .set('Authorization', token) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + it('should return error when role is manager', (done) => { + chai + .request(app) + .get(`${prefix}/user/status`) + .set('Authorization', adminToken) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); + }); + + // Testing travel approval... + describe('Testing the travel approval route', () => { + let managerToken1, managerToken2; + + before((done) => { + chai + .request(app) + .post(loginRoute) + .send(testManager1) + .end((err, res) => { + const { data } = res.body; + managerToken1 = data.token; + done(); + }); + }); + before((done) => { + chai + .request(app) + .post(loginRoute) + .send(testManager2) + .end((err, res) => { + const { data } = res.body; + managerToken2 = data.token; + done(); + }); + }); + + it('should not allow a manager to approve travel in another department', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken2) + .end((err, res) => { + expect(res).to.have.status(401); + expect(res.body.error).to.equal(message.diffDepartment); + done(); + }); + }); + + it('should successfully approve a travel request', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken1) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + + it('should return error if the travel request is not pending', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', managerToken1) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); + + it('should not allow a normal user to approve a travel request', (done) => { + chai + .request(app) + .patch(approveRequestRoute) + .set('Authorization', token) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); + }); + // Most travelled to destinations + describe('Testing for most travelled destinations', () => { + it('should successfully return most travelled destination', (done) => { + chai + .request(app) + .get(`${prefix}/most`) + .set('Authorization', token) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + }); + + // Users can edit pending requests + describe('Testing users can edit pending requests', () => { + before((done) => { + chai + .request(app) + .post(onewayRoute) + .set('Authorization', token) + .send(approvedRequest) + .end((err, res) => { + const { data } = res.body; + approvedReqId = data.id; + expect(res).to.have.status(201); + done(); + }); + }); + + before((done) => { + chai + .request(app) + .post(loginRoute) + .send(testUser1) + .end((err, res) => { + const { data } = res.body; + token2 = data.token; + done(); + }); + }); + + it('should successfully edit pending requests', (done) => { + chai + .request(app) + .put(rightUpdateRoute) + .set('Authorization', token) + .send(testTravelRequest) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + + it('should return an error if token is not valid', (done) => { + chai + .request(app) + .put(rightUpdateRoute) + .send(testTravelRequest) + .end((err, res) => { + expect(res).to.have.status(401); + done(); + }); + }); + + it('should return an error if modifier is not the requester', (done) => { + chai + .request(app) + .put(rightUpdateRoute) + .set('Authorization', token2) + .send(testTravelRequest) + .end((err, res) => { + expect(res).to.have.status(500); + done(); + }); + }); + + it('should return an error if travel id not specified', (done) => { + chai + .request(app) + .put(wrongUpdateRoute) + .set('Authorization', token) + .send(testTravelRequest) + .end((err, res) => { + expect(res).to.have.status(404); + done(); + }); + }); + + it('should return an error if request has been approved', (done) => { + chai + .request(app) + .put(`${prefix}/travel/update_request/${approvedReqId}`) + .set('Authorization', token) + .send(approvedRequest) + .end((err, res) => { + expect(res).to.have.status(400); + done(); + }); + }); + }); }); diff --git a/src/utils/messageUtils.js b/src/utils/messageUtils.js index f494385..3650c39 100644 --- a/src/utils/messageUtils.js +++ b/src/utils/messageUtils.js @@ -21,7 +21,7 @@ export default { noDigitInPassword: 'Password must contain at least one digit.', commentNotFound: 'The comment does not exist.', dateForFuture: 'Please enter a date greater than the departure date for return date.', - dateForToday: 'Please your departure date must be equal to or greater than today\'s date.', + dateForToday: "Please your departure date must be equal to or greater than today's date.", deleteComment: 'Comment successfully deleted.', diffDepartment: 'You are not in the same department as the Travel Requester.', emptyAccommodation: 'You must select an accommodation.', @@ -34,16 +34,12 @@ export default { emptyOrigin: 'You must state your current city.', emptyReturnDate: 'You must state your return date', emptyTravelPurpose: 'You must state your travel purpose', + emptyTravelType: 'Sorry, travel type can not be empty.', notifyUser: 'Your travel request has been successfully created and it is awaiting approval', lineManager: 'Line manager must be present to continue', - lettersAlone: 'Only letters are allowed', - unauthorized: 'Not authorized.', - invalidToken: 'Invalid Token, please login.', - logoutSuccess: 'Logged out successfully.', - emptyTravelType: 'Sorry, travel type can not be empty.', incorrectPassword: 'Sorry, the password entered is not correct.', isNotInteger: 'You must enter a valid integer type.', - isNotISODate: 'Your date must be of ISO8601 standard \'2019-01-10\'.', + isNotISODate: "Your date must be of ISO8601 standard '2019-01-10'.", invalidToken: 'Invalid Token, please login.', invalidTravelType: 'Sorry you can only make return trip request here.', invalidTravelId: 'The travel ID must be an integer value.', @@ -60,8 +56,6 @@ export default { 'You have successfully retrieved all comments for this travel request.', ], travelNotFound: 'The travel request does not exist.', - unauthorizedAccessToTravel: 'Access denied. Accessible only by travel requester or his/her line manager.', - emptyComment: 'comment cannot be empty.', unauthorized: 'Not authorized.', unauthorizedAccessToTravel: 'Access denied. Accessible only by travel requester or his/her line manager.', unauthorizedCommentDelete: "comment can only be deleted by it's author", @@ -70,4 +64,10 @@ export default { userIdNotFound: (id) => `Sorry, there is no user with id: ${id} in the database.`, unregisteredEmail: (email) => `User with this email (${email}) not found in our database.`, wrongRole: (role) => `Sorry, you are not a/an ${role}.`, + + newFeedback: (accomm) => `You have successfully dropped a feedback on our accomodation facility with name, ${accomm}.`, + getFeedback: (accomm) => `You have successfully retrieved feedback on our accommodation facility with name, ${accomm}.`, + accommodationNotFound: 'The accommodation facility does not exist.', + invalidAccommodationId: 'The Accommodation ID must be an integer value.', + emptyFeedback: 'Feedback field cannot be empty.', }; diff --git a/src/validation/feedbackValidation.js b/src/validation/feedbackValidation.js new file mode 100644 index 0000000..6353b47 --- /dev/null +++ b/src/validation/feedbackValidation.js @@ -0,0 +1,40 @@ +import { check, validationResult } from 'express-validator'; + +import { getAnAccommodation } from '../services/accommodationServices'; +import { errorResponse } from '../utils/response'; + +import statusCode from '../utils/statusCode'; +import message from '../utils/messageUtils'; + +let accommodationName; + +const checkAccommodationId = check('accommodation_id') + .isNumeric({ no_symbols: true }) + .withMessage(message.invalidAccommodationId) + .custom((id) => getAnAccommodation(id).then((accommodation) => { + if (!accommodation) { + throw new Error(message.accommodationNotFound); + } + accommodationName = accommodation.dataValues.accommodation_name; + })); +const checkFeedbackField = check('feedback') + .isLength({ min: 1 }) + .withMessage(message.emptyFeedback); + +export const validateFeedback = [ + checkAccommodationId, + checkFeedbackField +]; + +export const validateAccommodationId = [ + checkAccommodationId, +]; + +export const validateResult = (req, res, next) => { + const errors = validationResult(req); + if (!errors.isEmpty()) { + return errorResponse(res, statusCode.badRequest, errors.array()[0].msg); + } + req.body.accommodation_name = accommodationName; + return next(); +};