diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..8d87b1d2 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules/* diff --git a/.eslintrc.json b/.eslintrc.json index d48ce39e..7c128e88 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,6 +5,7 @@ ], "parser": "@typescript-eslint/parser", "parserOptions": { + "project": "./tsconfig.json", "sourceType": "module", "ecmaFeatures": { "modules": true @@ -15,9 +16,35 @@ "json" ], "rules": { + "@typescript-eslint/camelcase": "off", "@typescript-eslint/indent": ["error", 2], - "import/no-extraneous-dependencies": "off", + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/restrict-plus-operands": "error", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/unified-signatures": "error", + "@typescript-eslint/unbound-method": [ + "error", + { + "ignoreStatic": true + } + ], + "@typescript-eslint/promise-function-async": [ + "error", + { + "checkArrowFunctions": true, + "checkFunctionDeclarations": true, + "checkFunctionExpressions": true, + "checkMethodDeclarations": true + } + ], + "no-console": "off", "no-underscore-dangle": "off", + "import/no-extraneous-dependencies": "off", "strict": "off" }, "env": { diff --git a/.travis.yml b/.travis.yml index ec40ae59..d966251a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,16 @@ dist: trusty language: node_js -sudo: required node_js: - "11" +cache: npm +sudo: required branches: only: - master - develop + - /^feature\/.*/ + - /^release-.*/ + - /^hotfix-.*/ notifications: email: recipients: @@ -17,5 +21,5 @@ notifications: install: - npm ci script: - - npm run coverage + - npm run test diff --git a/package-lock.json b/package-lock.json index 5057a088..926a269f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -195,22 +195,42 @@ } } }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-as-promised": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz", + "integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/mocha": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.6.tgz", - "integrity": "sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", "dev": true }, "@types/node": { "version": "11.11.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.3.tgz", - "integrity": "sha512-wp6IOGu1lxsfnrD+5mX6qwSwWuqsdkKKxTN4aQc4wByHAKZJf9/D4KXPQ1POUjEbnCP5LMggB0OEFNY9OTsMqg==", - "dev": true + "integrity": "sha512-wp6IOGu1lxsfnrD+5mX6qwSwWuqsdkKKxTN4aQc4wByHAKZJf9/D4KXPQ1POUjEbnCP5LMggB0OEFNY9OTsMqg==" }, "@types/underscore": { - "version": "1.8.19", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.19.tgz", - "integrity": "sha512-9r6zM91/lTnSYTEJbxf7FwgeVXzRZDegaGPXF+Bp0MSMYTTI2UvQPkoti/YE9ZWThU+0DMya6l9XePvOPBLKow==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.9.0.tgz", + "integrity": "sha512-1koEJ2AhXaR0HVP3VlN0pCb51n87g5QL9rUiGaY+Nte9gBd2FYf/zNvS5ZtHg7o6owYNS6QA/4ZJ/mIiz2q1hA==", "dev": true }, "@types/web3": { @@ -224,63 +244,55 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.5.0.tgz", - "integrity": "sha512-TZ5HRDFz6CswqBUviPX8EfS+iOoGbclYroZKT3GWGYiGScX0qo6QjHc5uuM7JN920voP2zgCkHgF5SDEVlCtjQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.10.2.tgz", + "integrity": "sha512-7449RhjE1oLFIy5E/5rT4wG5+KsfPzakJuhvpzXJ3C46lq7xywY0/Rjo9ZBcwrfbk0nRZ5xmUHkk7DZ67tSBKw==", "dev": true, "requires": { - "@typescript-eslint/parser": "1.5.0", - "@typescript-eslint/typescript-estree": "1.5.0", - "requireindex": "^1.2.0", + "@typescript-eslint/experimental-utils": "1.10.2", + "eslint-utils": "^1.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^2.0.1", "tsutils": "^3.7.0" - }, - "dependencies": { - "@typescript-eslint/parser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.5.0.tgz", - "integrity": "sha512-pRWTnJrnxuT0ragdY26hZL+bxqDd4liMlftpH2CBlMPryOIOb1J+MdZuw6R4tIu6bWVdwbHKPTs+Q34LuGvfGw==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "1.5.0", - "eslint-scope": "^4.0.0", - "eslint-visitor-keys": "^1.0.0" - } - } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.10.2.tgz", + "integrity": "sha512-Hf5lYcrnTH5Oc67SRrQUA7KuHErMvCf5RlZsyxXPIT6AXa8fKTyfFO6vaEnUmlz48RpbxO4f0fY3QtWkuHZNjg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.10.2", + "eslint-scope": "^4.0.0" } }, "@typescript-eslint/parser": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.4.2.tgz", - "integrity": "sha512-OqLkY9295DXXaWToItUv3olO2//rmzh6Th6Sc7YjFFEpEuennsm5zhygLLvHZjPxPlzrQgE8UDaOPurDylaUuw==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.10.2.tgz", + "integrity": "sha512-xWDWPfZfV0ENU17ermIUVEVSseBBJxKfqBcRCMZ8nAjJbfA5R7NWMZmFFHYnars5MjK4fPjhu4gwQv526oZIPQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "1.4.2", - "eslint-scope": "^4.0.0", + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "1.10.2", + "@typescript-eslint/typescript-estree": "1.10.2", "eslint-visitor-keys": "^1.0.0" - }, - "dependencies": { - "@typescript-eslint/typescript-estree": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.4.2.tgz", - "integrity": "sha512-wKgi/w6k1v3R4b6oDc20cRWro2gBzp0wn6CAeYC8ExJMfvXMfiaXzw2tT9ilxdONaVWMCk7B9fMdjos7bF/CWw==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" - } - } } }, "@typescript-eslint/typescript-estree": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.5.0.tgz", - "integrity": "sha512-XqR14d4BcYgxcrpxIwcee7UEjncl9emKc/MgkeUfIk2u85KlsGYyaxC7Zxjmb17JtWERk/NaO+KnBsqgpIXzwA==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.10.2.tgz", + "integrity": "sha512-Kutjz0i69qraOsWeI8ETqYJ07tRLvD9URmdrMoF10bG8y8ucLmPtSxROvVejWvlJUGl2et/plnMiKRDW+rhEhw==", "dev": true, "requires": { "lodash.unescape": "4.0.1", "semver": "5.5.0" } }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -333,8 +345,7 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "ansi-styles": { "version": "3.2.1", @@ -345,6 +356,11 @@ "color-convert": "^1.9.0" } }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, "append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", @@ -354,12 +370,26 @@ "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", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, "arg": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", @@ -385,6 +415,16 @@ "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -443,8 +483,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { "version": "1.3.0", @@ -515,7 +554,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -718,6 +756,15 @@ "type-detect": "^4.0.5" } }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -781,11 +828,19 @@ "wrap-ansi": "^2.0.0" } }, + "cls-bluebird": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz", + "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=", + "requires": { + "is-bluebird": "^1.0.2", + "shimmer": "^1.1.0" + } + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "color-convert": { "version": "1.9.3", @@ -827,8 +882,12 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "contains-path": { "version": "0.1.0", @@ -1105,6 +1164,11 @@ "type-detect": "^4.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -1133,6 +1197,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1152,6 +1221,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -1181,6 +1255,11 @@ "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" }, + "dottie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz", + "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==" + }, "drbg.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", @@ -1391,21 +1470,22 @@ } }, "eslint-plugin-import": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz", - "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz", + "integrity": "sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==", "dev": true, "requires": { + "array-includes": "^3.0.3", "contains-path": "^0.1.0", - "debug": "^2.6.8", + "debug": "^2.6.9", "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", "read-pkg-up": "^2.0.0", - "resolve": "^1.6.0" + "resolve": "^1.11.0" }, "dependencies": { "doctrine": { @@ -2018,8 +2098,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "function-bind": { "version": "1.1.1", @@ -2032,6 +2111,54 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2065,7 +2192,6 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2192,6 +2318,11 @@ "has-symbol-support-x": "^1.4.1" } }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "hash-base": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", @@ -2297,6 +2428,14 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "ignore-walk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, "import-fresh": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", @@ -2313,11 +2452,15 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "inflection": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", + "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2328,6 +2471,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, "inquirer": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", @@ -2383,6 +2531,11 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bluebird": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", + "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" + }, "is-buffer": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", @@ -2402,8 +2555,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-function": { "version": "1.0.1", @@ -2983,7 +3135,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3145,6 +3296,19 @@ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.10.1.tgz", "integrity": "sha512-w22rOL5ZYu6HbUehB5deurghGM0hS/xBVyHMGKOuQctkk93J9z9VEOhDsiWrXOprVNQpP9uzGKdl8v9mFspKuw==" }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "moment-timezone": { + "version": "0.5.25", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz", + "integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==", + "requires": { + "moment": ">= 2.9.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3172,6 +3336,31 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -3243,6 +3432,32 @@ } } }, + "node-pre-gyp": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", + "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -3255,6 +3470,20 @@ "validate-npm-package-license": "^3.0.1" } }, + "npm-bundled": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" + }, + "npm-packlist": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -3264,11 +3493,21 @@ "path-key": "^2.0.0" } }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "number-to-bn": { "version": "1.7.0", @@ -3495,8 +3734,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { "version": "3.1.0", @@ -3512,8 +3750,16 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } }, "p-cancelable": { "version": "0.3.0", @@ -3635,8 +3881,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", @@ -3858,6 +4103,24 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -3959,12 +4222,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "requireindex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -3995,11 +4252,18 @@ "signal-exit": "^3.0.2" } }, + "retry-as-promised": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", + "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", + "requires": { + "any-promise": "^1.3.0" + } + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -4049,6 +4313,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "scrypt": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", @@ -4112,8 +4381,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "send": { "version": "0.17.1", @@ -4142,6 +4410,53 @@ } } }, + "sequelize": { + "version": "5.8.10", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.8.10.tgz", + "integrity": "sha512-EUQh/Tv/66WTOsVwN+GxB/5HIa0tHzf9Of8nQmjVTw7hG0nXSbZLOsHP+mbhDJp6Y68y0GsynNAKy8Y/c1uLhA==", + "requires": { + "bluebird": "^3.5.0", + "cls-bluebird": "^2.1.0", + "debug": "^4.1.1", + "dottie": "^2.0.0", + "inflection": "1.12.0", + "lodash": "^4.17.11", + "moment": "^2.24.0", + "moment-timezone": "^0.5.21", + "retry-as-promised": "^3.1.0", + "semver": "^5.6.0", + "sequelize-pool": "^2.1.0", + "toposort-class": "^1.0.1", + "uuid": "^3.2.1", + "validator": "^10.11.0", + "wkx": "^0.4.6" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } + } + }, + "sequelize-pool": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-2.1.0.tgz", + "integrity": "sha512-NDy4qJPxm6+i7FEQqAsJPKVmKLOgorQJ5fYxrTNmvhb3QAbC5nAUxftiIOKQCyYXhWSgPBlDw7eJQozavmq45g==" + }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -4168,8 +4483,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "setimmediate": { "version": "1.0.5", @@ -4213,11 +4527,15 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-concat": { "version": "1.0.0", @@ -4326,6 +4644,16 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sqlite3": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.0.8.tgz", + "integrity": "sha512-kgwHu4j10KhpCHtx//dejd/tVQot7jc3sw+Sn0vMuKOw0X00Ckyg9VceKgzPyGmmz+zEoYue9tOLriWTvYy0ww==", + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.11.0", + "request": "^2.87.0" + } + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -4356,7 +4684,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -4384,7 +4711,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -4420,8 +4746,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { "version": "5.5.0", @@ -4687,6 +5012,11 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -4781,9 +5111,9 @@ } }, "typescript": { - "version": "3.3.3333", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3333.tgz", - "integrity": "sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw==" + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.1.tgz", + "integrity": "sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==" }, "uglify-js": { "version": "3.6.0", @@ -4894,6 +5224,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -5271,11 +5606,18 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "requires": { "string-width": "^1.0.2 || 2" } }, + "wkx": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.7.tgz", + "integrity": "sha512-pHf546L96TK8RradLt1cWaIffstgv/zXZ14CGz5KnBs1AxBX0wm+IDphjJw0qrEqRv8P9W9CdTt8Z1unMRZ19A==", + "requires": { + "@types/node": "*" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", diff --git a/package.json b/package.json index ad17dbbe..f96c56cb 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "0.1.0-alpha.1", "description": "Facilitator is an executable to facilitate asynchronous message passing between blockchains.", "scripts": { - "lint": "eslint src -c .eslintrc.json --ext ts", "test": "npm run test:unit", - "test:unit": "mocha -r ts-node/register tests/**/*.test.ts tests/*.test.ts ", + "lint:ts": "eslint src -c .eslintrc.json --ext ts", + "test:unit": "mocha -r ts-node/register tests/**/*.test.ts tests/*.test.ts", "coverage": "nyc npm run test" }, "repository": { @@ -31,20 +31,26 @@ "homepage": "https://github.com/OpenST/facilitator#readme", "dependencies": { "ts-node": "8.0.3", - "typescript": "3.3.3333", + "typescript": "3.5.1", "web3": "1.0.0-beta.52", - "fs-extra": "7.0.1" + "fs-extra": "7.0.1", + "sequelize": "5.8.10", + "sqlite3": "4.0.8" }, "devDependencies": { - "@types/mocha": "5.2.6", + "@types/chai": "4.1.7", + "@types/chai-as-promised": "7.1.0", + "@types/mocha": "5.2.7", "@types/node": "11.11.3", "@types/web3": "1.0.18", - "@typescript-eslint/eslint-plugin": "1.5.0", - "@typescript-eslint/parser": "1.4.2", + "@typescript-eslint/eslint-plugin": "1.10.2", + "@typescript-eslint/parser": "1.10.2", + "@typescript-eslint/typescript-estree": "1.10.2", "chai": "4.2.0", + "chai-as-promised": "7.1.1", "eslint": "5.16.0", "eslint-config-airbnb-base": "13.1.0", - "eslint-plugin-import": "2.14.0", + "eslint-plugin-import": "2.17.3", "eslint-plugin-json": "1.4.0", "mocha": "6.1.4", "nyc": "14.1.1", diff --git a/src/models/Database.ts b/src/models/Database.ts new file mode 100644 index 00000000..2d737838 --- /dev/null +++ b/src/models/Database.ts @@ -0,0 +1,77 @@ +// Copyright 2019 OpenST Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ---------------------------------------------------------------------------- + +import { Sequelize } from 'sequelize'; + +import { StakeRequestRepository } from './StakeRequestRepository'; + +export default class Database { + /* Storage */ + + public stakeRequestRepository: StakeRequestRepository; + + + /* Public Functions */ + + /** + * Creates a database object. + * + * Creates an empty database if a database does not exist. + * Opens a database in read/write mode. + * + * @param storage A database file path or ':memory' in case of in + * memory database. + */ + public static async create(storage = ':memory:'): Promise { + const sequelize = new Sequelize({ + dialect: 'sqlite', + storage, + logging: false, + }); + + const db = new Database(sequelize); + await sequelize.sync(); + + return db; + } + + + /* Private Functions */ + + /** + * Creates a database object. + * + * Function instantiates all repository classes by passing the following + * configuration options: + * - underscored: true -- Sets field option for all attributes of all models + * to snake cased name. + * - timestamps: true -- Adds timestamps attributes (createdAt and updatedAt) to all + * objects (StakeRequest, etc) of all repositories. + * - freezeTableName: true -- Disables the modification of table names; by default + * sequelize will automatically transform all passed model names + * (first parameter of define) into plural. + * + * @param sequelize Sequelize instance. + */ + private constructor(sequelize: Sequelize) { + this.stakeRequestRepository = new StakeRequestRepository({ + sequelize, + underscored: true, + timestamps: true, + freezeTableName: true, + }); + } +} diff --git a/src/models/StakeRequestRepository.ts b/src/models/StakeRequestRepository.ts new file mode 100644 index 00000000..69c663ad --- /dev/null +++ b/src/models/StakeRequestRepository.ts @@ -0,0 +1,205 @@ +// Copyright 2019 OpenST Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ---------------------------------------------------------------------------- + +/* eslint-disable class-methods-use-this */ + +import { + DataTypes, Model, InitOptions, +} from 'sequelize'; + +class StakeRequestModel extends Model {} + +/** + * An interface for input to create a StakeRequest object in the StakeRequestRepository. + * + * @see StakeRequestRepository::create() + */ +export interface StakeRequestAttributes { + stakeRequestHash: string; + messageHash: string; + amount: number; + beneficiary: string; + gasPrice: number; + gasLimit: number; + nonce: number; + gateway: string; + stakerProxy: string; +} + +/** + * An interface for an object created and stored within StakeRequestRepository. + * + * @see StakeRequestRepository::create() + * @see StakeRequestRepository::get() + */ +export interface StakeRequest extends StakeRequestAttributes { + createdAt: Date; + updatedAt: Date; +} + +/** + * Stores instances of StakeRequest. + * + * Class enables creation, update and retrieval of StakeRequest objects. + * On construction it initializes underlying database model. + */ +export class StakeRequestRepository { + /* Public Functions */ + + /** + * Initializes an underlying model and a database table. + * Creates database table if it does not exist. + */ + public constructor(initOptions: InitOptions) { + StakeRequestModel.init( + { + stakeRequestHash: { + type: DataTypes.STRING, + primaryKey: true, + }, + messageHash: { + type: DataTypes.STRING, + }, + amount: { + type: DataTypes.INTEGER, + validate: { + min: 0, + }, + }, + beneficiary: { + type: DataTypes.STRING, + }, + gasPrice: { + type: DataTypes.INTEGER, + validate: { + min: 0, + }, + }, + gasLimit: { + type: DataTypes.INTEGER, + validate: { + min: 0, + }, + }, + nonce: { + type: DataTypes.INTEGER, + validate: { + min: 0, + }, + }, + gateway: { + type: DataTypes.STRING, + }, + stakerProxy: { + type: DataTypes.STRING, + }, + }, + { + ...initOptions, + modelName: 'stakeRequest', + tableName: 'stake_request', + }, + ); + } + + /** + * Creates a stake request model in the repository. + * + * Function throws if a stake request with the same stake request's hash + * already exists. + * + * @param stakeRequestAttributes Attributes of a newly created stake request. + * + * @return Newly created stake request object. + */ + public async create(stakeRequestAttributes: StakeRequestAttributes): Promise { + try { + return await StakeRequestModel.create(stakeRequestAttributes) as StakeRequest; + } catch (e) { + const errorContext = { + input: { + stakeRequestAttributes, + }, + reason: e.message, + }; + + throw Error(`Failed to create a stake request: ${JSON.stringify(errorContext)}`); + } + } + + /** + * Returns a stake request with the specified stake request's hash or + * null if there is no. + * + * @param stakeRequestHash Stake request's hash to retrieve. + * + * @return Stake request object if exists, otherwise null. + */ + public async get(stakeRequestHash: string): Promise { + const stakeRequestModel = await StakeRequestModel.findOne({ + where: { + stakeRequestHash, + }, + }); + + if (stakeRequestModel === null) { + return null; + } + + return stakeRequestModel as StakeRequest; + } + + /** + * Updates a message hash for the specified stake request's hash. + * + * Function fails if stake request's hash does not exist. + * + * @param stakeRequestHash Stake request's hash to update message hash. + * @param messageHash New message hash to update. + */ + public async updateMessageHash(stakeRequestHash: string, messageHash: string): Promise { + const stakeRequestModel: StakeRequestModel = await StakeRequestModel.findOne({ + where: { + stakeRequestHash, + }, + }); + + if (stakeRequestModel === null) { + const errorContext = { + input: { + stakeRequestHash, + messageHash, + }, + reason: 'The specified stake request hash does not exist.', + }; + throw new Error(`Failed to update a stake request: ${JSON.stringify(errorContext)}`); + } + + try { + await stakeRequestModel.update({ messageHash }); + } catch (e) { + const errorContext = { + input: { + stakeRequestHash, + messageHash, + }, + reason: e.message, + }; + + throw Error(`Failed to update a stake request: ${JSON.stringify(errorContext)}`); + } + } +} diff --git a/tests/models/StakeRequestRepository/create.test.ts b/tests/models/StakeRequestRepository/create.test.ts new file mode 100644 index 00000000..39c303d0 --- /dev/null +++ b/tests/models/StakeRequestRepository/create.test.ts @@ -0,0 +1,119 @@ +// Copyright 2019 OpenST Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ---------------------------------------------------------------------------- + +import 'mocha'; + +import { + StakeRequestAttributes, + StakeRequest, +} from '../../../src/models/StakeRequestRepository'; + +import Database from '../../../src/models/Database'; + +import Util from './util'; + +import chai = require('chai'); +import chaiAsPromised = require('chai-as-promised'); +chai.use(chaiAsPromised); +const { assert } = chai; + +interface TestConfigInterface { + db: Database; +} +let config: TestConfigInterface; + +describe('StakeRequestRepository::create', (): void => { + beforeEach(async (): Promise => { + config = { + db: await Database.create(), + }; + }); + + it('Checks creation of stake request model.', async (): Promise => { + const stakeRequestAttributes: StakeRequestAttributes = { + stakeRequestHash: 'stakeRequestHash', + messageHash: 'messageHash', + amount: 1, + beneficiary: 'beneficiary', + gasPrice: 2, + gasLimit: 3, + nonce: 4, + gateway: 'gateway', + stakerProxy: 'stakerProxy', + }; + + const stakeRequestResponse = await config.db.stakeRequestRepository.create( + stakeRequestAttributes, + ); + + Util.checkStakeRequestAgainstAttributes(stakeRequestResponse, stakeRequestAttributes); + + const stakeRequest = await config.db.stakeRequestRepository.get( + stakeRequestAttributes.stakeRequestHash, + ); + + assert.notStrictEqual( + stakeRequest, + null, + 'Newly created stake request does not exist.', + ); + + Util.checkStakeRequestAgainstAttributes( + stakeRequest as StakeRequest, + stakeRequestAttributes, + ); + }); + + it('Throws if a stake request ' + + 'with the same stake request\'s hash already exists.', async (): Promise => { + const stakeRequestAttributesA: StakeRequestAttributes = { + stakeRequestHash: 'stakeRequestHash', + messageHash: 'messageHashA', + amount: 1, + beneficiary: 'beneficiaryA', + gasPrice: 2, + gasLimit: 3, + nonce: 4, + gateway: 'gatewayA', + stakerProxy: 'stakerProxyA', + }; + + // All members, except stakeRequestHash differs from stakeRequestAttributesA. + const stakeRequestAttributesB: StakeRequestAttributes = { + stakeRequestHash: 'stakeRequestHash', + messageHash: 'messageHashB', + amount: 5, + beneficiary: 'beneficiaryB', + gasPrice: 6, + gasLimit: 7, + nonce: 8, + gateway: 'gatewayB', + stakerProxy: 'stakerProxyB', + }; + + await config.db.stakeRequestRepository.create( + stakeRequestAttributesA, + ); + + return assert.isRejected( + config.db.stakeRequestRepository.create( + stakeRequestAttributesB, + ), + /^Failed to create a stake request*/, + 'Creation should fail as a stake request with the same hash already exists.', + ); + }); +}); diff --git a/tests/models/StakeRequestRepository/get.test.ts b/tests/models/StakeRequestRepository/get.test.ts new file mode 100644 index 00000000..4e77b052 --- /dev/null +++ b/tests/models/StakeRequestRepository/get.test.ts @@ -0,0 +1,85 @@ +// Copyright 2019 OpenST Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ---------------------------------------------------------------------------- + +import 'mocha'; + +import { + StakeRequestAttributes, + StakeRequest, +} from '../../../src/models/StakeRequestRepository'; +import Database from '../../../src/models/Database'; + +import Util from './util'; + +import assert = require('assert'); + +interface TestConfigInterface { + db: Database; +} +let config: TestConfigInterface; + +describe('StakeRequestRepository::get', (): void => { + beforeEach(async (): Promise => { + config = { + db: await Database.create(), + }; + }); + + it('Checks retrieval of an existing stake request.', async (): Promise => { + const stakeRequestAttributes: StakeRequestAttributes = { + stakeRequestHash: 'stakeRequestHash', + messageHash: 'messageHash', + amount: 1, + beneficiary: 'beneficiary', + gasPrice: 2, + gasLimit: 3, + nonce: 4, + gateway: 'gateway', + stakerProxy: 'stakerProxy', + }; + + await config.db.stakeRequestRepository.create( + stakeRequestAttributes, + ); + + const stakeRequest = await config.db.stakeRequestRepository.get( + stakeRequestAttributes.stakeRequestHash, + ); + + assert.notStrictEqual( + stakeRequest, + null, + 'Stake request should exists as it has been just created.', + ); + + Util.checkStakeRequestAgainstAttributes( + stakeRequest as StakeRequest, + stakeRequestAttributes, + ); + }); + + it('Checks retrieval of non-existing model.', async (): Promise => { + const stakeRequest = await config.db.stakeRequestRepository.get( + 'nonExistingHash', + ); + + assert.strictEqual( + stakeRequest, + null, + 'Stake request with \'nonExistingHash\' does not exist.', + ); + }); +}); diff --git a/tests/models/StakeRequestRepository/updateMessageHash.test.ts b/tests/models/StakeRequestRepository/updateMessageHash.test.ts new file mode 100644 index 00000000..6d700313 --- /dev/null +++ b/tests/models/StakeRequestRepository/updateMessageHash.test.ts @@ -0,0 +1,98 @@ +// Copyright 2019 OpenST Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ---------------------------------------------------------------------------- + +import 'mocha'; + +import { + StakeRequestAttributes, + StakeRequest, +} from '../../../src/models/StakeRequestRepository'; + +import Database from '../../../src/models/Database'; + +import Util from './util'; + +import chai = require('chai'); +import chaiAsPromised = require('chai-as-promised'); +chai.use(chaiAsPromised); +const { assert } = chai; + +interface TestConfigInterface { + db: Database; +} +let config: TestConfigInterface; + +describe('StakeRequestRepository::create', (): void => { + beforeEach(async (): Promise => { + config = { + db: await Database.create(), + }; + }); + + it('Updates existing existing stake request.', async (): Promise => { + const stakeRequestAttributes: StakeRequestAttributes = { + stakeRequestHash: 'stakeRequestHash', + messageHash: '', + amount: 1, + beneficiary: 'beneficiary', + gasPrice: 2, + gasLimit: 3, + nonce: 4, + gateway: 'gateway', + stakerProxy: 'stakerProxy', + }; + + await config.db.stakeRequestRepository.create( + stakeRequestAttributes, + ); + + const updatedMessageHash = 'updatedMessageHash'; + + await config.db.stakeRequestRepository.updateMessageHash( + stakeRequestAttributes.stakeRequestHash, + updatedMessageHash, + ); + + const stakeRequest = await config.db.stakeRequestRepository.get( + stakeRequestAttributes.stakeRequestHash, + ); + + assert.notStrictEqual( + stakeRequest, + null, + 'Newly created stake request does not exist.', + ); + + const updatedStakeRequestAttributes = stakeRequestAttributes; + updatedStakeRequestAttributes.messageHash = updatedMessageHash; + + // Checking that the retrieved stake request matches with the updated one. + Util.checkStakeRequestAgainstAttributes( + stakeRequest as StakeRequest, + updatedStakeRequestAttributes, + ); + }); + + it('Fails to updates a stake request that does not exist.', + async (): Promise => assert.isRejected( + config.db.stakeRequestRepository.updateMessageHash( + 'nonExistingStakeRequestHash', + 'updatedMessageHash', + ), + /^Failed to update a stake request*/, + 'Update should fail as a stake request with the specified hash does not exist.', + )); +}); diff --git a/tests/models/StakeRequestRepository/util.ts b/tests/models/StakeRequestRepository/util.ts new file mode 100644 index 00000000..54738abb --- /dev/null +++ b/tests/models/StakeRequestRepository/util.ts @@ -0,0 +1,77 @@ +// Copyright 2019 OpenST Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ---------------------------------------------------------------------------- + +import { + StakeRequestAttributes, + StakeRequest, +} from '../../../src/models/StakeRequestRepository'; + +import assert = require('assert'); + +const Util = { + checkStakeRequestAgainstAttributes( + stakeRequest: StakeRequest, + stakeRequestAttributes: StakeRequestAttributes, + ): void { + assert.strictEqual( + stakeRequest.stakeRequestHash, + stakeRequestAttributes.stakeRequestHash, + ); + + assert.strictEqual( + stakeRequest.messageHash, + stakeRequestAttributes.messageHash, + ); + + assert.strictEqual( + stakeRequest.amount, + stakeRequestAttributes.amount, + ); + + assert.strictEqual( + stakeRequest.beneficiary, + stakeRequestAttributes.beneficiary, + ); + + assert.strictEqual( + stakeRequest.gasPrice, + stakeRequestAttributes.gasPrice, + ); + + assert.strictEqual( + stakeRequest.gasLimit, + stakeRequestAttributes.gasLimit, + ); + + assert.strictEqual( + stakeRequest.nonce, + stakeRequestAttributes.nonce, + ); + + assert.strictEqual( + stakeRequest.gateway, + stakeRequestAttributes.gateway, + ); + + assert.strictEqual( + stakeRequest.stakerProxy, + stakeRequestAttributes.stakerProxy, + ); + }, + +}; + +export default Util; diff --git a/tsconfig.json b/tsconfig.json index 48ef0486..1bfeba70 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,33 @@ { "compilerOptions": { - "declaration": true, + "target": "es6", "module": "commonjs", - "outDir": "./lib", + "alwaysStrict": true, + "strictNullChecks": true, + "strictBindCallApply": true, + "strictFunctionTypes": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noErrorTruncation": true, "sourceMap": true, - "target": "es5" + "types": [ + "chai", + "node", + "mocha" + ], + "resolveJsonModule": true }, "include": [ "index.ts", + "src/*.ts", "src/**/*.ts" + ], + "exclude": [ + "node_modules" ] }