From 71d9a729dd55378f9b81e7e78a8c60d8845e864c Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Mon, 7 Oct 2019 12:46:55 +0530 Subject: [PATCH 01/16] Added travis config file --- .travis.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..55a178f --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: javascript \ No newline at end of file From f922d42ec532b25ac87888dadf995e14135582fb Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Mon, 7 Oct 2019 12:56:30 +0530 Subject: [PATCH 02/16] Modify travis config file --- .travis.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 55a178f..f6fa9b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,11 @@ -language: javascript \ No newline at end of file +language: node_js +node_js: + - '12' + - '10' + - '8' +os: + - windows + - linux + - osx + +sudo: false \ No newline at end of file From f0ef1523b941d5d6eebe191655dd5ba73203c2f9 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Thu, 10 Oct 2019 17:46:24 +0530 Subject: [PATCH 03/16] Added code coverage --- .travis.yml | 12 + package-lock.json | 884 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 5 +- 3 files changed, 888 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index f6fa9b8..e7e2ad6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,18 @@ node_js: - '12' - '10' - '8' +branches: + only: + - master +cache: + npm: true +services: + - mongodb +before_script: + - cp .env.example .env +env: + - NODE_ENV=test + - MONGODB_URL=mongodb://127.0.0.1:27017/rest-api-nodejs-mongodb os: - windows - linux diff --git a/package-lock.json b/package-lock.json index f03ce11..7ac79b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,137 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@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/generator": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.3.tgz", + "integrity": "sha512-hLhYbAb3pHwxjlijC4AQ7mqZdcoujiNaW7izCT04CIowHK8psN0IN8QjDv0iyFtycF5FowUOTwDloIheI25aMw==", + "dev": true, + "requires": { + "@babel/types": "^7.6.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.6.1" + }, + "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 + } + } + }, + "@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-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/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/parser": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.3.tgz", + "integrity": "sha512-sUZdXlva1dt2Vw2RqbMkmfoImubO0D0gaCrNngV6Hi0DA4x3o4mlrq0tbfY0dZEUIccH8I6wQ4qgEtwcpOR6Qg==", + "dev": true + }, + "@babel/template": { + "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.6.0", + "@babel/types": "^7.6.0" + } + }, + "@babel/traverse": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.6.3", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, "@types/chai": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.3.tgz", @@ -96,11 +227,26 @@ } } }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, "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", @@ -389,6 +535,36 @@ "unset-value": "^1.0.0" } }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -585,6 +761,19 @@ "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==", + "dev": true, + "optional": true + }, + "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", @@ -625,6 +814,15 @@ "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.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", @@ -670,6 +868,37 @@ "vary": "^1" } }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -730,6 +959,15 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -856,6 +1094,15 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "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" + } + }, "es-abstract": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", @@ -885,6 +1132,12 @@ "is-symbol": "^1.0.2" } }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -902,6 +1155,12 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "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", @@ -1155,6 +1414,35 @@ "unpipe": "~1.0.0" } }, + "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" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -1187,6 +1475,28 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + } + } + }, "form-data": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", @@ -1256,7 +1566,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1277,12 +1588,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -1297,17 +1610,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1424,7 +1740,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1436,6 +1753,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1450,6 +1768,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1457,12 +1776,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": 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" @@ -1481,6 +1802,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1561,7 +1883,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1573,6 +1896,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1658,7 +1982,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -1694,6 +2019,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1713,6 +2039,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1756,12 +2083,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -1886,6 +2215,12 @@ "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", @@ -1917,6 +2252,26 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "handlebars": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.3.tgz", + "integrity": "sha512-B0W4A2U1ww3q7VVthTKfh+epHx+q4mCt6iK+zEAzbMBpWQAwxCeKxEGpj/1oQTpzPXDNSOG7hmG14TsISH50yw==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "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 + } + } + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1975,12 +2330,27 @@ } } }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, "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 }, + "hosted-git-info": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true + }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -2076,6 +2446,12 @@ } } }, + "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", @@ -2305,6 +2681,149 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.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 + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "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 + } + } + }, + "istanbul-reports": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", + "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "dev": true, + "requires": { + "handlebars": "^4.1.2" + } + }, + "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", @@ -2315,6 +2834,18 @@ "esprima": "^4.0.0" } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -2378,6 +2909,18 @@ "package-json": "^4.0.0" } }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -2393,6 +2936,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -2498,6 +3047,23 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "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 + } + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -2843,6 +3409,18 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, "node-environment-flags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", @@ -2930,6 +3508,18 @@ "abbrev": "1" } }, + "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", @@ -2975,6 +3565,63 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, + "nyc": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "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 + } + } + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3084,6 +3731,24 @@ "wrappy": "1" } }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -3133,6 +3798,18 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, "package-json": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", @@ -3145,6 +3822,16 @@ "semver": "^5.1.0" } }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -3185,11 +3872,26 @@ "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==", + "dev": true + }, "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": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", @@ -3202,6 +3904,15 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, + "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", @@ -3272,6 +3983,27 @@ "strip-json-comments": "~2.0.1" } }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -3331,6 +4063,15 @@ "rc": "^1.0.1" } }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -3370,6 +4111,15 @@ "semver": "^5.1.0" } }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", @@ -3677,6 +4427,52 @@ "memory-pager": "^1.0.2" } }, + "spawn-wrap": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", + "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "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-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -3763,6 +4559,12 @@ "ansi-regex": "^3.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", @@ -3848,12 +4650,30 @@ "execa": "^0.7.0" } }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + } + }, "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 }, + "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", @@ -3920,6 +4740,26 @@ "mime-types": "~2.1.24" } }, + "uglify-js": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.1.tgz", + "integrity": "sha512-+dSJLJpXBb6oMHP+Yvw8hUgElz4gLTh82XuX68QiJVTXaE5ibl6buzhNkQdYhBlIhozWOC9ge16wyRmjG4TwVQ==", + "dev": true, + "optional": true, + "requires": { + "commander": "2.20.0", + "source-map": "~0.6.1" + }, + "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, + "optional": true + } + } + }, "undefsafe": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", @@ -4056,6 +4896,22 @@ "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==", + "dev": true + }, + "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", @@ -4098,6 +4954,12 @@ "string-width": "^2.1.1" } }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", diff --git a/package.json b/package.json index 88dca5f..28c9e27 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "start": "node ./bin/www", "dev": "nodemon ./bin/www", - "test": "mocha --timeout 10000" + "test": "nyc mocha --timeout 10000 --exit" }, "dependencies": { "bcrypt": "^3.0.6", @@ -26,6 +26,7 @@ "chai": "^4.2.0", "chai-http": "^4.3.0", "mocha": "^6.2.1", - "nodemon": "^1.19.1" + "nodemon": "^1.19.1", + "nyc": "^14.1.1" } } From d892f6d96a59d77a0246f7b2d10acc1d54173cba Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Fri, 11 Oct 2019 23:21:40 +0530 Subject: [PATCH 04/16] modified travis.yml --- .travis.yml | 9 +-------- package-lock.json | 41 +++++++++++------------------------------ 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7e2ad6..3ad1393 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,12 +12,5 @@ services: - mongodb before_script: - cp .env.example .env -env: - - NODE_ENV=test - - MONGODB_URL=mongodb://127.0.0.1:27017/rest-api-nodejs-mongodb os: - - windows - - linux - - osx - -sudo: false \ No newline at end of file + - linux \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7ac79b9..431b5c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1566,8 +1566,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -1588,14 +1587,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1610,20 +1607,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -1740,8 +1734,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -1753,7 +1746,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1768,7 +1760,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1776,14 +1767,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1802,7 +1791,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -1883,8 +1871,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -1896,7 +1883,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -1982,8 +1968,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -2019,7 +2004,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2039,7 +2023,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2083,14 +2066,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, From f07a65661a23f70ee32cd4209f532c7fd9ae95b4 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Sat, 12 Oct 2019 00:34:11 +0530 Subject: [PATCH 05/16] Added eslint, lint code --- .eslintrc.json | 34 ++ app.js | 62 +-- controllers/AuthController.js | 426 ++++++++++----------- controllers/BookController.js | 329 ++++++++-------- helpers/apiResponse.js | 74 ++-- helpers/constants.js | 16 +- helpers/mailer.js | 36 +- helpers/utility.js | 16 +- middlewares/jwt.js | 4 +- models/BookModel.js | 13 +- models/UserModel.js | 28 +- package-lock.json | 683 +++++++++++++++++++++++++++++++++- package.json | 4 +- routes/api.js | 10 +- routes/index.js | 6 +- test/auth.js | 236 ++++++------ test/book.js | 228 ++++++------ test/testConfig.js | 18 +- 18 files changed, 1463 insertions(+), 760 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..dda4b71 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,34 @@ +{ + "env": { + "commonjs": true, + "es6": true, + "node": true, + "mocha": true + }, + "extends": "eslint:recommended", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018 + }, + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ] + } +} \ No newline at end of file diff --git a/app.js b/app.js index 14e82c1..c6a6055 100644 --- a/app.js +++ b/app.js @@ -1,57 +1,57 @@ -var express = require('express'); -var path = require('path'); -var cookieParser = require('cookie-parser'); -var logger = require('morgan'); -require('dotenv').config() -var indexRouter = require('./routes/index'); -var apiRouter = require('./routes/api'); -var apiResponse = require('./helpers/apiResponse'); -var cors = require('cors'); +var express = require("express"); +var path = require("path"); +var cookieParser = require("cookie-parser"); +var logger = require("morgan"); +require("dotenv").config(); +var indexRouter = require("./routes/index"); +var apiRouter = require("./routes/api"); +var apiResponse = require("./helpers/apiResponse"); +var cors = require("cors"); // DB connection var MONGODB_URL = process.env.MONGODB_URL; -var mongoose = require('mongoose'); +var mongoose = require("mongoose"); mongoose.connect(MONGODB_URL, { useNewUrlParser: true }).then(() => { - //don't show the log when it is test - if(process.env.NODE_ENV !== 'test') { - console.log("Connected to %s", MONGODB_URL); - console.log("App is running ... \n"); - console.log("Press CTRL + C to stop the process. \n"); - } - }) - .catch(err => { - console.error("App starting error:", err.message); - process.exit(1); - }); + //don't show the log when it is test + if(process.env.NODE_ENV !== "test") { + console.log("Connected to %s", MONGODB_URL); + console.log("App is running ... \n"); + console.log("Press CTRL + C to stop the process. \n"); + } +}) + .catch(err => { + console.error("App starting error:", err.message); + process.exit(1); + }); var db = mongoose.connection; var app = express(); //don't show the log when it is test -if(process.env.NODE_ENV !== 'test') { - app.use(logger('dev')); +if(process.env.NODE_ENV !== "test") { + app.use(logger("dev")); } app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); +app.use(express.static(path.join(__dirname, "public"))); //To allow cross-origin requests app.use(cors()); //Route Prefixes -app.use('/', indexRouter); -app.use('/api/', apiRouter); +app.use("/", indexRouter); +app.use("/api/", apiRouter); // throw 404 if URL not found app.all("*", function(req, res) { - return apiResponse.notFoundResponse(res, 'Page not found'); + return apiResponse.notFoundResponse(res, "Page not found"); }); -app.use((err, req, res, next) => { - if(err.name == "UnauthorizedError"){ - return apiResponse.unauthorizedResponse(res, err.message); - } +app.use((err, req, res) => { + if(err.name == "UnauthorizedError"){ + return apiResponse.unauthorizedResponse(res, err.message); + } }); module.exports = app; diff --git a/controllers/AuthController.js b/controllers/AuthController.js index cd561c0..57271b2 100644 --- a/controllers/AuthController.js +++ b/controllers/AuthController.js @@ -20,79 +20,79 @@ const { constants } = require("../helpers/constants"); * @returns {Object} */ exports.register = [ - // Validate fields. - body("firstName").isLength({ min: 1 }).trim().withMessage("First name must be specified.") - .isAlphanumeric().withMessage("First name has non-alphanumeric characters."), - body("lastName").isLength({ min: 1 }).trim().withMessage("Last name must be specified.") - .isAlphanumeric().withMessage("Last name has non-alphanumeric characters."), - body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") - .isEmail().withMessage("Email must be a valid email address.").custom((value) => { - return UserModel.findOne({email : value}).then((user) => { - if (user) { - return Promise.reject("E-mail already in use"); - } - }); - }), - body("password").isLength({ min: 6 }).trim().withMessage("Password must be 6 characters or greater."), - // Sanitize fields. - sanitizeBody("firstName").escape(), - sanitizeBody("lastName").escape(), - sanitizeBody("email").escape(), - sanitizeBody("password").escape(), - // Process request after validation and sanitization. - (req, res, next) => { - try { - // Extract the validation errors from a request. - const errors = validationResult(req); - if (!errors.isEmpty()) { - // Display sanitized values/errors messages. - return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); - }else { - //hash input password - bcrypt.hash(req.body.password,10,function(err, hash) { - // generate OTP for confirmation - let otp = utility.randomNumber(4); - // Create User object with escaped and trimmed data - var user = new UserModel( - { - firstName: req.body.firstName, - lastName: req.body.lastName, - email: req.body.email, - password: hash, - confirmOTP: otp - } - ); - // Html email body - let html = '

Please Confirm your Account.

OTP: '+otp+'

'; - // Send confirmation email - mailer.send( - constants.confirmEmails.from, - req.body.email, - 'Confirm Account', - html - ).then(function(response){ - // Save user. - user.save(function (err) { - if (err) { return apiResponse.ErrorResponse(res, err); } - let userData = { - _id: user._id, - firstName: user.firstName, - lastName: user.lastName, - email: user.email - } - return apiResponse.successResponseWithData(res,"Registration Success.", userData); - }); - }).catch(err => { - console.log(err) - return apiResponse.ErrorResponse(res,err); - }) ; - }); - } - } catch (err) { - //throw error in json response with status 500. - return apiResponse.ErrorResponse(res, err); - } -}]; + // Validate fields. + body("firstName").isLength({ min: 1 }).trim().withMessage("First name must be specified.") + .isAlphanumeric().withMessage("First name has non-alphanumeric characters."), + body("lastName").isLength({ min: 1 }).trim().withMessage("Last name must be specified.") + .isAlphanumeric().withMessage("Last name has non-alphanumeric characters."), + body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") + .isEmail().withMessage("Email must be a valid email address.").custom((value) => { + return UserModel.findOne({email : value}).then((user) => { + if (user) { + return Promise.reject("E-mail already in use"); + } + }); + }), + body("password").isLength({ min: 6 }).trim().withMessage("Password must be 6 characters or greater."), + // Sanitize fields. + sanitizeBody("firstName").escape(), + sanitizeBody("lastName").escape(), + sanitizeBody("email").escape(), + sanitizeBody("password").escape(), + // Process request after validation and sanitization. + (req, res) => { + try { + // Extract the validation errors from a request. + const errors = validationResult(req); + if (!errors.isEmpty()) { + // Display sanitized values/errors messages. + return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); + }else { + //hash input password + bcrypt.hash(req.body.password,10,function(err, hash) { + // generate OTP for confirmation + let otp = utility.randomNumber(4); + // Create User object with escaped and trimmed data + var user = new UserModel( + { + firstName: req.body.firstName, + lastName: req.body.lastName, + email: req.body.email, + password: hash, + confirmOTP: otp + } + ); + // Html email body + let html = "

Please Confirm your Account.

OTP: "+otp+"

"; + // Send confirmation email + mailer.send( + constants.confirmEmails.from, + req.body.email, + "Confirm Account", + html + ).then(function(){ + // Save user. + user.save(function (err) { + if (err) { return apiResponse.ErrorResponse(res, err); } + let userData = { + _id: user._id, + firstName: user.firstName, + lastName: user.lastName, + email: user.email + }; + return apiResponse.successResponseWithData(res,"Registration Success.", userData); + }); + }).catch(err => { + console.log(err); + return apiResponse.ErrorResponse(res,err); + }) ; + }); + } + } catch (err) { + //throw error in json response with status 500. + return apiResponse.ErrorResponse(res, err); + } + }]; /** * User login. @@ -103,60 +103,60 @@ exports.register = [ * @returns {Object} */ exports.login = [ - body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") - .isEmail().withMessage("Email must be a valid email address."), - body("password").isLength({ min: 1 }).trim().withMessage("Password must be specified."), - sanitizeBody("email").escape(), - sanitizeBody("password").escape(), - (req, res, next) => { - try { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); - }else { - UserModel.findOne({email : req.body.email}).then(user => { - if (user) { - //Compare given password with db's hash. - bcrypt.compare(req.body.password,user.password,function (err,same) { - if(same){ - //Check account confirmation. - if(user.isConfirmed){ - // Check User's account active or not. - if(user.status) { - let userData = { - _id: user._id, - firstName: user.firstName, - lastName: user.lastName, - email: user.email, - } - //Prepare JWT token for authentication - const jwtPayload = userData; - const jwtData = { - expiresIn: process.env.JWT_TIMEOUT_DURATION, - }; - const secret = process.env.JWT_SECRET; - //Generated JWT token with Payload and secret. - userData.token = jwt.sign(jwtPayload, secret, jwtData); - return apiResponse.successResponseWithData(res,"Login Success.", userData); - }else { - return apiResponse.unauthorizedResponse(res, "Account is not active. Please contact admin."); - } - }else{ - return apiResponse.unauthorizedResponse(res, "Account is not confirmed. Please confirm your account."); - } - }else{ - return apiResponse.unauthorizedResponse(res, "Email or Password wrong."); - } - }); - }else{ - return apiResponse.unauthorizedResponse(res, "Email or Password wrong."); - } - }); - } - } catch (err) { - return apiResponse.ErrorResponse(res, err); - } -}]; + body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") + .isEmail().withMessage("Email must be a valid email address."), + body("password").isLength({ min: 1 }).trim().withMessage("Password must be specified."), + sanitizeBody("email").escape(), + sanitizeBody("password").escape(), + (req, res) => { + try { + const errors = validationResult(req); + if (!errors.isEmpty()) { + return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); + }else { + UserModel.findOne({email : req.body.email}).then(user => { + if (user) { + //Compare given password with db's hash. + bcrypt.compare(req.body.password,user.password,function (err,same) { + if(same){ + //Check account confirmation. + if(user.isConfirmed){ + // Check User's account active or not. + if(user.status) { + let userData = { + _id: user._id, + firstName: user.firstName, + lastName: user.lastName, + email: user.email, + }; + //Prepare JWT token for authentication + const jwtPayload = userData; + const jwtData = { + expiresIn: process.env.JWT_TIMEOUT_DURATION, + }; + const secret = process.env.JWT_SECRET; + //Generated JWT token with Payload and secret. + userData.token = jwt.sign(jwtPayload, secret, jwtData); + return apiResponse.successResponseWithData(res,"Login Success.", userData); + }else { + return apiResponse.unauthorizedResponse(res, "Account is not active. Please contact admin."); + } + }else{ + return apiResponse.unauthorizedResponse(res, "Account is not confirmed. Please confirm your account."); + } + }else{ + return apiResponse.unauthorizedResponse(res, "Email or Password wrong."); + } + }); + }else{ + return apiResponse.unauthorizedResponse(res, "Email or Password wrong."); + } + }); + } + } catch (err) { + return apiResponse.ErrorResponse(res, err); + } + }]; /** * Verify Confirm otp. @@ -167,47 +167,47 @@ exports.login = [ * @returns {Object} */ exports.verifyConfirm = [ - body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") - .isEmail().withMessage("Email must be a valid email address."), - body("otp").isLength({ min: 1 }).trim().withMessage("OTP must be specified."), - sanitizeBody("email").escape(), - sanitizeBody("otp").escape(), - (req, res, next) => { - try { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); - }else { - var query = {email : req.body.email}; - UserModel.findOne(query).then(user => { - if (user) { - //Check already confirm or not. - if(!user.isConfirmed){ - //Check account confirmation. - if(user.confirmOTP == req.body.otp){ - //Update user as confirmed - UserModel.findOneAndUpdate(query, { - isConfirmed: 1, - confirmOTP: null - }).catch(err => { - return apiResponse.ErrorResponse(res, err); - }); - return apiResponse.successResponse(res,"Account confirmed success."); - }else{ - return apiResponse.unauthorizedResponse(res, "Otp does not match"); - } - }else{ - return apiResponse.unauthorizedResponse(res, "Account already confirmed."); - } - }else{ - return apiResponse.unauthorizedResponse(res, "Specified email not found."); - } - }); - } - } catch (err) { - return apiResponse.ErrorResponse(res, err); - } -}]; + body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") + .isEmail().withMessage("Email must be a valid email address."), + body("otp").isLength({ min: 1 }).trim().withMessage("OTP must be specified."), + sanitizeBody("email").escape(), + sanitizeBody("otp").escape(), + (req, res) => { + try { + const errors = validationResult(req); + if (!errors.isEmpty()) { + return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); + }else { + var query = {email : req.body.email}; + UserModel.findOne(query).then(user => { + if (user) { + //Check already confirm or not. + if(!user.isConfirmed){ + //Check account confirmation. + if(user.confirmOTP == req.body.otp){ + //Update user as confirmed + UserModel.findOneAndUpdate(query, { + isConfirmed: 1, + confirmOTP: null + }).catch(err => { + return apiResponse.ErrorResponse(res, err); + }); + return apiResponse.successResponse(res,"Account confirmed success."); + }else{ + return apiResponse.unauthorizedResponse(res, "Otp does not match"); + } + }else{ + return apiResponse.unauthorizedResponse(res, "Account already confirmed."); + } + }else{ + return apiResponse.unauthorizedResponse(res, "Specified email not found."); + } + }); + } + } catch (err) { + return apiResponse.ErrorResponse(res, err); + } + }]; /** * Resend Confirm otp. @@ -217,48 +217,48 @@ exports.verifyConfirm = [ * @returns {Object} */ exports.resendConfirmOtp = [ - body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") - .isEmail().withMessage("Email must be a valid email address."), - sanitizeBody("email").escape(), - (req, res, next) => { - try { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); - }else { - var query = {email : req.body.email}; - UserModel.findOne(query).then(user => { - if (user) { - //Check already confirm or not. - if(!user.isConfirmed){ - // Generate otp - let otp = utility.randomNumber(4); - // Html email body - let html = '

Please Confirm your Account.

OTP: '+otp+'

'; - // Send confirmation email - mailer.send( - constants.confirmEmails.from, - req.body.email, - 'Confirm Account', - html - ).then(function(response){ - user.isConfirmed = 0; - user.confirmOTP = otp; - // Save user. - user.save(function (err) { - if (err) { return apiResponse.ErrorResponse(res, err); } - return apiResponse.successResponse(res,"Confirm otp sent."); - }); - }); - }else{ - return apiResponse.unauthorizedResponse(res, "Account already confirmed."); - } - }else{ - return apiResponse.unauthorizedResponse(res, "Specified email not found."); - } - }); - } - } catch (err) { - return apiResponse.ErrorResponse(res, err); - } -}]; \ No newline at end of file + body("email").isLength({ min: 1 }).trim().withMessage("Email must be specified.") + .isEmail().withMessage("Email must be a valid email address."), + sanitizeBody("email").escape(), + (req, res) => { + try { + const errors = validationResult(req); + if (!errors.isEmpty()) { + return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); + }else { + var query = {email : req.body.email}; + UserModel.findOne(query).then(user => { + if (user) { + //Check already confirm or not. + if(!user.isConfirmed){ + // Generate otp + let otp = utility.randomNumber(4); + // Html email body + let html = "

Please Confirm your Account.

OTP: "+otp+"

"; + // Send confirmation email + mailer.send( + constants.confirmEmails.from, + req.body.email, + "Confirm Account", + html + ).then(function(){ + user.isConfirmed = 0; + user.confirmOTP = otp; + // Save user. + user.save(function (err) { + if (err) { return apiResponse.ErrorResponse(res, err); } + return apiResponse.successResponse(res,"Confirm otp sent."); + }); + }); + }else{ + return apiResponse.unauthorizedResponse(res, "Account already confirmed."); + } + }else{ + return apiResponse.unauthorizedResponse(res, "Specified email not found."); + } + }); + } + } catch (err) { + return apiResponse.ErrorResponse(res, err); + } + }]; \ No newline at end of file diff --git a/controllers/BookController.js b/controllers/BookController.js index 7d13459..fca3fe2 100644 --- a/controllers/BookController.js +++ b/controllers/BookController.js @@ -1,18 +1,17 @@ const Book = require("../models/BookModel"); -const { body,validationResult } = require('express-validator'); -const { sanitizeBody } = require('express-validator'); -const apiResponse = require('../helpers/apiResponse'); -const auth = require('../middlewares/jwt'); -var moment = require('moment'); -var mongoose = require('mongoose'); -mongoose.set('useFindAndModify', false); +const { body,validationResult } = require("express-validator"); +const { sanitizeBody } = require("express-validator"); +const apiResponse = require("../helpers/apiResponse"); +const auth = require("../middlewares/jwt"); +var mongoose = require("mongoose"); +mongoose.set("useFindAndModify", false); // Book Schema function BookData(data) { - this.title= data.title; - this.description = data.description; - this.isbn = data.isbn; - this.createdAt = data.createdAt; + this.title= data.title; + this.description = data.description; + this.isbn = data.isbn; + this.createdAt = data.createdAt; } /** @@ -21,21 +20,21 @@ function BookData(data) { * @returns {Object} */ exports.bookList = [ - auth, - function (req, res) { - try { - Book.find({user: req.user._id},'title description isbn createdAt').then((books)=>{ - if(books.length > 0){ - return apiResponse.successResponseWithData(res, 'Operation success', books); - }else{ - return apiResponse.successResponseWithData(res, "Operation success", {}); - } - }); - } catch (err) { - //throw error in json response with status 500. - return apiResponse.ErrorResponse(res, err); - } - } + auth, + function (req, res) { + try { + Book.find({user: req.user._id},"title description isbn createdAt").then((books)=>{ + if(books.length > 0){ + return apiResponse.successResponseWithData(res, "Operation success", books); + }else{ + return apiResponse.successResponseWithData(res, "Operation success", {}); + } + }); + } catch (err) { + //throw error in json response with status 500. + return apiResponse.ErrorResponse(res, err); + } + } ]; /** @@ -46,25 +45,25 @@ exports.bookList = [ * @returns {Object} */ exports.bookDetail = [ - auth, - function (req, res) { - if(!mongoose.Types.ObjectId.isValid(req.params.id)){ - return apiResponse.successResponseWithData(res, "Operation success", {}); - } - try { - Book.findOne({_id: req.params.id,user: req.user._id},'title description isbn createdAt').then((book)=>{ - if(book !== null){ - let bookData = new BookData(book); - return apiResponse.successResponseWithData(res, 'Operation success', bookData); - }else{ - return apiResponse.successResponseWithData(res, "Operation success", {}); - } - }); - } catch (err) { - //throw error in json response with status 500. - return apiResponse.ErrorResponse(res, err); - } - } + auth, + function (req, res) { + if(!mongoose.Types.ObjectId.isValid(req.params.id)){ + return apiResponse.successResponseWithData(res, "Operation success", {}); + } + try { + Book.findOne({_id: req.params.id,user: req.user._id},"title description isbn createdAt").then((book)=>{ + if(book !== null){ + let bookData = new BookData(book); + return apiResponse.successResponseWithData(res, "Operation success", bookData); + }else{ + return apiResponse.successResponseWithData(res, "Operation success", {}); + } + }); + } catch (err) { + //throw error in json response with status 500. + return apiResponse.ErrorResponse(res, err); + } + } ]; /** @@ -77,43 +76,43 @@ exports.bookDetail = [ * @returns {Object} */ exports.bookStore = [ - auth, - body('title', 'Title must not be empty.').isLength({ min: 1 }).trim(), - body('description', 'Description must not be empty.').isLength({ min: 1 }).trim(), - body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim().custom((value,{req}) => { - return Book.findOne({isbn : value,user: req.user._id}).then(book => { - if (book) { - return Promise.reject('Book already exist with this ISBN no.'); - } - }); - }), - sanitizeBody('*').escape(), - (req, res, next) => { - try { - const errors = validationResult(req); - var book = new Book( - { title: req.body.title, - user: req.user, - description: req.body.description, - isbn: req.body.isbn - }); + auth, + body("title", "Title must not be empty.").isLength({ min: 1 }).trim(), + body("description", "Description must not be empty.").isLength({ min: 1 }).trim(), + body("isbn", "ISBN must not be empty").isLength({ min: 1 }).trim().custom((value,{req}) => { + return Book.findOne({isbn : value,user: req.user._id}).then(book => { + if (book) { + return Promise.reject("Book already exist with this ISBN no."); + } + }); + }), + sanitizeBody("*").escape(), + (req, res) => { + try { + const errors = validationResult(req); + var book = new Book( + { title: req.body.title, + user: req.user, + description: req.body.description, + isbn: req.body.isbn + }); - if (!errors.isEmpty()) { - return apiResponse.validationErrorWithData(res, 'Validation Error.', errors.array()); - } - else { - //Save book. - book.save(function (err) { - if (err) { return apiResponse.ErrorResponse(res, err); } - let bookData = new BookData(book); - return apiResponse.successResponseWithData(res,'Book add Success.', bookData); - }); - } - } catch (err) { - //throw error in json response with status 500. - return apiResponse.ErrorResponse(res, err); - } - } + if (!errors.isEmpty()) { + return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); + } + else { + //Save book. + book.save(function (err) { + if (err) { return apiResponse.ErrorResponse(res, err); } + let bookData = new BookData(book); + return apiResponse.successResponseWithData(res,"Book add Success.", bookData); + }); + } + } catch (err) { + //throw error in json response with status 500. + return apiResponse.ErrorResponse(res, err); + } + } ]; /** @@ -126,61 +125,61 @@ exports.bookStore = [ * @returns {Object} */ exports.bookUpdate = [ - auth, - body('title', 'Title must not be empty.').isLength({ min: 1 }).trim(), - body('description', 'Description must not be empty.').isLength({ min: 1 }).trim(), - body('isbn', 'ISBN must not be empty').isLength({ min: 1 }).trim().custom((value,{req}) => { - return Book.findOne({isbn : value,user: req.user._id, _id: { "$ne": req.params.id }}).then(book => { - if (book) { - return Promise.reject('Book already exist with this ISBN no.'); - } - }); - }), - sanitizeBody('*').escape(), - (req, res, next) => { - try { - const errors = validationResult(req); - var book = new Book( - { title: req.body.title, - description: req.body.description, - isbn: req.body.isbn, - _id:req.params.id - }); + auth, + body("title", "Title must not be empty.").isLength({ min: 1 }).trim(), + body("description", "Description must not be empty.").isLength({ min: 1 }).trim(), + body("isbn", "ISBN must not be empty").isLength({ min: 1 }).trim().custom((value,{req}) => { + return Book.findOne({isbn : value,user: req.user._id, _id: { "$ne": req.params.id }}).then(book => { + if (book) { + return Promise.reject("Book already exist with this ISBN no."); + } + }); + }), + sanitizeBody("*").escape(), + (req, res) => { + try { + const errors = validationResult(req); + var book = new Book( + { title: req.body.title, + description: req.body.description, + isbn: req.body.isbn, + _id:req.params.id + }); - if (!errors.isEmpty()) { - return apiResponse.validationErrorWithData(res, 'Validation Error.', errors.array()); - } - else { - if(!mongoose.Types.ObjectId.isValid(req.params.id)){ - return apiResponse.validationErrorWithData(res, 'Invalid Error.', "Invalid ID"); - }else{ - Book.findById(req.params.id, function (err, foundBook) { - if(foundBook === null){ - return apiResponse.notFoundResponse(res,"Book not exists with this id"); - }else{ - //Check authorized user - if(foundBook.user.toString() !== req.user._id){ - return apiResponse.unauthorizedResponse(res, 'You are not authorized to do this operation.'); - }else{ - //update book. - Book.findByIdAndUpdate(req.params.id, book, {},function (err) { - if (err) { - return apiResponse.ErrorResponse(res, err); - }else{ - let bookData = new BookData(book); - return apiResponse.successResponseWithData(res,'Book update Success.', bookData); - } - }); - } - } - }); - } - } - } catch (err) { - //throw error in json response with status 500. - return apiResponse.ErrorResponse(res, err); - } - } + if (!errors.isEmpty()) { + return apiResponse.validationErrorWithData(res, "Validation Error.", errors.array()); + } + else { + if(!mongoose.Types.ObjectId.isValid(req.params.id)){ + return apiResponse.validationErrorWithData(res, "Invalid Error.", "Invalid ID"); + }else{ + Book.findById(req.params.id, function (err, foundBook) { + if(foundBook === null){ + return apiResponse.notFoundResponse(res,"Book not exists with this id"); + }else{ + //Check authorized user + if(foundBook.user.toString() !== req.user._id){ + return apiResponse.unauthorizedResponse(res, "You are not authorized to do this operation."); + }else{ + //update book. + Book.findByIdAndUpdate(req.params.id, book, {},function (err) { + if (err) { + return apiResponse.ErrorResponse(res, err); + }else{ + let bookData = new BookData(book); + return apiResponse.successResponseWithData(res,"Book update Success.", bookData); + } + }); + } + } + }); + } + } + } catch (err) { + //throw error in json response with status 500. + return apiResponse.ErrorResponse(res, err); + } + } ]; /** @@ -191,34 +190,34 @@ exports.bookUpdate = [ * @returns {Object} */ exports.bookDelete = [ - auth, - function (req, res) { - if(!mongoose.Types.ObjectId.isValid(req.params.id)){ - return apiResponse.validationErrorWithData(res, 'Invalid Error.', "Invalid ID"); - } - try { - Book.findById(req.params.id, function (err, foundBook) { - if(foundBook === null){ - return apiResponse.notFoundResponse(res,"Book not exists with this id"); - }else{ - //Check authorized user - if(foundBook.user.toString() !== req.user._id){ - return apiResponse.unauthorizedResponse(res, 'You are not authorized to do this operation.'); - }else{ - //delete book. - Book.findByIdAndRemove(req.params.id,function (err) { - if (err) { - return apiResponse.ErrorResponse(res, err); - }else{ - return apiResponse.successResponse(res,'Book delete Success.'); - } - }); - } - } - }); - } catch (err) { - //throw error in json response with status 500. - return apiResponse.ErrorResponse(res, err); - } - } + auth, + function (req, res) { + if(!mongoose.Types.ObjectId.isValid(req.params.id)){ + return apiResponse.validationErrorWithData(res, "Invalid Error.", "Invalid ID"); + } + try { + Book.findById(req.params.id, function (err, foundBook) { + if(foundBook === null){ + return apiResponse.notFoundResponse(res,"Book not exists with this id"); + }else{ + //Check authorized user + if(foundBook.user.toString() !== req.user._id){ + return apiResponse.unauthorizedResponse(res, "You are not authorized to do this operation."); + }else{ + //delete book. + Book.findByIdAndRemove(req.params.id,function (err) { + if (err) { + return apiResponse.ErrorResponse(res, err); + }else{ + return apiResponse.successResponse(res,"Book delete Success."); + } + }); + } + } + }); + } catch (err) { + //throw error in json response with status 500. + return apiResponse.ErrorResponse(res, err); + } + } ]; \ No newline at end of file diff --git a/helpers/apiResponse.js b/helpers/apiResponse.js index f0480f3..e40550a 100644 --- a/helpers/apiResponse.js +++ b/helpers/apiResponse.js @@ -1,49 +1,49 @@ exports.successResponse = function (res, msg) { - var data = { - status: 1, - message: msg - } - return res.status(200).json(data); + var data = { + status: 1, + message: msg + }; + return res.status(200).json(data); }; exports.successResponseWithData = function (res, msg, data) { - var data = { - status: 1, - message: msg, - data: data - } - return res.status(200).json(data); -} + var resData = { + status: 1, + message: msg, + data: data + }; + return res.status(200).json(resData); +}; exports.ErrorResponse = function (res, msg) { - var data = { - status: 0, - message: msg, - } - return res.status(500).json(data); -} + var data = { + status: 0, + message: msg, + }; + return res.status(500).json(data); +}; exports.notFoundResponse = function (res, msg) { - var data = { - status: 0, - message: msg, - } - return res.status(404).json(data); -} + var data = { + status: 0, + message: msg, + }; + return res.status(404).json(data); +}; exports.validationErrorWithData = function (res, msg, data) { - var data = { - status: 0, - message: msg, - data: data - } - return res.status(400).json(data); -} + var resData = { + status: 0, + message: msg, + data: data + }; + return res.status(400).json(resData); +}; exports.unauthorizedResponse = function (res, msg) { - var data = { - status: 0, - message: msg, - } - return res.status(401).json(data); -} \ No newline at end of file + var data = { + status: 0, + message: msg, + }; + return res.status(401).json(data); +}; \ No newline at end of file diff --git a/helpers/constants.js b/helpers/constants.js index f51fc99..15994ad 100644 --- a/helpers/constants.js +++ b/helpers/constants.js @@ -1,9 +1,9 @@ exports.constants = { - admin: { - name: "admin", - email: "admin@admin.com" - }, - confirmEmails: { - from : "no-reply@test-app.com" - } -} \ No newline at end of file + admin: { + name: "admin", + email: "admin@admin.com" + }, + confirmEmails: { + from : "no-reply@test-app.com" + } +}; \ No newline at end of file diff --git a/helpers/mailer.js b/helpers/mailer.js index b624d70..c9ab493 100644 --- a/helpers/mailer.js +++ b/helpers/mailer.js @@ -1,25 +1,25 @@ -const nodemailer = require('nodemailer'); +const nodemailer = require("nodemailer"); // create reusable transporter object using the default SMTP transport let transporter = nodemailer.createTransport({ - host: process.env.EMAIL_SMTP_HOST, - port: process.env.EMAIL_SMTP_PORT, - //secure: process.env.EMAIL_SMTP_SECURE, // lack of ssl commented this. You can uncomment it. - auth: { - user: process.env.EMAIL_SMTP_USERNAME, - pass: process.env.EMAIL_SMTP_PASSWORD - } + host: process.env.EMAIL_SMTP_HOST, + port: process.env.EMAIL_SMTP_PORT, + //secure: process.env.EMAIL_SMTP_SECURE, // lack of ssl commented this. You can uncomment it. + auth: { + user: process.env.EMAIL_SMTP_USERNAME, + pass: process.env.EMAIL_SMTP_PASSWORD + } }); exports.send = function (from, to, subject, html) { - // send mail with defined transport object - // visit https://nodemailer.com/ for more options - return transporter.sendMail({ - from: from, // sender address e.g. no-reply@xyz.com or "Fred Foo 👻" - to: to, // list of receivers e.g. bar@example.com, baz@example.com - subject: subject, // Subject line e.g. 'Hello ✔' - //text: text, // plain text body e.g. Hello world? - html: html // html body e.g. 'Hello world?' - }); -} \ No newline at end of file + // send mail with defined transport object + // visit https://nodemailer.com/ for more options + return transporter.sendMail({ + from: from, // sender address e.g. no-reply@xyz.com or "Fred Foo 👻" + to: to, // list of receivers e.g. bar@example.com, baz@example.com + subject: subject, // Subject line e.g. 'Hello ✔' + //text: text, // plain text body e.g. Hello world? + html: html // html body e.g. 'Hello world?' + }); +}; \ No newline at end of file diff --git a/helpers/utility.js b/helpers/utility.js index d785d8b..730396c 100644 --- a/helpers/utility.js +++ b/helpers/utility.js @@ -1,9 +1,9 @@ exports.randomNumber = function (length) { - var text = ""; - var possible = "123456789"; - for (var i = 0; i < length; i++) { - var sup = Math.floor(Math.random() * possible.length); - text += i > 0 && sup == i ? "0" : possible.charAt(sup); - } - return Number(text); -} \ No newline at end of file + var text = ""; + var possible = "123456789"; + for (var i = 0; i < length; i++) { + var sup = Math.floor(Math.random() * possible.length); + text += i > 0 && sup == i ? "0" : possible.charAt(sup); + } + return Number(text); +}; \ No newline at end of file diff --git a/middlewares/jwt.js b/middlewares/jwt.js index a3eeeba..7d274f6 100644 --- a/middlewares/jwt.js +++ b/middlewares/jwt.js @@ -1,8 +1,8 @@ -const jwt = require('express-jwt'); +const jwt = require("express-jwt"); const secret = process.env.JWT_SECRET; const authenticate = jwt({ - secret: secret + secret: secret }); module.exports = authenticate; \ No newline at end of file diff --git a/models/BookModel.js b/models/BookModel.js index e539508..8e4dd1c 100644 --- a/models/BookModel.js +++ b/models/BookModel.js @@ -1,13 +1,12 @@ -var mongoose = require('mongoose'); -var moment = require('moment'); +var mongoose = require("mongoose"); var Schema = mongoose.Schema; var BookSchema = new Schema({ - title: {type: String, required: true}, - description: {type: String, required: true}, - isbn: {type: String, required: true}, - user: { type: Schema.ObjectId, ref: 'User', required: true }, + title: {type: String, required: true}, + description: {type: String, required: true}, + isbn: {type: String, required: true}, + user: { type: Schema.ObjectId, ref: "User", required: true }, }, {timestamps: true}); -module.exports = mongoose.model('Book', BookSchema); \ No newline at end of file +module.exports = mongoose.model("Book", BookSchema); \ No newline at end of file diff --git a/models/UserModel.js b/models/UserModel.js index c9ee6a6..edf2dbc 100644 --- a/models/UserModel.js +++ b/models/UserModel.js @@ -1,21 +1,21 @@ -var mongoose = require('mongoose'); +var mongoose = require("mongoose"); var UserSchema = new mongoose.Schema({ - firstName: {type: String, required: true}, - lastName: {type: String, required: true}, - email: {type: String, required: true}, - password: {type: String, required: true}, - isConfirmed: {type: Boolean, required: true, default: 0}, - confirmOTP: {type: String, required:false}, - otpTries: {type: Number, required:false, default: 0}, - status: {type: Boolean, required: true, default: 1} + firstName: {type: String, required: true}, + lastName: {type: String, required: true}, + email: {type: String, required: true}, + password: {type: String, required: true}, + isConfirmed: {type: Boolean, required: true, default: 0}, + confirmOTP: {type: String, required:false}, + otpTries: {type: Number, required:false, default: 0}, + status: {type: Boolean, required: true, default: 1} }, {timestamps: true}); // Virtual for user's full name UserSchema -.virtual('fullName') -.get(function () { - return this.firstName + ' ' + this.lastName; -}); + .virtual("fullName") + .get(function () { + return this.firstName + " " + this.lastName; + }); -module.exports = mongoose.model('User', UserSchema); \ No newline at end of file +module.exports = mongoose.model("User", UserSchema); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 431b5c1..c0b6e6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -177,6 +177,30 @@ "negotiator": "0.6.2" } }, + "acorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "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 + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "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", @@ -192,6 +216,12 @@ "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": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -306,6 +336,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "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": "2.6.2", "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", @@ -565,6 +601,12 @@ } } }, + "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": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -617,6 +659,12 @@ "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", @@ -683,6 +731,21 @@ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", "dev": true }, + "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", @@ -959,6 +1022,12 @@ "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 + }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", @@ -1050,6 +1119,15 @@ "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", @@ -1149,12 +1227,191 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", + "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 + }, + "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" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "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-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==", "dev": true }, + "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", @@ -1312,6 +1569,28 @@ } } }, + "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" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1377,6 +1656,42 @@ } } }, + "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=", + "dev": true + }, + "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=", + "dev": true + }, + "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", @@ -1469,6 +1784,23 @@ } } }, + "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" + } + }, + "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", @@ -1587,12 +1919,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -1607,17 +1941,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1734,7 +2071,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1746,6 +2084,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1760,6 +2099,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1767,12 +2107,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": 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" @@ -1791,6 +2133,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1871,7 +2214,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1883,6 +2227,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2004,6 +2349,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2081,6 +2427,12 @@ "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", @@ -2351,6 +2703,12 @@ "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", @@ -2365,6 +2723,24 @@ "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" + }, + "dependencies": { + "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 + } + } + }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", @@ -2396,6 +2772,44 @@ "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": "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" + } + } + } + }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -2603,6 +3017,12 @@ "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=", + "dev": true + }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -2827,6 +3247,18 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "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==", + "dev": true + }, + "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 + }, "jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -2890,6 +3322,16 @@ "package-json": "^4.0.0" } }, + "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": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -3089,6 +3531,12 @@ "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", @@ -3334,6 +3782,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "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", @@ -3360,6 +3814,12 @@ "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", @@ -3402,6 +3862,12 @@ "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, + "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.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", @@ -3712,6 +4178,15 @@ "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" + } + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -3730,6 +4205,28 @@ } } }, + "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" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -3803,6 +4300,15 @@ "semver": "^5.1.0" } }, + "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": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -3900,6 +4406,12 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, + "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", @@ -3911,6 +4423,12 @@ "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 + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -3932,6 +4450,12 @@ "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", "dev": true }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", @@ -4025,6 +4549,12 @@ "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" }, + "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 + }, "registry-auth-token": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", @@ -4112,6 +4642,16 @@ "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", @@ -4126,6 +4666,24 @@ "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", @@ -4262,6 +4820,17 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "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" + } + }, "sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", @@ -4601,6 +5170,46 @@ "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 + }, + "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", @@ -4643,12 +5252,33 @@ "require-main-filename": "^2.0.0" } }, + "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=", + "dev": true + }, "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 }, + "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", @@ -4706,6 +5336,21 @@ "nopt": "~1.0.10" } }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "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", @@ -4846,6 +5491,15 @@ "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==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -4883,6 +5537,12 @@ "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, + "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 + }, "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", @@ -4985,6 +5645,15 @@ "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", diff --git a/package.json b/package.json index 28c9e27..387b4e8 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "start": "node ./bin/www", "dev": "nodemon ./bin/www", - "test": "nyc mocha --timeout 10000 --exit" + "test": "nyc mocha --timeout 10000 --exit", + "lint": "eslint --fix --config .eslintrc.json \"**/*.js\"" }, "dependencies": { "bcrypt": "^3.0.6", @@ -25,6 +26,7 @@ "devDependencies": { "chai": "^4.2.0", "chai-http": "^4.3.0", + "eslint": "^6.5.1", "mocha": "^6.2.1", "nodemon": "^1.19.1", "nyc": "^14.1.1" diff --git a/routes/api.js b/routes/api.js index c08d2d4..052441e 100644 --- a/routes/api.js +++ b/routes/api.js @@ -1,10 +1,10 @@ -var express = require('express'); -var authRouter = require('./auth'); -var bookRouter = require('./book'); +var express = require("express"); +var authRouter = require("./auth"); +var bookRouter = require("./book"); var app = express(); -app.use('/auth/', authRouter); -app.use('/book/', bookRouter); +app.use("/auth/", authRouter); +app.use("/book/", bookRouter); module.exports = app; \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index ecca96a..66fd6e7 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,9 +1,9 @@ -var express = require('express'); +var express = require("express"); var router = express.Router(); /* GET home page. */ -router.get('/', function(req, res, next) { - res.render('index', { title: 'Express' }); +router.get("/", function(req, res) { + res.render("index", { title: "Express" }); }); module.exports = router; diff --git a/test/auth.js b/test/auth.js index 5eca863..7bb4dc7 100644 --- a/test/auth.js +++ b/test/auth.js @@ -1,4 +1,4 @@ -const { chai, server, should } = require('./testConfig'); +const { chai, server, should } = require("./testConfig"); const UserModel = require("../models/UserModel"); /** @@ -10,147 +10,147 @@ const UserModel = require("../models/UserModel"); * (4) Verify Confirm OTP */ -describe('Auth', () => { +describe("Auth", () => { - // Before each test we empty the database - before((done) => { - UserModel.deleteMany({}, (err) => { - done(); - }); - }); + // Before each test we empty the database + before((done) => { + UserModel.deleteMany({}, (err) => { + done(); + }); + }); - // Prepare data for testing - const testData = { - "firstName":"test", - "lastName":"testing", - "password":"Test@123", - "email":"maitraysuthar@test12345.com" - } + // Prepare data for testing + const testData = { + "firstName":"test", + "lastName":"testing", + "password":"Test@123", + "email":"maitraysuthar@test12345.com" + }; - /* + /* * Test the /POST route */ - describe('/POST Register', () => { - it('It should send validation error for Register', (done) => { - chai.request(server) - .post('/api/auth/register') - .send({"email": testData.email}) - .end((err, res) => { - res.should.have.status(400); - done(); - }); - }); - }); + describe("/POST Register", () => { + it("It should send validation error for Register", (done) => { + chai.request(server) + .post("/api/auth/register") + .send({"email": testData.email}) + .end((err, res) => { + res.should.have.status(400); + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Register', () => { - it('It should Register user', (done) => { - chai.request(server) - .post('/api/auth/register') - .send(testData) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Registration Success."); - testData._id = res.body.data._id; - done(); - }); - }); - }); + describe("/POST Register", () => { + it("It should Register user", (done) => { + chai.request(server) + .post("/api/auth/register") + .send(testData) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Registration Success."); + testData._id = res.body.data._id; + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Login', () => { - it('it should Send account not confirm notice.', (done) => { - chai.request(server) - .post('/api/auth/login') - .send({"email": testData.email,"password": testData.password}) - .end((err, res) => { - res.should.have.status(401); - res.body.should.have.property('message').eql("Account is not confirmed. Please confirm your account."); - done(); - }); - }); - }); + describe("/POST Login", () => { + it("it should Send account not confirm notice.", (done) => { + chai.request(server) + .post("/api/auth/login") + .send({"email": testData.email,"password": testData.password}) + .end((err, res) => { + res.should.have.status(401); + res.body.should.have.property("message").eql("Account is not confirmed. Please confirm your account."); + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Resend Confirm OTP', () => { - it('It should resend confirm OTP', (done) => { - chai.request(server) - .post('/api/auth/resend-verify-otp') - .send({"email": testData.email}) - .end((err, res) => { - res.should.have.status(200); - UserModel.findOne({_id: testData._id},'confirmOTP').then((user)=>{ - testData.confirmOTP = user.confirmOTP; - done(); - }); - }); - }); - }); + describe("/POST Resend Confirm OTP", () => { + it("It should resend confirm OTP", (done) => { + chai.request(server) + .post("/api/auth/resend-verify-otp") + .send({"email": testData.email}) + .end((err, res) => { + res.should.have.status(200); + UserModel.findOne({_id: testData._id},"confirmOTP").then((user)=>{ + testData.confirmOTP = user.confirmOTP; + done(); + }); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Verify Confirm OTP', () => { - it('It should verify confirm OTP', (done) => { - chai.request(server) - .post('/api/auth/verify-otp') - .send({"email": testData.email, "otp": testData.confirmOTP}) - .end((err, res) => { - res.should.have.status(200); - done(); - }); - }); - }); + describe("/POST Verify Confirm OTP", () => { + it("It should verify confirm OTP", (done) => { + chai.request(server) + .post("/api/auth/verify-otp") + .send({"email": testData.email, "otp": testData.confirmOTP}) + .end((err, res) => { + res.should.have.status(200); + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Login', () => { - it('It should send validation error for Login', (done) => { - chai.request(server) - .post('/api/auth/login') - .send({"email": testData.email}) - .end((err, res) => { - res.should.have.status(400); - done(); - }); - }); - }); + describe("/POST Login", () => { + it("It should send validation error for Login", (done) => { + chai.request(server) + .post("/api/auth/login") + .send({"email": testData.email}) + .end((err, res) => { + res.should.have.status(400); + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Login', () => { - it('it should Send failed user Login', (done) => { - chai.request(server) - .post('/api/auth/login') - .send({"email": "admin@admin.com","password": "1234"}) - .end((err, res) => { - res.should.have.status(401); - done(); - }); - }); - }); + describe("/POST Login", () => { + it("it should Send failed user Login", (done) => { + chai.request(server) + .post("/api/auth/login") + .send({"email": "admin@admin.com","password": "1234"}) + .end((err, res) => { + res.should.have.status(401); + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Login', () => { - it('it should do user Login', (done) => { - chai.request(server) - .post('/api/auth/login') - .send({"email": testData.email,"password": testData.password}) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Login Success."); - done(); - }); - }); - }); + describe("/POST Login", () => { + it("it should do user Login", (done) => { + chai.request(server) + .post("/api/auth/login") + .send({"email": testData.email,"password": testData.password}) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Login Success."); + done(); + }); + }); + }); }); \ No newline at end of file diff --git a/test/book.js b/test/book.js index b3dabcc..8c809ce 100644 --- a/test/book.js +++ b/test/book.js @@ -1,4 +1,4 @@ -const { chai, server, should } = require('./testConfig'); +const { chai, server, should } = require("./testConfig"); const BookModel = require("../models/BookModel"); /** @@ -12,140 +12,140 @@ const BookModel = require("../models/BookModel"); * (6) Delete book */ -describe('Book', () => { - //Before each test we empty the database - before((done) => { - BookModel.deleteMany({}, (err) => { - done(); - }); - }); +describe("Book", () => { + //Before each test we empty the database + before((done) => { + BookModel.deleteMany({}, (err) => { + done(); + }); + }); - // Prepare data for testing - const userTestData = { - "password":"Test@123", - "email":"maitraysuthar@test12345.com" - } + // Prepare data for testing + const userTestData = { + "password":"Test@123", + "email":"maitraysuthar@test12345.com" + }; - // Prepare data for testing - const testData = { - "title":"testing book", - "description":"testing book desc", - "isbn":"3214htrff4" - }; + // Prepare data for testing + const testData = { + "title":"testing book", + "description":"testing book desc", + "isbn":"3214htrff4" + }; - /* + /* * Test the /POST route */ - describe('/POST Login', () => { - it('it should do user Login for book', (done) => { - chai.request(server) - .post('/api/auth/login') - .send({"email": userTestData.email,"password": userTestData.password}) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Login Success."); - userTestData.token = res.body.data.token; - done(); - }); - }); - }); + describe("/POST Login", () => { + it("it should do user Login for book", (done) => { + chai.request(server) + .post("/api/auth/login") + .send({"email": userTestData.email,"password": userTestData.password}) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Login Success."); + userTestData.token = res.body.data.token; + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Book Store', () => { - it('It should send validation error for store book', (done) => { - chai.request(server) - .post('/api/book') - .send() - .set('Authorization', 'Bearer '+ userTestData.token) - .end((err, res) => { - res.should.have.status(400); - done(); - }); - }); - }); + describe("/POST Book Store", () => { + it("It should send validation error for store book", (done) => { + chai.request(server) + .post("/api/book") + .send() + .set("Authorization", "Bearer "+ userTestData.token) + .end((err, res) => { + res.should.have.status(400); + done(); + }); + }); + }); - /* + /* * Test the /POST route */ - describe('/POST Book Store', () => { - it('It should store book', (done) => { - chai.request(server) - .post('/api/book') - .send(testData) - .set('Authorization', 'Bearer '+ userTestData.token) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Book add Success."); - done(); - }); - }); - }); + describe("/POST Book Store", () => { + it("It should store book", (done) => { + chai.request(server) + .post("/api/book") + .send(testData) + .set("Authorization", "Bearer "+ userTestData.token) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Book add Success."); + done(); + }); + }); + }); - /* + /* * Test the /GET route */ - describe('/GET All book', () => { - it('it should GET all the books', (done) => { - chai.request(server) - .get('/api/book') - .set('Authorization', 'Bearer '+ userTestData.token) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Operation success"); - testData._id = res.body.data[0]._id; - done(); - }); - }); - }); + describe("/GET All book", () => { + it("it should GET all the books", (done) => { + chai.request(server) + .get("/api/book") + .set("Authorization", "Bearer "+ userTestData.token) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Operation success"); + testData._id = res.body.data[0]._id; + done(); + }); + }); + }); - /* + /* * Test the /GET/:id route */ - describe('/GET/:id book', () => { - it('it should GET the books', (done) => { - chai.request(server) - .get('/api/book/'+testData._id) - .set('Authorization', 'Bearer '+ userTestData.token) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Operation success"); - done(); - }); - }); - }); + describe("/GET/:id book", () => { + it("it should GET the books", (done) => { + chai.request(server) + .get("/api/book/"+testData._id) + .set("Authorization", "Bearer "+ userTestData.token) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Operation success"); + done(); + }); + }); + }); - /* + /* * Test the /PUT/:id route */ - describe('/PUT/:id book', () => { - it('it should PUT the books', (done) => { - chai.request(server) - .put('/api/book/'+testData._id) - .send(testData) - .set('Authorization', 'Bearer '+ userTestData.token) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Book update Success."); - done(); - }); - }); - }); + describe("/PUT/:id book", () => { + it("it should PUT the books", (done) => { + chai.request(server) + .put("/api/book/"+testData._id) + .send(testData) + .set("Authorization", "Bearer "+ userTestData.token) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Book update Success."); + done(); + }); + }); + }); - /* + /* * Test the /DELETE/:id route */ - describe('/DELETE/:id book', () => { - it('it should DELETE the books', (done) => { - chai.request(server) - .delete('/api/book/'+testData._id) - .set('Authorization', 'Bearer '+ userTestData.token) - .end((err, res) => { - res.should.have.status(200); - res.body.should.have.property('message').eql("Book delete Success."); - done(); - }); - }); - }); + describe("/DELETE/:id book", () => { + it("it should DELETE the books", (done) => { + chai.request(server) + .delete("/api/book/"+testData._id) + .set("Authorization", "Bearer "+ userTestData.token) + .end((err, res) => { + res.should.have.status(200); + res.body.should.have.property("message").eql("Book delete Success."); + done(); + }); + }); + }); }); \ No newline at end of file diff --git a/test/testConfig.js b/test/testConfig.js index ca0281c..85a1081 100644 --- a/test/testConfig.js +++ b/test/testConfig.js @@ -1,17 +1,17 @@ //During the automated test the env variable, We will set it to "test" -process.env.NODE_ENV = 'test'; -process.env.MONGODB_URL = 'mongodb://127.0.0.1:27017/rest-api-nodejs-mongodb-test'; +process.env.NODE_ENV = "test"; +process.env.MONGODB_URL = "mongodb://127.0.0.1:27017/rest-api-nodejs-mongodb-test"; //Require the dev-dependencies -let chai = require('chai'); -let chaiHttp = require('chai-http'); -let server = require('../app'); +let chai = require("chai"); +let chaiHttp = require("chai-http"); +let server = require("../app"); let should = chai.should(); chai.use(chaiHttp); //Export this to use in multiple files module.exports = { - chai: chai, - server: server, - should: should -} \ No newline at end of file + chai: chai, + server: server, + should: should +}; \ No newline at end of file From f165fdfcd110ce0991ba56d9a6e8be9bf782e4c9 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Sun, 13 Oct 2019 00:38:36 +0530 Subject: [PATCH 06/16] Added codacy. Modify README.md --- README.md | 30 ++- package-lock.json | 526 +++++++++++++++++++++++++++++++++++++++------- package.json | 4 +- 3 files changed, 482 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 0e41083..e68935a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Nodejs Expressjs MongoDB Ready-to-use API Project Structure -[![Author](http://img.shields.io/badge/author-@maitraysuthar-blue.svg)](https://www.linkedin.com/in/maitray-suthar/) [![GitHub license](https://img.shields.io/github/license/maitraysuthar/rest-api-nodejs-mongodb.svg)](https://github.com/maitraysuthar/rest-api-nodejs-mongodb/blob/master/LICENSE) ![GitHub repo size](https://img.shields.io/github/repo-size/maitraysuthar/rest-api-nodejs-mongodb) ![Travis (.com)](https://img.shields.io/travis/com/maitraysuthar/rest-api-nodejs-mongodb) +[![Author](http://img.shields.io/badge/author-@maitraysuthar-blue.svg)](https://www.linkedin.com/in/maitray-suthar/) [![GitHub license](https://img.shields.io/github/license/maitraysuthar/rest-api-nodejs-mongodb.svg)](https://github.com/maitraysuthar/rest-api-nodejs-mongodb/blob/master/LICENSE) ![GitHub repo size](https://img.shields.io/github/repo-size/maitraysuthar/rest-api-nodejs-mongodb) [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/b3eb80984adc4671988ffb22d6ad83df)](https://www.codacy.com/manual/maitraysuthar/rest-api-nodejs-mongodb?utm_source=github.com&utm_medium=referral&utm_content=maitraysuthar/rest-api-nodejs-mongodb&utm_campaign=Badge_Coverage) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b3eb80984adc4671988ffb22d6ad83df)](https://www.codacy.com/manual/maitraysuthar/rest-api-nodejs-mongodb?utm_source=github.com&utm_medium=referral&utm_content=maitraysuthar/rest-api-nodejs-mongodb&utm_campaign=Badge_Grade) ![Travis (.com)](https://img.shields.io/travis/com/maitraysuthar/rest-api-nodejs-mongodb) A ready-to-use boilerplate for REST API Development with Node.js, Express, and MongoDB @@ -11,6 +11,16 @@ This is a basic API skeleton written in JavaScript ES2015. Very useful to buildi This project will run on **NodeJs** using **MongoDB** as database. I had tried to maintain the code structure easy as any beginner can also adopt the flow and start building an API. Project is open for suggestions, Bug reports and pull requests. +## Advertise for Job/Work Contract + +I am looking for a good job or work contract. You can contact me directly on my email ([maitraysuthar@gmail.com](mailto:maitraysuthar@gmail.com "maitraysuthar@gmail.com")) or you can download my CV from my personal [website](https://maitraysuthar.github.io/portfolio/). Looking forward. Thanks :smile: + +## Buy me a Coffee + +If you consider my project as a helpful stuff, You can appriciate me or my hard work and time spent to create this helpful structure with buying a coffee for me. I would be very thankful if you buy me a coffee, Please buy me a coffee :smile:. + +Buy Me A Coffee + ## Features - Basic Authentication (Register/Login with hashed password) @@ -20,15 +30,19 @@ This project will run on **NodeJs** using **MongoDB** as database. I had tried t - Pre-defined response structures with proper status codes. - Included CORS. - **Book** example with **CRUD** operations. -- Validations added. +- Validations added. - Included API collection for Postman. - Light-weight project. - Test cases with [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/). +- Code coverage with [Istanbuljs (nyc)](https://istanbul.js.org/). +- Included CI (Continuas Integration) with [Travis CI](https://travis-ci.org). +- Linting with [Eslint](https://eslint.org/). ## Software Requirements -- Node.js **10+** +- Node.js **8+** - MongoDB **3.6+** (Recommended **4+**) + ## How to install ### Using Git (recommended) @@ -103,6 +117,16 @@ You can set custom command for test at `package.json` file inside `scripts` prop If you need to add more test cases to the project just create a new file in `/test/` and run the command. +## ESLint + +### Running Eslint + +```bash +npm run lint +``` + +You can set custom rules for eslint in `.eslintrc.json` file, Added at project root. + ## Bugs or improvements Every project needs improvements, Feel free to report any bugs or improvements. Pull requests are always welcome. diff --git a/package-lock.json b/package-lock.json index c0b6e6e..c689ba4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -193,7 +193,6 @@ "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -324,6 +323,19 @@ "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", @@ -359,8 +371,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", @@ -368,6 +379,16 @@ "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==" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -452,6 +473,14 @@ } } }, + "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" + } + }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -536,8 +565,7 @@ "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 + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "bson": { "version": "1.1.1", @@ -619,6 +647,11 @@ "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", @@ -785,6 +818,22 @@ } } }, + "codacy-coverage": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/codacy-coverage/-/codacy-coverage-3.4.0.tgz", + "integrity": "sha512-A0ats3/gZtOw76muu++HZ6QrInztWjjLefkLJmmBpjPfyn6nNwNLoApmGmj3F3dfgl2+o6u5GwPnUBkKdfKXTQ==", + "requires": { + "bluebird": "^3.5.x", + "commander": "^2.x", + "jacoco-parse": "^2.x", + "joi": "^13.x", + "lcov-parse": "^1.x", + "lodash": "^4.17.4", + "log-driver": "^1.x", + "request": "^2.88.0", + "request-promise": "^4.x" + } + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -819,7 +868,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -827,9 +875,7 @@ "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true, - "optional": true + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" }, "commondir": { "version": "1.0.1", @@ -988,6 +1034,14 @@ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "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": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1041,7 +1095,6 @@ "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" } @@ -1090,8 +1143,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", @@ -1116,8 +1168,7 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, "doctrine": { "version": "3.0.0", @@ -1148,6 +1199,15 @@ "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", @@ -1185,7 +1245,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz", "integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==", - "dev": true, "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", @@ -1203,7 +1262,6 @@ "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", @@ -1224,8 +1282,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.5.1", @@ -1545,8 +1602,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", @@ -1656,17 +1712,20 @@ } } }, + "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=", - "dev": true + "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=", - "dev": true + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fast-levenshtein": { "version": "2.0.6", @@ -1829,6 +1888,11 @@ } } }, + "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", @@ -1919,14 +1983,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1941,20 +2003,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -2071,8 +2130,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -2084,7 +2142,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2099,7 +2156,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2107,14 +2163,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -2133,7 +2187,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -2214,8 +2267,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -2227,7 +2279,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -2349,7 +2400,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2424,8 +2474,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -2505,6 +2554,14 @@ "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", @@ -2582,8 +2639,7 @@ "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, "handlebars": { "version": "4.4.3", @@ -2605,11 +2661,24 @@ } } }, + "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" } @@ -2617,14 +2686,12 @@ "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", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" }, "has-unicode": { "version": "2.0.1", @@ -2678,6 +2745,11 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==" + }, "hosted-git-info": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", @@ -2695,6 +2767,16 @@ "statuses": ">= 1.4.0 < 2" } }, + "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.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -2865,8 +2947,7 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" }, "is-ci": { "version": "1.2.1", @@ -2900,8 +2981,7 @@ "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 + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-descriptor": { "version": "0.1.6", @@ -3033,7 +3113,6 @@ "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" } @@ -3054,11 +3133,15 @@ "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", @@ -3070,6 +3153,14 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "requires": { + "punycode": "2.x.x" + } + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3082,6 +3173,11 @@ "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=" + }, "istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", @@ -3219,6 +3315,84 @@ "handlebars": "^4.1.2" } }, + "jacoco-parse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jacoco-parse/-/jacoco-parse-2.0.1.tgz", + "integrity": "sha512-YGhIb2iXuQ4/zNh2zgHd6Z6dqlYwLYH1wfsxtTNQ+jnHH9PhhuMwqOFihXymSI41trxok48LdKkSeDIWs28tYg==", + "requires": { + "mocha": "^5.2.0", + "xml2js": "^0.4.9" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, + "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" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3235,6 +3409,11 @@ "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", @@ -3247,11 +3426,15 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "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==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3259,6 +3442,11 @@ "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=" + }, "jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -3283,6 +3471,17 @@ } } }, + "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" + } + }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -3322,6 +3521,11 @@ "package-json": "^4.0.0" } }, + "lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=" + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -3405,6 +3609,11 @@ "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", @@ -3681,6 +3890,11 @@ } } }, + "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=" + }, "moment": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", @@ -4069,6 +4283,11 @@ } } }, + "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", @@ -4108,14 +4327,12 @@ "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 + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" }, "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 + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -4142,7 +4359,6 @@ "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" @@ -4385,6 +4601,11 @@ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -4444,6 +4665,11 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, + "psl": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" + }, "pstree.remy": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", @@ -4453,8 +4679,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { "version": "6.5.2", @@ -4601,6 +4826,64 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "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" + } + } + } + }, + "request-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.4.tgz", + "integrity": "sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg==", + "requires": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "request-promise-core": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "requires": { + "lodash": "^4.17.11" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5038,6 +5321,22 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "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", @@ -5064,6 +5363,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -5077,7 +5381,6 @@ "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.3", "function-bind": "^1.1.1" @@ -5087,7 +5390,6 @@ "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.3", "function-bind": "^1.1.1" @@ -5327,6 +5629,21 @@ "repeat-string": "^1.6.1" } }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==" + } + } + }, "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", @@ -5336,12 +5653,41 @@ "nopt": "~1.0.10" } }, + "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=" + } + } + }, "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-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -5495,7 +5841,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -5526,6 +5871,15 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -5534,8 +5888,7 @@ "uuid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "dev": true + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, "v8-compile-cache": { "version": "2.1.0", @@ -5563,6 +5916,16 @@ "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", @@ -5671,6 +6034,21 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "xml2js": { + "version": "0.4.22", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz", + "integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==", + "requires": { + "sax": ">=0.6.0", + "util.promisify": "~1.0.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", diff --git a/package.json b/package.json index 387b4e8..bdd2cc3 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,12 @@ "scripts": { "start": "node ./bin/www", "dev": "nodemon ./bin/www", - "test": "nyc mocha --timeout 10000 --exit", + "test": "nyc _mocha --timeout 10000 --exit --report lcovonly -- -R spec", "lint": "eslint --fix --config .eslintrc.json \"**/*.js\"" }, "dependencies": { "bcrypt": "^3.0.6", + "codacy-coverage": "^3.4.0", "cookie-parser": "~1.4.3", "cors": "^2.8.5", "debug": "~2.6.9", @@ -18,6 +19,7 @@ "express-jwt": "^5.3.1", "express-validator": "^6.1.1", "jsonwebtoken": "^8.5.1", + "mocha-lcov-reporter": "^1.3.0", "moment": "^2.24.0", "mongoose": "^5.6.6", "morgan": "~1.9.0", From 233c8fada4df84a0f4c360984022d814180ef627 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Tue, 22 Oct 2019 13:15:54 +0530 Subject: [PATCH 07/16] Updated packages. Modified README.md --- README.md | 42 ++++++++- package-lock.json | 214 +++++++++++++++++++++++++++------------------- package.json | 12 +-- 3 files changed, 171 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index e68935a..a8015cd 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ I am looking for a good job or work contract. You can contact me directly on my ## Buy me a Coffee -If you consider my project as a helpful stuff, You can appriciate me or my hard work and time spent to create this helpful structure with buying a coffee for me. I would be very thankful if you buy me a coffee, Please buy me a coffee :smile:. +If you consider my project as helpful stuff, You can appreciate me or my hard work and time spent to create this helpful structure with buying a coffee for me. I would be very thankful if you buy me a coffee, please buy me a coffee :smile:. Buy Me A Coffee @@ -35,7 +35,7 @@ If you consider my project as a helpful stuff, You can appriciate me or my hard - Light-weight project. - Test cases with [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/). - Code coverage with [Istanbuljs (nyc)](https://istanbul.js.org/). -- Included CI (Continuas Integration) with [Travis CI](https://travis-ci.org). +- Included CI (Continuous Integration) with [Travis CI](https://travis-ci.org). - Linting with [Eslint](https://eslint.org/). ## Software Requirements @@ -63,16 +63,50 @@ git clone https://github.com/maitraysuthar/rest-api-nodejs-mongodb.git ./myproje ```bash cd myproject npm install -npm update ``` ### Setting up environments 1. You will find a file named `.env.example` on root directory of project. 2. Create a new file by copying and pasting the file and then renaming it to just `.env` + ```bash + cp .env.example .env + ``` 3. The file `.env` is already ignored, so you never commit your credentials. 4. Change the values of the file to your environment. Helpful comments added to `.env.example` file to understand the constants. - +## Project structure +```sh +. +├── app.js +├── package.json +├── bin +│ └── www +├── controllers +│ ├── AuthController.js +│ └── BookController.js +├── models +│ ├── BookModel.js +│ └── UserModel.js +├── routes +│ ├── api.js +│ ├── auth.js +│ └── book.js +├── middlewares +│ ├── jwt.js +├── helpers +│ ├── apiResponse.js +│ ├── constants.js +│ ├── mailer.js +│ └── utility.js +├── test +│ ├── testConfig.js +│ ├── auth.js +│ └── book.js +└── public + ├── index.html + └── stylesheets + └── style.css +``` ## How to run ### Running API server locally diff --git a/package-lock.json b/package-lock.json index c689ba4..45b7c3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -354,14 +354,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", - "requires": { - "lodash": "^4.17.11" - } - }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -705,9 +697,9 @@ "dev": true }, "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "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", @@ -1189,9 +1181,9 @@ } }, "dotenv": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz", - "integrity": "sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg==" + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" }, "duplexer3": { "version": "0.1.4", @@ -1591,12 +1583,12 @@ "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" }, "express-validator": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.1.1.tgz", - "integrity": "sha512-AF6YOhdDiCU7tUOO/OHp2W++I3qpYX7EInMmEEcRGOjs+qoubwgc5s6Wo3OQgxwsWRGCxXlrF73SIDEmY4y3wg==", + "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.11", - "validator": "^11.0.0" + "lodash": "^4.17.15", + "validator": "^11.1.0" } }, "extend": { @@ -1833,14 +1825,6 @@ "dev": true, "requires": { "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - } } }, "flat-cache": { @@ -1962,7 +1946,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1983,12 +1968,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": 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" @@ -2003,17 +1990,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -2130,7 +2120,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -2142,6 +2133,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2156,6 +2148,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2163,12 +2156,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": 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" @@ -2187,6 +2182,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2267,7 +2263,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2279,6 +2276,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2364,7 +2362,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2400,6 +2399,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2419,6 +2419,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2462,12 +2463,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -2719,6 +2722,12 @@ "kind-of": "^4.0.0" }, "dependencies": { + "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 + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -2912,6 +2921,12 @@ "kind-of": "^3.0.2" }, "dependencies": { + "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 + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -2939,9 +2954,9 @@ } }, "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true }, "is-callable": { @@ -2967,6 +2982,12 @@ "kind-of": "^3.0.2" }, "dependencies": { + "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 + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -3062,6 +3083,12 @@ "kind-of": "^3.0.2" }, "dependencies": { + "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 + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -3118,9 +3145,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": { @@ -3502,9 +3529,9 @@ } }, "kareem": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", - "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", + "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw==" }, "kind-of": { "version": "6.0.2", @@ -3820,9 +3847,9 @@ } }, "mocha": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.1.tgz", - "integrity": "sha512-VCcWkLHwk79NYQc8cxhkmI8IigTIhsCwZ6RTxQsqK6go4UvEhzJkYuHm8B2YtlSxcYq2fY+ucr4JBwoD6ci80A==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", + "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", "dev": true, "requires": { "ansi-colors": "3.2.3", @@ -3901,18 +3928,9 @@ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, "mongodb": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.7.tgz", - "integrity": "sha512-2YdWrdf1PJgxcCrT1tWoL6nHuk6hCxhddAAaEh8QJL231ci4+P9FLyqopbTm2Z2sAU6mhCri+wd9r1hOcHdoMw==", - "requires": { - "mongodb-core": "3.2.7", - "safe-buffer": "^5.1.2" - } - }, - "mongodb-core": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.7.tgz", - "integrity": "sha512-WypKdLxFNPOH/Jy6i9z47IjG2wIldA54iDZBmHMINcgKOUcWJh8og+Wix76oGd7EyYkHJKssQ2FAOw5Su/n4XQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.3.tgz", + "integrity": "sha512-MdRnoOjstmnrKJsK8PY0PjP6fyF/SBS4R8coxmhsfEU7tQ46/J6j+aSHF2n4c2/H8B+Hc/Klbfp8vggZfI0mmA==", "requires": { "bson": "^1.1.1", "require_optional": "^1.0.1", @@ -3921,18 +3939,16 @@ } }, "mongoose": { - "version": "5.6.6", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.6.6.tgz", - "integrity": "sha512-5uecJSyl2TwbGM9vJteP4C54zsQL6qllq1qe/JPGO3oqIWcK/PnzCL91E0gfPH5VVpvWGX+6PafNYmU3NK8S7w==", + "version": "5.7.6", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.7.6.tgz", + "integrity": "sha512-2r87HmQMDCeZocoFmYGnJSpCW9ut95iQyPUcseG2B6EiAJjJBmR3pA01QyDF2+zQWpA8Ui4wH7xOq05U1nF6wg==", "requires": { - "async": "2.6.2", "bson": "~1.1.1", - "kareem": "2.3.0", - "mongodb": "3.2.7", - "mongodb-core": "3.2.7", + "kareem": "2.3.1", + "mongodb": "3.3.3", "mongoose-legacy-pluralize": "1.0.2", "mpath": "0.6.0", - "mquery": "3.2.1", + "mquery": "3.2.2", "ms": "2.1.2", "regexp-clone": "1.0.0", "safe-buffer": "5.1.2", @@ -3970,9 +3986,9 @@ "integrity": "sha512-i75qh79MJ5Xo/sbhxrDrPSEG0H/mr1kcZXJ8dH6URU5jD/knFxCVqVC/gVSW7GIXL/9hHWlT9haLbCXWOll3qw==" }, "mquery": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.1.tgz", - "integrity": "sha512-kY/K8QToZWTTocm0U+r8rqcJCp5PRl6e8tPmoDs5OeSO3DInZE2rAL6AYH+V406JTo8305LdASOQcxRDqHojyw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz", + "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==", "requires": { "bluebird": "3.5.1", "debug": "3.1.0", @@ -4121,23 +4137,23 @@ } }, "nodemailer": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.3.0.tgz", - "integrity": "sha512-TEHBNBPHv7Ie/0o3HXnb7xrPSSQmH1dXwQKRaMKDBGt/ZN54lvDVujP6hKkO/vjkIYL9rK8kHSG11+G42Nhxuw==" + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.3.1.tgz", + "integrity": "sha512-j0BsSyaMlyadEDEypK/F+xlne2K5m6wzPYMXS/yxKI0s7jmT1kBx6GEKRVbZmyYfKOsjkeC/TiMVDJBI/w5gMQ==" }, "nodemon": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz", - "integrity": "sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", + "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", "dev": true, "requires": { - "chokidar": "^2.1.5", - "debug": "^3.1.0", + "chokidar": "^2.1.8", + "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.6", - "semver": "^5.5.0", - "supports-color": "^5.2.0", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.2", "update-notifier": "^2.5.0" @@ -4157,6 +4173,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true } } }, @@ -4313,6 +4335,12 @@ "is-descriptor": "^0.1.0" } }, + "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 + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -5215,6 +5243,12 @@ "kind-of": "^3.2.0" }, "dependencies": { + "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 + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -5596,6 +5630,12 @@ "kind-of": "^3.0.2" }, "dependencies": { + "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 + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -5814,9 +5854,9 @@ "dev": true }, "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "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": { diff --git a/package.json b/package.json index bdd2cc3..0e7fa2b 100644 --- a/package.json +++ b/package.json @@ -14,23 +14,23 @@ "cookie-parser": "~1.4.3", "cors": "^2.8.5", "debug": "~2.6.9", - "dotenv": "^8.0.0", + "dotenv": "^8.2.0", "express": "~4.16.0", "express-jwt": "^5.3.1", - "express-validator": "^6.1.1", + "express-validator": "^6.2.0", "jsonwebtoken": "^8.5.1", "mocha-lcov-reporter": "^1.3.0", "moment": "^2.24.0", - "mongoose": "^5.6.6", + "mongoose": "^5.7.6", "morgan": "~1.9.0", - "nodemailer": "^6.3.0" + "nodemailer": "^6.3.1" }, "devDependencies": { "chai": "^4.2.0", "chai-http": "^4.3.0", "eslint": "^6.5.1", - "mocha": "^6.2.1", - "nodemon": "^1.19.1", + "mocha": "^6.2.2", + "nodemon": "^1.19.4", "nyc": "^14.1.1" } } From e10b73bcd30a311ae67a8780ee9e2f085d04b579 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Tue, 22 Oct 2019 14:13:49 +0530 Subject: [PATCH 08/16] Resolved mangoose warning, correct typo --- .env.example | 2 +- app.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 0370f3d..0837045 100644 --- a/.env.example +++ b/.env.example @@ -8,7 +8,7 @@ JWT_SECRET=YourSecret JWT_TIMEOUT_DURATION="2 hours" # You can place duration available here: https://github.com/auth0/node-jsonwebtoken#usage -# Seach for "expiresIn" option on above link. +# Search for "expiresIn" option on above link. EMAIL_SMTP_HOST=YourSMTPHost EMAIL_SMTP_PORT=YourSMTPPort diff --git a/app.js b/app.js index c6a6055..cd7c5d1 100644 --- a/app.js +++ b/app.js @@ -11,7 +11,7 @@ var cors = require("cors"); // DB connection var MONGODB_URL = process.env.MONGODB_URL; var mongoose = require("mongoose"); -mongoose.connect(MONGODB_URL, { useNewUrlParser: true }).then(() => { +mongoose.connect(MONGODB_URL, { useNewUrlParser: true, useUnifiedTopology: true }).then(() => { //don't show the log when it is test if(process.env.NODE_ENV !== "test") { console.log("Connected to %s", MONGODB_URL); From a056c4b62f6613cc325553005ff4d8a9e0adf7a4 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Tue, 22 Oct 2019 15:23:25 +0530 Subject: [PATCH 09/16] modified index.js --- public/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/index.html b/public/index.html index ab1ad8a..baa0d95 100644 --- a/public/index.html +++ b/public/index.html @@ -1,13 +1,13 @@ - Express + Nodejs API boilerplate -

Express

-

Welcome to Express

+

A boilerplate for REST API Development with Node.js, Express, and MongoDB

+

Author: @Maitray Suthar

From fa1b035fb462efd4107414afe7668619a98ef0d4 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Tue, 12 Nov 2019 18:05:14 +0530 Subject: [PATCH 10/16] Changed default response of book list. --- controllers/BookController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/BookController.js b/controllers/BookController.js index fca3fe2..6718226 100644 --- a/controllers/BookController.js +++ b/controllers/BookController.js @@ -27,7 +27,7 @@ exports.bookList = [ if(books.length > 0){ return apiResponse.successResponseWithData(res, "Operation success", books); }else{ - return apiResponse.successResponseWithData(res, "Operation success", {}); + return apiResponse.successResponseWithData(res, "Operation success", []); } }); } catch (err) { From 8191ce980308849b4663b20f63c292dd4664ca01 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Tue, 19 Nov 2019 18:33:16 +0530 Subject: [PATCH 11/16] Added id to responses. --- controllers/BookController.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/controllers/BookController.js b/controllers/BookController.js index 6718226..ee3aea4 100644 --- a/controllers/BookController.js +++ b/controllers/BookController.js @@ -8,6 +8,7 @@ mongoose.set("useFindAndModify", false); // Book Schema function BookData(data) { + this.id = data._id; this.title= data.title; this.description = data.description; this.isbn = data.isbn; @@ -23,7 +24,7 @@ exports.bookList = [ auth, function (req, res) { try { - Book.find({user: req.user._id},"title description isbn createdAt").then((books)=>{ + Book.find({user: req.user._id},"_id title description isbn createdAt").then((books)=>{ if(books.length > 0){ return apiResponse.successResponseWithData(res, "Operation success", books); }else{ @@ -51,7 +52,7 @@ exports.bookDetail = [ return apiResponse.successResponseWithData(res, "Operation success", {}); } try { - Book.findOne({_id: req.params.id,user: req.user._id},"title description isbn createdAt").then((book)=>{ + Book.findOne({_id: req.params.id,user: req.user._id},"_id title description isbn createdAt").then((book)=>{ if(book !== null){ let bookData = new BookData(book); return apiResponse.successResponseWithData(res, "Operation success", bookData); From 7ebd93ef19859c9a97735be9dde37909827ef6e9 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Thu, 18 Jun 2020 22:16:34 +0530 Subject: [PATCH 12/16] Added Ad banner to README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a8015cd..9048b3d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,11 @@ A ready-to-use boilerplate for REST API Development with Node.js, Express, and M This is a basic API skeleton written in JavaScript ES2015. Very useful to building a RESTful web APIs for your front-end platforms like Android, iOS or JavaScript frameworks (Angular, Reactjs, etc). -This project will run on **NodeJs** using **MongoDB** as database. I had tried to maintain the code structure easy as any beginner can also adopt the flow and start building an API. Project is open for suggestions, Bug reports and pull requests. +This project will run on **NodeJs** using **MongoDB** as database. I had tried to maintain the code structure easy as any beginner can also adopt the flow and start building an API. Project is open for suggestions, Bug reports and pull requests. + +## Some Great Stuff + +Buy Me A Coffee ## Advertise for Job/Work Contract From 999a063906a0416a24ff781cd37fc2da615c97bd Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Thu, 18 Jun 2020 22:40:33 +0530 Subject: [PATCH 13/16] Corrected Ad banner image to README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9048b3d..d5e1f1d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This project will run on **NodeJs** using **MongoDB** as database. I had tried t ## Some Great Stuff -Buy Me A Coffee +Some Great Stuff ## Advertise for Job/Work Contract From 6ca5ae919063031e9752067808ff56070420c3d7 Mon Sep 17 00:00:00 2001 From: GitAds Date: Sat, 20 Jun 2020 16:26:37 +0100 Subject: [PATCH 14/16] GitAds - change sponsor to PopSQL --- README.md | 4 +++- readme_image.png | Bin 0 -> 176648 bytes 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 readme_image.png diff --git a/README.md b/README.md index d5e1f1d..9678ad8 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,9 @@ This project will run on **NodeJs** using **MongoDB** as database. I had tried t ## Some Great Stuff -Some Great Stuff +Some Great Stuff +
This advert was placed by GitAds + ## Advertise for Job/Work Contract diff --git a/readme_image.png b/readme_image.png new file mode 100644 index 0000000000000000000000000000000000000000..0126b02cd5f6da9aec9a4b8237b622249fdd5558 GIT binary patch literal 176648 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�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 literal 0 HcmV?d00001 From 040f8de19057f8135de23b5b891e05e562b2cd39 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Fri, 26 Jun 2020 09:15:21 +0530 Subject: [PATCH 15/16] Modified ad link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5e1f1d..442bacb 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This project will run on **NodeJs** using **MongoDB** as database. I had tried t ## Some Great Stuff -Some Great Stuff +Some Great Stuff ## Advertise for Job/Work Contract From 6a1ba2da70a26b010d5aa1791a778a69b8ce7396 Mon Sep 17 00:00:00 2001 From: Maitray Suthar Date: Sun, 21 Feb 2021 21:06:18 +0530 Subject: [PATCH 16/16] Modify README.md --- README.md | 62 +++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index c96760b..34f1d41 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,46 @@ # Nodejs Expressjs MongoDB Ready-to-use API Project Structure -[![Author](http://img.shields.io/badge/author-@maitraysuthar-blue.svg)](https://www.linkedin.com/in/maitray-suthar/) [![GitHub license](https://img.shields.io/github/license/maitraysuthar/rest-api-nodejs-mongodb.svg)](https://github.com/maitraysuthar/rest-api-nodejs-mongodb/blob/master/LICENSE) ![GitHub repo size](https://img.shields.io/github/repo-size/maitraysuthar/rest-api-nodejs-mongodb) [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/b3eb80984adc4671988ffb22d6ad83df)](https://www.codacy.com/manual/maitraysuthar/rest-api-nodejs-mongodb?utm_source=github.com&utm_medium=referral&utm_content=maitraysuthar/rest-api-nodejs-mongodb&utm_campaign=Badge_Coverage) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b3eb80984adc4671988ffb22d6ad83df)](https://www.codacy.com/manual/maitraysuthar/rest-api-nodejs-mongodb?utm_source=github.com&utm_medium=referral&utm_content=maitraysuthar/rest-api-nodejs-mongodb&utm_campaign=Badge_Grade) ![Travis (.com)](https://img.shields.io/travis/com/maitraysuthar/rest-api-nodejs-mongodb) -A ready-to-use boilerplate for REST API Development with Node.js, Express, and MongoDB +[![Author](http://img.shields.io/badge/author-@maitraysuthar-blue.svg)](https://www.linkedin.com/in/maitray-suthar/) [![GitHub license](https://img.shields.io/github/license/maitraysuthar/rest-api-nodejs-mongodb.svg)](https://github.com/maitraysuthar/rest-api-nodejs-mongodb/blob/master/LICENSE) ![GitHub repo size](https://img.shields.io/github/repo-size/maitraysuthar/rest-api-nodejs-mongodb) [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/b3eb80984adc4671988ffb22d6ad83df)](https://www.codacy.com/manual/maitraysuthar/rest-api-nodejs-mongodb?utm_source=github.com&utm_medium=referral&utm_content=maitraysuthar/rest-api-nodejs-mongodb&utm_campaign=Badge_Coverage) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b3eb80984adc4671988ffb22d6ad83df)](https://www.codacy.com/manual/maitraysuthar/rest-api-nodejs-mongodb?utm_source=github.com&utm_medium=referral&utm_content=maitraysuthar/rest-api-nodejs-mongodb&utm_campaign=Badge_Grade) ![Travis (.com)](https://img.shields.io/travis/com/maitraysuthar/rest-api-nodejs-mongodb) +A ready-to-use boilerplate for REST API Development with Node.js, Express, and MongoDB ## Getting started - This is a basic API skeleton written in JavaScript ES2015. Very useful to building a RESTful web APIs for your front-end platforms like Android, iOS or JavaScript frameworks (Angular, Reactjs, etc). This project will run on **NodeJs** using **MongoDB** as database. I had tried to maintain the code structure easy as any beginner can also adopt the flow and start building an API. Project is open for suggestions, Bug reports and pull requests. -## Some Great Stuff - -Some Great Stuff -
This advert was placed by GitAds - ## Advertise for Job/Work Contract -I am looking for a good job or work contract. You can contact me directly on my email ([maitraysuthar@gmail.com](mailto:maitraysuthar@gmail.com "maitraysuthar@gmail.com")) or you can download my CV from my personal [website](https://maitraysuthar.github.io/portfolio/). Looking forward. Thanks :smile: +I am open for a good job or work contract. You can contact me directly on my email ([maitraysuthar@gmail.com](mailto:maitraysuthar@gmail.com "maitraysuthar@gmail.com")) or you can download my CV from my personal [website](https://maitraysuthar.github.io/portfolio/). ## Buy me a Coffee -If you consider my project as helpful stuff, You can appreciate me or my hard work and time spent to create this helpful structure with buying a coffee for me. I would be very thankful if you buy me a coffee, please buy me a coffee :smile:. +If you consider my project as helpful stuff, You can appreciate me or my hard work and time spent to create this helpful structure with buying me a coffee. Buy Me A Coffee ## Features -- Basic Authentication (Register/Login with hashed password) -- Account confirmation with 4 (Changeable) digit OTP. -- Email helper ready just import and use. -- JWT Tokens, make requests with a token after login with `Authorization` header with value `Bearer yourToken` where `yourToken` will be returned in Login response. -- Pre-defined response structures with proper status codes. -- Included CORS. -- **Book** example with **CRUD** operations. -- Validations added. -- Included API collection for Postman. -- Light-weight project. -- Test cases with [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/). -- Code coverage with [Istanbuljs (nyc)](https://istanbul.js.org/). -- Included CI (Continuous Integration) with [Travis CI](https://travis-ci.org). -- Linting with [Eslint](https://eslint.org/). +- Basic Authentication (Register/Login with hashed password) +- Account confirmation with 4 (Changeable) digit OTP. +- Email helper ready just import and use. +- JWT Tokens, make requests with a token after login with `Authorization` header with value `Bearer yourToken` where `yourToken` will be returned in Login response. +- Pre-defined response structures with proper status codes. +- Included CORS. +- **Book** example with **CRUD** operations. +- Validations added. +- Included API collection for Postman. +- Light-weight project. +- Test cases with [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/). +- Code coverage with [Istanbuljs (nyc)](https://istanbul.js.org/). +- Included CI (Continuous Integration) with [Travis CI](https://travis-ci.org). +- Linting with [Eslint](https://eslint.org/). ## Software Requirements -- Node.js **8+** -- MongoDB **3.6+** (Recommended **4+**) +- Node.js **8+** +- MongoDB **3.6+** (Recommended **4+**) ## How to install @@ -79,7 +73,9 @@ npm install ``` 3. The file `.env` is already ignored, so you never commit your credentials. 4. Change the values of the file to your environment. Helpful comments added to `.env.example` file to understand the constants. -## Project structure + +## Project structure + ```sh . ├── app.js @@ -112,9 +108,10 @@ npm install └── stylesheets └── style.css ``` + ## How to run -### Running API server locally +### Running API server locally ```bash npm run dev @@ -128,7 +125,8 @@ App is running ... Press CTRL + C to stop the process. ``` -**Note:** `YOUR_DB_CONNECTION_STRING` will be your MongoDB connection string. + +**Note:** `YOUR_DB_CONNECTION_STRING` will be your MongoDB connection string. ### Creating new models @@ -144,7 +142,7 @@ If you need to add more controllers to the project just create a new file in `/c ## Tests -### Running Test Cases +### Running Test Cases ```bash npm test @@ -158,7 +156,7 @@ If you need to add more test cases to the project just create a new file in `/te ## ESLint -### Running Eslint +### Running Eslint ```bash npm run lint @@ -172,4 +170,4 @@ Every project needs improvements, Feel free to report any bugs or improvements. ## License -This project is open-sourced software licensed under the MIT License. See the LICENSE file for more information. \ No newline at end of file +This project is open-sourced software licensed under the MIT License. See the LICENSE file for more information.