diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..cef74ae4f --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +# don't ever lint node_modules +node_modules +# don't lint build output (make sure it's set to your correct build folder name) +dist +# don't lint nyc coverage output +coverage + +.eslintrc.js +jest.config.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..10fbfc63d --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,12 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: [ + '@typescript-eslint', + ], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + ], +}; + diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index c2181ff0c..90a22a39f 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -17,3 +17,5 @@ jobs: run: npm run check - name: Run test run: npm t + - name: Run lint + run: npm run lint diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 8bdedbe57..95bcf7bb7 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -20,3 +20,5 @@ jobs: run: npm run check-sanity - name: Run test run: npm t + - name: Run lint + run: npm run lint \ No newline at end of file diff --git a/dangerfile.ts b/dangerfile.ts index 17a6858b2..16050ccc2 100644 --- a/dangerfile.ts +++ b/dangerfile.ts @@ -4,7 +4,7 @@ import { sanityCheckAll } from "./script/action/update-all"; sanityCheckAll().then(([errors, warnings]) => { errors.forEach(err => fail(err)); warnings.forEach(err => warn(err)); - if (errors.length > 0 || warnings.length > 0 { + if (errors.length > 0 || warnings.length > 0) { markdown("Please fix the errors/warnings above. Files can be replaced/renamed in this pull request (using command-line, or GitHub Desktop). Alternatively, you may close this pull request and open a new one."); } }); diff --git a/package-lock.json b/package-lock.json index a52395614..c742423ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -445,6 +445,74 @@ "minimist": "^1.2.0" } }, + "@eslint/eslintrc": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", + "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", + "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "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 + }, + "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 + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } + } + }, "@ethersproject/abi": { "version": "5.0.0-beta.153", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz", @@ -959,6 +1027,32 @@ } } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@octokit/auth-token": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", @@ -1347,6 +1441,12 @@ "@types/jest": "*" } }, + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, "@types/long": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", @@ -1410,6 +1510,152 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.1.1.tgz", + "integrity": "sha512-Hoxyt99EA9LMmqo/5PuWWPeWeB3mKyvibfJ1Hy5SfiUpjE8Nqp+5QNd9fOkzL66+fqvIWSIE+Ett16LGMzCGnQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.1.1", + "@typescript-eslint/scope-manager": "4.1.1", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.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" + } + }, + "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": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.1.1.tgz", + "integrity": "sha512-jzYsNciHoa4Z3c1URtmeT/bamYm8Dwfw6vuN3WHIE/BXb1iC4KveAnXDErTAZtPVxTYBaYn3n2gbt6F6D2rm1A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.1.1", + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/typescript-estree": "4.1.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.1.tgz", + "integrity": "sha512-NLIhmicpKGfJbdXyQBz9j48PA6hq6e+SDOoXy7Ak6bq1ebGqbgG+fR1UIDAuay6OjQdot69c/URu2uLlsP8GQQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.1.1", + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/typescript-estree": "4.1.1", + "debug": "^4.1.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" + } + }, + "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 + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.1.tgz", + "integrity": "sha512-0W8TTobCvIIQ2FsrYTffyZGAAFUyIbEHq5EYJb1m7Rpd005jrnOvKOo8ywCLhs/Bm17C+KsrUboBvBAARQVvyA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/visitor-keys": "4.1.1" + } + }, + "@typescript-eslint/types": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.1.tgz", + "integrity": "sha512-zrBiqOKYerMTllKcn+BP+i1b7LW/EbMMYytroXMxUTvFPn1smkCu0D7lSAx29fTUO4jnwV0ljSvYQtn2vNrNxA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.1.tgz", + "integrity": "sha512-2AUg5v0liVBsqbGxBphbJ0QbGqSRVaF5qPoTPWcxop+66vMdU1h4CCvHxTC47+Qb+Pr4l2RhXDd41JNpwcQEKw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/visitor-keys": "4.1.1", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.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" + } + }, + "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": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.1.tgz", + "integrity": "sha512-/EOOXbA2ferGLG6RmCHEQ0lTTLkOlXYDgblCmQk3tIU7mTPLm4gKhFMeeUSe+bcchTUsKeCk8xcpbop5Zr/8Rw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.1.1", + "eslint-visitor-keys": "^2.0.0" + } + }, "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", @@ -1459,6 +1705,12 @@ } } }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, "acorn-walk": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", @@ -1500,6 +1752,12 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", @@ -1614,6 +1872,12 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -3321,6 +3585,32 @@ "randombytes": "^2.0.0" } }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "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" + } + }, "dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", @@ -3403,6 +3693,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3484,11 +3783,269 @@ "source-map": "~0.6.1" } }, + "eslint": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.9.0.tgz", + "integrity": "sha512-V6QyhX21+uXp4T+3nrNfI3hQNBDa/P8ga7LoQOenwrlEFXrEnUEE+ok1dMtaS3b6rmLXhT1TkTIsG75HMLbknA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.1.3", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "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" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "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 + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.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 + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", @@ -4158,6 +4715,20 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "fast-json-patch": { "version": "3.0.0-1", "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.0.0-1.tgz", @@ -4176,6 +4747,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -4185,6 +4765,15 @@ "bser": "2.1.1" } }, + "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" + } + }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -4235,6 +4824,34 @@ "locate-path": "^2.0.0" } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -4333,6 +4950,12 @@ "dev": true, "optional": 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", @@ -4539,6 +5162,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "global": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", @@ -4555,6 +5187,20 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -4949,6 +5595,12 @@ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", "dev": true }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, "ignore-walk": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", @@ -4972,6 +5624,24 @@ "queue": "6.0.1" } }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "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-local": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", @@ -5121,6 +5791,12 @@ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -5139,6 +5815,15 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", @@ -6304,6 +6989,12 @@ "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 + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -6764,6 +7455,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -7435,6 +8132,15 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "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-asn1": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", @@ -7775,6 +8481,12 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "promise-nodeify": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/promise-nodeify/-/promise-nodeify-3.0.1.tgz", @@ -8025,6 +8737,12 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -8184,6 +8902,12 @@ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -8218,6 +8942,12 @@ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -8658,6 +9388,49 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -9211,6 +9984,58 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "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 + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "tar": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", @@ -9310,6 +10135,12 @@ "minimatch": "^3.0.4" } }, + "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 + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -9478,6 +10309,21 @@ "yn": "3.1.1" } }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -9716,6 +10562,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, "v8-to-istanbul": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", @@ -10305,6 +11157,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "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": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", diff --git a/package.json b/package.json index 6e3cc138b..4fea08377 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "check-sanity": "ts-node ./script/main/check-sanity", "fix": "ts-node ./script/main/fix", "fix-sanity": "ts-node ./script/main/fix-sanity", - "update": "ts-node ./script/main/update" + "update": "ts-node ./script/main/update", + "lint": "npx eslint . --ext .js,.jsx,.ts,.tsx" }, "repository": { "type": "git", @@ -35,11 +36,14 @@ "@types/jest": "^25.2.3", "@types/jest-expect-message": "^1.0.2", "@types/node": "^13.13.17", + "@typescript-eslint/eslint-plugin": "^4.1.1", + "@typescript-eslint/parser": "^4.1.1", "axios": "^0.19.2", "bip44-constants": "^8.0.49", "bluebird": "^3.7.2", "chalk": "^4.1.0", "danger": "^10.4.0", + "eslint": "^7.9.0", "ethereum-checksum-address": "0.0.6", "eztz-lib": "^0.1.2", "image-size": "^0.8.3", diff --git a/script/action/allowlists.ts b/script/action/allowlists.ts index 4b5cd5202..625a7f278 100644 --- a/script/action/allowlists.ts +++ b/script/action/allowlists.ts @@ -14,11 +14,10 @@ import { import { ActionInterface, CheckStepInterface } from "./interface"; import { formatSortJson } from "../common/json"; import * as bluebird from "bluebird"; -import { copyFile } from "fs"; async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Promise<[boolean, string[], string[]]> { - let errorMsgs: string[] = []; - let warningMsgs: string[] = []; + const errorMsgs: string[] = []; + const warningMsgs: string[] = []; const assets = getChainAssetsList(chain); const allowlistPath = getChainAllowlistPath(chain); diff --git a/script/action/binance.ts b/script/action/binance.ts index 6f5fd44eb..327373e0d 100644 --- a/script/action/binance.ts +++ b/script/action/binance.ts @@ -8,26 +8,27 @@ import { ActionInterface, CheckStepInterface } from "./interface"; import { getChainAssetsPath } from "../common/repo-structure"; import { Binance } from "../common/blockchains"; import { readDirSync } from "../common/filesystem"; +import { readJsonFile } from "../common/json"; import { getChainAssetLogoPath, getChainDenylistPath } from "../common/repo-structure"; -const binanceChain = "binance" +const binanceChain = "binance"; const binanceUrlTokens2 = config.binanceUrlTokens2; const binanceUrlTokens8 = config.binanceUrlTokens8; const binanceUrlTokenAssets = config.binanceUrlTokenAssets; -var cachedAssets = []; +let cachedAssets = []; -async function retrieveBep2AssetList(): Promise { +async function retrieveBep2AssetList(): Promise { console.log(` Retrieving token asset infos from: ${binanceUrlTokenAssets}`); const { assetInfoList } = await axios.get(binanceUrlTokenAssets).then(r => r.data); console.log(` Retrieved ${assetInfoList.length} token asset infos`); return assetInfoList } -async function retrieveAssets(): Promise { +async function retrieveAssets(): Promise { // cache results because of rate limit, used more than once if (cachedAssets.length == 0) { console.log(` Retrieving token infos (${binanceUrlTokens2}, ${binanceUrlTokens8})`); @@ -54,8 +55,8 @@ function fetchImage(url) { } /// Return: array with images to fetch; {asset, assetImg} -export function findImagesToFetch(assetInfoList: any, denylist: string[]): any[] { - let toFetch: any[] = []; +export function findImagesToFetch(assetInfoList: unknown[], denylist: string[]): unknown[] { + const toFetch: unknown[] = []; console.log(`Checking for asset images to be fetched`); assetInfoList.forEach(({asset, assetImg}) => { process.stdout.write(`.${asset} `); @@ -78,9 +79,9 @@ export function findImagesToFetch(assetInfoList: any, denylist: string[]): any[] } -async function fetchMissingImages(toFetch: any[]): Promise { +async function fetchMissingImages(toFetch: unknown[]): Promise { console.log(`Attempting to fetch ${toFetch.length} asset image(s)`); - let fetchedAssets: string[] = []; + const fetchedAssets: string[] = []; await bluebird.each(toFetch, async ({ asset, assetImg }) => { if (assetImg) { const imagePath = getChainAssetLogoPath(binanceChain, asset); @@ -106,7 +107,7 @@ export class BinanceAction implements ActionInterface { { getName: () => { return "Binance chain; assets must exist on chain"}, check: async () => { - var errors = []; + const errors = []; const tokenSymbols = await retrieveAssetSymbols(); const assets = readDirSync(getChainAssetsPath(Binance)); assets.forEach(asset => { @@ -130,7 +131,7 @@ export class BinanceAction implements ActionInterface { async update(): Promise { // retrieve missing token images; BEP2 (bep8 not supported) const bep2InfoList = await retrieveBep2AssetList(); - const denylist: string[] = require(getChainDenylistPath(binanceChain)); + const denylist: string[] = readJsonFile(getChainDenylistPath(binanceChain)) as string[]; const toFetch = findImagesToFetch(bep2InfoList, denylist); const fetchedAssets = await fetchMissingImages(toFetch); diff --git a/script/action/cosmos.ts b/script/action/cosmos.ts index 9ba7bec88..f0aa33758 100644 --- a/script/action/cosmos.ts +++ b/script/action/cosmos.ts @@ -11,7 +11,7 @@ export class CosmosAction implements ActionInterface { { getName: () => { return "Cosmos validator assets must have correct format"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const assets = getChainValidatorsAssets(Cosmos); const prefix = "cosmosvaloper1"; const expLength = 52; diff --git a/script/action/eth-forks.ts b/script/action/eth-forks.ts index 236fc68b0..e78639337 100644 --- a/script/action/eth-forks.ts +++ b/script/action/eth-forks.ts @@ -27,12 +27,12 @@ import * as bluebird from "bluebird"; async function formatInfos() { console.log(`Formatting info files...`); await bluebird.each(ethForkChains, async (chain) => { - let count: number = 0; + let count = 0; const chainAssets = getChainAssetsList(chain); await bluebird.each(chainAssets, async (address) => { if (isChainAssetInfoExistSync(chain, address)) { const chainAssetInfoPath = getChainAssetInfoPath(chain, address); - formatJsonFile(chainAssetInfoPath, true); + formatJsonFile(chainAssetInfoPath); ++count; } }) @@ -69,13 +69,13 @@ export class EthForks implements ActionInterface { getName(): string { return "Ethereum forks"; } getSanityChecks(): CheckStepInterface[] { - var steps: CheckStepInterface[] = []; + const steps: CheckStepInterface[] = []; ethForkChains.forEach(chain => { steps.push( { getName: () => { return `Folder structure for chain ${chain} (ethereum fork)`;}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const assetsFolder = getChainAssetsPath(chain); const assetsList = getChainAssetsList(chain); console.log(` Found ${assetsList.length} assets for chain ${chain}`); diff --git a/script/action/folders-and-files.ts b/script/action/folders-and-files.ts index 28f7244b3..3649a6bd4 100644 --- a/script/action/folders-and-files.ts +++ b/script/action/folders-and-files.ts @@ -29,7 +29,7 @@ export class FoldersFiles implements ActionInterface { { getName: () => { return "Repository root dir"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const dirActualFiles = readDirSync("."); dirActualFiles.forEach(file => { if (!(rootDirAllowedFiles.indexOf(file) >= 0)) { @@ -42,7 +42,7 @@ export class FoldersFiles implements ActionInterface { { getName: () => { return "Chain folders are lowercase, contain only predefined list of files"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; foundChains.forEach(chain => { if (!isLowerCase(chain)) { errors.push(`Chain folder must be in lowercase "${chain}"`); @@ -59,7 +59,7 @@ export class FoldersFiles implements ActionInterface { { getName: () => { return "Chain folders have logo, and correct size"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; await bluebird.each(foundChains, async (chain) => { const chainLogoPath = getChainLogoPath(chain); if (!isPathExistsSync(chainLogoPath)) { @@ -76,7 +76,7 @@ export class FoldersFiles implements ActionInterface { { getName: () => { return "Asset folders contain logo"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; foundChains.forEach(chain => { const assetsPath = getChainAssetsPath(chain); if (isPathExistsSync(assetsPath)) { @@ -94,7 +94,7 @@ export class FoldersFiles implements ActionInterface { { getName: () => { return "Asset folders contain info.json"}, check: async () => { - var warnings: string[] = []; + const warnings: string[] = []; foundChains.forEach(chain => { const assetsPath = getChainAssetsPath(chain); if (isPathExistsSync(assetsPath)) { @@ -112,7 +112,7 @@ export class FoldersFiles implements ActionInterface { { getName: () => { return "Asset folders contain only predefined set of files"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; foundChains.forEach(chain => { const assetsPath = getChainAssetsPath(chain); if (isPathExistsSync(assetsPath)) { diff --git a/script/action/json.ts b/script/action/json.ts index eef56b3bf..8987ff64b 100644 --- a/script/action/json.ts +++ b/script/action/json.ts @@ -12,7 +12,7 @@ export class JsonAction implements ActionInterface { { getName: () => { return "Check all JSON files to have valid content"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const files = [ ...findFiles(chainsPath, 'json'), ]; diff --git a/script/action/kava.ts b/script/action/kava.ts index 1d9fbdf38..c25f67590 100644 --- a/script/action/kava.ts +++ b/script/action/kava.ts @@ -11,7 +11,7 @@ export class KavaAction implements ActionInterface { { getName: () => { return "Kava validator assets must have correct format"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const assets = getChainValidatorsAssets(Kava); const prefix = "kavavaloper1"; const expLength = 50; diff --git a/script/action/logo-size.ts b/script/action/logo-size.ts index 8f022313e..405d2771a 100644 --- a/script/action/logo-size.ts +++ b/script/action/logo-size.ts @@ -18,14 +18,14 @@ import { ActionInterface, CheckStepInterface } from "./interface"; // return name of large logo, or empty async function checkDownsize(chains, checkOnly: boolean): Promise { console.log(`Checking all logos for size ...`); - let totalCountChecked: number = 0; - let totalCountTooLarge: number = 0; - let totalCountUpdated: number = 0; - let largePaths: string[] = []; + let totalCountChecked = 0; + let totalCountTooLarge = 0; + let totalCountUpdated = 0; + const largePaths: string[] = []; await bluebird.map(chains, async chain => { - let countChecked: number = 0; - let countTooLarge: number = 0; - let countUpdated: number = 0; + let countChecked = 0; + let countTooLarge = 0; + let countUpdated = 0; const path = getChainLogoPath(chain); countChecked++; diff --git a/script/action/terra.ts b/script/action/terra.ts index c2312a0bb..e9a65e472 100644 --- a/script/action/terra.ts +++ b/script/action/terra.ts @@ -11,7 +11,7 @@ export class TerraAction implements ActionInterface { { getName: () => { return "Terra validator assets must have correct format"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const assets = getChainValidatorsAssets(Terra); const prefix = "terravaloper1"; const expLength = 51; diff --git a/script/action/tezos.ts b/script/action/tezos.ts index b753e8f83..092aad2a4 100644 --- a/script/action/tezos.ts +++ b/script/action/tezos.ts @@ -57,7 +57,7 @@ async function gen_validators_tezos() { } // Enable baker if has capacity - if (freeSpace > 0 && val.hasOwnProperty("status")) { + if (freeSpace > 0 && Object.prototype.hasOwnProperty.call(val, "status")) { delete val.status } @@ -83,7 +83,7 @@ export class TezosAction implements ActionInterface { { getName: () => { return "Tezos validator assets must have correct format"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const assets = getChainValidatorsAssets(Tezos); assets.forEach(addr => { if (!(eztz.crypto.checkAddress(addr))) { diff --git a/script/action/tron.ts b/script/action/tron.ts index 58b2f92f8..6beb561a3 100644 --- a/script/action/tron.ts +++ b/script/action/tron.ts @@ -25,7 +25,7 @@ export class TronAction implements ActionInterface { { getName: () => { return "Tron assets should be TRC10 or TRC20, logo of correct size"; }, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const path = getChainAssetsPath(Tron); const assets = readDirSync(path); await bluebird.each(assets, async (asset) => { @@ -43,7 +43,7 @@ export class TronAction implements ActionInterface { { getName: () => { return "Tron validator assets must have correct format"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const assets = getChainValidatorsAssets(Tron); assets.forEach(addr => { if (!(isTRC20(addr))) { diff --git a/script/action/update-all.ts b/script/action/update-all.ts index 4142839fd..eddc4405e 100644 --- a/script/action/update-all.ts +++ b/script/action/update-all.ts @@ -35,15 +35,15 @@ const actionList: ActionInterface[] = [ const maxErrosFromOneCheck = 5; async function checkStepList(steps: CheckStepInterface[]): Promise<[string[], string[]]> { - var errorsAll: string[] = []; - var warningsAll: string[] = []; + const errorsAll: string[] = []; + const warningsAll: string[] = []; await bluebird.each(steps, async (step) => { try { //console.log(` Running check step '${step.getName()}'...`); const [errors, warnings] = await step.check(); if (errors && errors.length > 0) { console.log(`- ${chalk.red('X')} '${step.getName()}': ${errors.length} errors`); - var cnt = 0; + let cnt = 0; errors.forEach(err => { if (cnt < maxErrosFromOneCheck) { console.log(` ${chalk.red('X')} '${err}'`); @@ -56,7 +56,7 @@ async function checkStepList(steps: CheckStepInterface[]): Promise<[string[], st } if (warnings && warnings.length > 0) { console.log(`- ${chalk.yellow('!')} '${step.getName()}': ${warnings.length} warnings`); - var cnt = 0; + let cnt = 0; warnings.forEach(warn => { if (cnt < maxErrosFromOneCheck) { console.log(` ${chalk.yellow('!')} '${warn}'`); @@ -80,8 +80,8 @@ async function checkStepList(steps: CheckStepInterface[]): Promise<[string[], st async function sanityCheckByActionList(actions: ActionInterface[]): Promise<[string[], string[]]> { console.log("Running sanity checks..."); - var errors: string[] = []; - var warnings: string[] = []; + const errors: string[] = []; + const warnings: string[] = []; await bluebird.each(actions, async (action) => { try { if (action.getSanityChecks) { @@ -111,8 +111,8 @@ async function sanityCheckByActionList(actions: ActionInterface[]): Promise<[str async function consistencyCheckByActionList(actions: ActionInterface[]): Promise<[string[], string[]]> { console.log("Running consistency checks..."); - var errors: string[] = []; - var warnings: string[] = []; + const errors: string[] = []; + const warnings: string[] = []; await bluebird.each(actions, async (action) => { try { if (action.getConsistencyChecks) { @@ -193,14 +193,14 @@ export async function consistencyCheckAll(): Promise<[string[], string[]]> { return await consistencyCheckByActionList(actionList); } -export async function sanityFixAll() { +export async function sanityFixAll(): Promise { await sanityFixByList(actionList); } -export async function consistencyFixAll() { +export async function consistencyFixAll(): Promise { await consistencyFixByList(actionList); } -export async function updateAll() { +export async function updateAll(): Promise { await updateByList(actionList); } diff --git a/script/action/validators.ts b/script/action/validators.ts index 014576842..c8089e041 100644 --- a/script/action/validators.ts +++ b/script/action/validators.ts @@ -20,7 +20,7 @@ function formatValidators() { } function getChainValidatorsList(chain: string): ValidatorModel[] { - return readJsonFile(getChainValidatorsListPath(chain)); + return readJsonFile(getChainValidatorsListPath(chain)) as ValidatorModel[]; } function isValidatorHasAllKeys(val: ValidatorModel): boolean { @@ -34,7 +34,7 @@ export class Validators implements ActionInterface { getName(): string { return "Validators"; } getSanityChecks(): CheckStepInterface[] { - var steps: CheckStepInterface[] = [ + const steps: CheckStepInterface[] = [ { getName: () => { return "Make sure tests added for new staking chain"}, check: async (): Promise<[string[], string[]]> => { @@ -55,7 +55,7 @@ export class Validators implements ActionInterface { return [[`Not valid Json file at path ${validatorsListPath}`], []]; } - var errors: string[] = []; + const errors: string[] = []; const validatorsList = getChainValidatorsList(chain); const chainValidatorsAssetsList = getChainValidatorsAssets(chain); await bluebird.each(validatorsList, async (val: ValidatorModel) => { diff --git a/script/action/waves.ts b/script/action/waves.ts index 50cd16406..bb78b355d 100644 --- a/script/action/waves.ts +++ b/script/action/waves.ts @@ -18,7 +18,7 @@ export class WavesAction implements ActionInterface { { getName: () => { return "Waves validator assets must have correct format"}, check: async () => { - var errors: string[] = []; + const errors: string[] = []; const assets = getChainValidatorsAssets(Waves); assets.forEach(addr => { if (!(isWavesAddress(addr))) { diff --git a/script/common/asset-info.ts b/script/common/asset-info.ts index eab900daf..0c0c525a3 100644 --- a/script/common/asset-info.ts +++ b/script/common/asset-info.ts @@ -9,7 +9,7 @@ function isAssetInfoHasAllKeys(path: string): [boolean, string] { const info = JSON.parse(readFileSync(path)); const infoKeys = Object.keys(info); - const hasAllKeys = requiredKeys.every(k => info.hasOwnProperty(k)); + const hasAllKeys = requiredKeys.every(k => Object.prototype.hasOwnProperty.call(info, k)); if (!hasAllKeys) { return [false, `Info at path '${path}' missing next key(s): ${arrayDiff(requiredKeys, infoKeys)}`]; diff --git a/script/common/eth-web3.ts b/script/common/eth-web3.ts index ea515e4b7..c6854b333 100644 --- a/script/common/eth-web3.ts +++ b/script/common/eth-web3.ts @@ -1,14 +1,12 @@ import { reverseCase } from "./types"; -const Web3 = require('web3'); - -const web3 = new Web3('ws://localhost:8546'); +const web3 = new (require('web3'))('ws://localhost:8546'); export const isChecksumEthereum = (address: string): boolean => web3.utils.checkAddressChecksum(address); export const toChecksumEthereum = (address: string): string => web3.utils.toChecksumAddress(address); -export function toChecksum(address: string, chain: string = "ethereum"): string { - var checksumEthereum = toChecksumEthereum(address); +export function toChecksum(address: string, chain = "ethereum"): string { + const checksumEthereum = toChecksumEthereum(address); // special handling for Wanchain if (chain.toLowerCase() === "wanchain") { @@ -19,7 +17,7 @@ export function toChecksum(address: string, chain: string = "ethereum"): string return checksumEthereum; } -export function isChecksum(address: string, chain: string = "ethereum"): boolean { +export function isChecksum(address: string, chain = "ethereum"): boolean { // special handling for Wanchain if (chain.toLowerCase() === "wanchain") { const addressEthereum = reverseCase(address).replace("X", "x"); diff --git a/script/common/filesystem.ts b/script/common/filesystem.ts index 33bd4723a..17bf2c722 100644 --- a/script/common/filesystem.ts +++ b/script/common/filesystem.ts @@ -5,8 +5,8 @@ import { execSync } from "child_process"; export const getFileName = (name: string): string => path.basename(name, path.extname(name)) export const getFileExt = (name: string): string => name.slice((Math.max(0, name.lastIndexOf(".")) || Infinity) + 1) -export const readFileSync = (path: string) => fs.readFileSync(path, 'utf8'); -export const writeFileSync = (path: string, data: any) => fs.writeFileSync(path, data); +export const readFileSync = (path: string): string => fs.readFileSync(path, 'utf8'); +export const writeFileSync = (path: string, data: unknown): void => fs.writeFileSync(path, data); export const readDirSync = (path: string): string[] => fs.readdirSync(path); export const isPathExistsSync = (path: string): boolean => fs.existsSync(path); export const getFileSizeInKilobyte = (path: string): number => fs.statSync(path).size / 1000; @@ -20,7 +20,7 @@ function gitMoveCommand(oldName: string, newName: string): string { return `git mv ${oldName} ${newName}-temp && git mv ${newName}-temp ${newName}`; } -export function gitMove(path: string, oldName: string, newName: string) { +export function gitMove(path: string, oldName: string, newName: string): void { console.log(`Renaming file or folder at path ${path}: ${oldName} => ${newName}`); execRename(gitMoveCommand(oldName, newName), path); } @@ -30,7 +30,7 @@ export function findFiles(base: string, ext: string, files: string[] = [], resul result = result || result; files.forEach(file => { - var newbase = path.join(base, file); + const newbase = path.join(base, file); if (fs.statSync(newbase).isDirectory()) { result = findFiles(newbase, ext, fs.readdirSync(newbase), result); } else { diff --git a/script/common/image.ts b/script/common/image.ts index 56505732c..38d1ff04a 100644 --- a/script/common/image.ts +++ b/script/common/image.ts @@ -36,7 +36,7 @@ export function calculateTargetSize(srcWidth: number, srcHeight: number, targetW // check logo dimensions (pixel) and size (kilobytes) export async function isLogoOK(path: string): Promise<[boolean, string]> { - var [isOK, msg] = await isLogoDimensionOK(path); + let [isOK, msg] = await isLogoDimensionOK(path); if (!isOK) { return [false, msg]; } @@ -74,7 +74,7 @@ async function isLogoSizeOK(path: string): Promise<[boolean, string]> { // return if image if too large, and if image has been updated export async function checkResizeIfTooLarge(path: string, checkOnly: boolean): Promise<[boolean, boolean]> { let tooLarge = false; - let updated: boolean = false; + let updated = false; const { width: srcWidth, height: srcHeight } = getImageDimensions(path); diff --git a/script/common/json.ts b/script/common/json.ts index 01e8cdcc1..b7f66b33e 100644 --- a/script/common/json.ts +++ b/script/common/json.ts @@ -2,44 +2,40 @@ import { readFileSync, writeFileSync } from "./filesystem"; -import { sortElements, makeUnique } from "./types"; +import { sortElements } from "./types"; export function isValidJSON(path: string): boolean { try { - let rawdata = readFileSync(path); + const rawdata = readFileSync(path); JSON.parse(rawdata); return true; } catch { + return false; } - return false; } -export function formatJson(content: any) { +export function formatJson(content: unknown): string { return JSON.stringify(content, null, 4); } -export function formatSortJson(content: any) { +export function formatSortJson(content: unknown[]): string { return JSON.stringify(sortElements(content), null, 4); } -export function formatUniqueSortJson(content: any) { - return JSON.stringify(makeUnique(sortElements(content)), null, 4); -} - -export function formatJsonFile(filename: string, silent: boolean = false) { +export function formatJsonFile(filename: string): void { writeFileSync(filename, formatJson(JSON.parse(readFileSync(filename)))); console.log(`Formatted json file ${filename}`); } -export function formatSortJsonFile(filename: string) { +export function formatSortJsonFile(filename: string): void { writeFileSync(filename, formatSortJson(JSON.parse(readFileSync(filename)))); console.log(`Formatted json file ${filename}`); } -export function readJsonFile(path: string): any { +export function readJsonFile(path: string): unknown { return JSON.parse(readFileSync(path)); } -export function writeJsonFile(path: string, data: any) { +export function writeJsonFile(path: string, data: unknown): void { writeFileSync(path, JSON.stringify(data, null, 4)); } diff --git a/script/common/repo-structure.ts b/script/common/repo-structure.ts index d47259453..8ff470433 100644 --- a/script/common/repo-structure.ts +++ b/script/common/repo-structure.ts @@ -28,7 +28,7 @@ export const chainsPath: string = path.join(process.cwd(), '/blockchains'); export const getChainPath = (chain: string): string => `${chainsPath}/${chain}`; export const getChainLogoPath = (chain: string): string => `${getChainPath(chain)}/info/${logoFullName}`; export const getChainAssetsPath = (chain: string): string => `${getChainPath(chain)}/assets`; -export const getChainAssetPath = (chain: string, asset: string) => `${getChainAssetsPath(chain)}/${asset}`; +export const getChainAssetPath = (chain: string, asset: string): string => `${getChainAssetsPath(chain)}/${asset}`; export const getChainAssetLogoPath = (chain: string, asset: string): string => `${getChainAssetPath(chain, asset)}/${logoFullName}`; export const getChainAssetInfoPath = (chain: string, asset: string): string => `${getChainAssetPath(chain, asset)}/${infoFullName}`; export const getChainAllowlistPath = (chain: string): string => `${getChainPath(chain)}/${allowList}`; @@ -40,11 +40,11 @@ export const getChainValidatorsListPath = (chain: string): string => `${getChain export const getChainValidatorsAssetsPath = (chain: string): string => `${getChainValidatorsPath(chain)}/assets` export const getChainValidatorAssetLogoPath = (chain: string, asset: string): string => `${getChainValidatorsAssetsPath(chain)}/${asset}/${logoFullName}` -export const isChainAssetInfoExistSync = (chain: string, address: string) => isPathExistsSync(getChainAssetInfoPath(chain, address)); +export const isChainAssetInfoExistSync = (chain: string, address: string): boolean => isPathExistsSync(getChainAssetInfoPath(chain, address)); -export const getChainFolderFilesList = (chain: string) => readDirSync(getChainPath(chain)) +export const getChainFolderFilesList = (chain: string): string[] => readDirSync(getChainPath(chain)) export const getChainAssetsList = (chain: string): string[] => readDirSync(getChainAssetsPath(chain)); -export const getChainAssetFilesList = (chain: string, address: string) => readDirSync(getChainAssetPath(chain, address)); +export const getChainAssetFilesList = (chain: string, address: string): string[] => readDirSync(getChainAssetPath(chain, address)); export const getChainValidatorsAssets = (chain: string): string[] => readDirSync(getChainValidatorsAssetsPath(chain)); export const rootDirAllowedFiles = config.foldersRootdirAllowedFiles; diff --git a/script/common/types.ts b/script/common/types.ts index 99cb3ff87..01e9b7058 100644 --- a/script/common/types.ts +++ b/script/common/types.ts @@ -1,28 +1,18 @@ export const isLowerCase = (str: string): boolean => str.toLowerCase() === str; export const isUpperCase = (str: string): boolean => str.toUpperCase() === str; -export const mapList = arr => { - return arr.reduce((acm, val) => { - acm[val] = ""; - return acm; - }, {}); -} - -export function mapListTolower(arr: string[]): {} { - return arr.reduce((acm, val) => { - acm[val.toLowerCase()] = ""; - return acm; - }, {}); -} - // Sort: treat numbers as number, strings as case-insensitive -export const sortElements = (arr: any[]): any[] => { +export function sortElements (arr: unknown[]): unknown[] { arr.sort((a, b) => { - if (!isNaN(a) && !isNaN(b)) { + if (typeof a === "number" && typeof b == "number") { // numerical comparison return a - b; } if ((typeof a === 'string' || a instanceof String) && (typeof b === 'string' || b instanceof String)) { + if (!isNaN(Number(a)) && !isNaN(Number(b))) { + // numerical comparison + return Number(a) - Number(b); + } return a.toLowerCase() > b.toLowerCase() ? 1 : -1; } return 0; @@ -30,23 +20,25 @@ export const sortElements = (arr: any[]): any[] => { return arr; } -export const makeUnique = (arr: any[]): any[] => Array.from(new Set(arr)); +export function makeUnique(arr: string[]): string[] { + return Array.from(new Set(arr)); +} // Remove from set A elements of set B. export function arrayDiff(a: string[], b: string[]): string[] { - const mappedB = mapList(b); - return a.filter(e => !mappedB.hasOwnProperty(e)); + const setB = new Set(b); + return a.filter(e => !setB.has(e)); } // Remove from set A elements of set B, case insensitive export function arrayDiffNocase(a: string[], b: string[]): string[] { - const mappedB = mapListTolower(b); - return a.filter(e => !mappedB.hasOwnProperty(e.toLowerCase())); + const setB = new Set(b.map(e => e.toLowerCase())); + return a.filter(e => !setB.has(e.toLowerCase())); } export function findDuplicates(list: string[]): string[] { - let m = new Map(); - let duplicates: string[] = []; + const m = new Map(); + const duplicates: string[] = []; list.forEach(val => { if (m.has(val.toLowerCase())) { duplicates.push(val); @@ -64,7 +56,7 @@ export function findCommonElementsOrDuplicates(list1: string[], list2: string[]) } // Compare two arrays, order does not matter -export function arrayEqual(a1: any[], a2: any[]): boolean { +export function arrayEqual(a1: string[], a2: string[]): boolean { if (a1.length != a2.length) { return false; } @@ -79,8 +71,8 @@ export function arrayEqual(a1: any[], a2: any[]): boolean { export function reverseCase(s: string): string { const n = s.length; - var out: string = ""; - for (var i = 0; i < n; ++i) { + let out = ""; + for (let i = 0; i < n; ++i) { const c = s[i]; if (isLowerCase(c)) { out += c.toUpperCase(); diff --git a/script/config.ts b/script/config.ts index bf7a53d6a..8a7d7c4cd 100644 --- a/script/config.ts +++ b/script/config.ts @@ -1,9 +1,9 @@ -export const imageMaxLogoWidth: number = 512; -export const imageMaxLogoHeight: number = 512; -export const imageMinLogoWidth: number = 64; -export const imageMinLogoHeight: number = 64; -export const imageMaxLogoSizeKb: number = 100; -export const foldersRootdirAllowedFiles: string[] = [".github", "blockchains", "dapps", "media", "node_modules", "script-old", "script", "test", ".gitignore", "azure-pipelines.yml", "jest.config.js", "LICENSE", "package-lock.json", "package.json", "README.md", ".git", "dangerfile.ts", "Gemfile", "Gemfile.lock"]; -export const binanceUrlTokens2: string = "https://dex-atlantic.binance.org/api/v1/tokens?limit=1000"; -export const binanceUrlTokens8: string = "https://dex-atlantic.binance.org/api/v1/mini/tokens?limit=1000"; -export const binanceUrlTokenAssets: string = "https://explorer.binance.org/api/v1/assets?page=1&rows=1000"; +export const imageMaxLogoWidth = 512; +export const imageMaxLogoHeight = 512; +export const imageMinLogoWidth = 64; +export const imageMinLogoHeight = 64; +export const imageMaxLogoSizeKb = 100; +export const foldersRootdirAllowedFiles: string[] = [".github", "blockchains", "dapps", "media", "node_modules", "script-old", "script", "test", ".gitignore", "azure-pipelines.yml", "jest.config.js", "LICENSE", "package-lock.json", "package.json", "README.md", ".git", "dangerfile.ts", "Gemfile", "Gemfile.lock", ".eslintignore", ".eslintrc.js"]; +export const binanceUrlTokens2 = "https://dex-atlantic.binance.org/api/v1/tokens?limit=1000"; +export const binanceUrlTokens8 = "https://dex-atlantic.binance.org/api/v1/mini/tokens?limit=1000"; +export const binanceUrlTokenAssets = "https://explorer.binance.org/api/v1/assets?page=1&rows=1000"; diff --git a/script/main/check-sanity.ts b/script/main/check-sanity.ts index dcf9ce9a6..a8a0047fc 100644 --- a/script/main/check-sanity.ts +++ b/script/main/check-sanity.ts @@ -1,9 +1,9 @@ import { sanityCheckAll } from "../action/update-all"; -export async function main() { +export async function main(): Promise { try { - const [errors, warnings] = await sanityCheckAll(); // warnings ignored + const [errors] = await sanityCheckAll(); process.exit(errors.length); } catch(err) { console.error(err); diff --git a/script/main/check.ts b/script/main/check.ts index af965b5f8..d128df11c 100644 --- a/script/main/check.ts +++ b/script/main/check.ts @@ -1,11 +1,11 @@ import { sanityCheckAll, consistencyCheckAll } from "../action/update-all"; -export async function main() { - var returnCode: number = 0; +export async function main(): Promise { + let returnCode = 0; try { - const [errors1, warnings1] = await sanityCheckAll(); // warnings ignored + const [errors1] = await sanityCheckAll(); if (errors1.length > 0) { returnCode = errors1.length; } @@ -15,8 +15,8 @@ export async function main() { } try { - const [errors1, warnings1] = await consistencyCheckAll(); // warnings ignored + const [errors1] = await consistencyCheckAll(); if (errors1.length > 0) { returnCode = errors1.length; } diff --git a/script/main/fix-sanity.ts b/script/main/fix-sanity.ts index 86168f92d..9e01444cc 100644 --- a/script/main/fix-sanity.ts +++ b/script/main/fix-sanity.ts @@ -1,6 +1,6 @@ -import { sanityFixAll, consistencyFixAll } from "../action/update-all"; +import { sanityFixAll } from "../action/update-all"; -export async function main() { +export async function main(): Promise { try { await sanityFixAll(); } catch(err) { diff --git a/script/main/fix.ts b/script/main/fix.ts index ceda27401..a5e27c43d 100644 --- a/script/main/fix.ts +++ b/script/main/fix.ts @@ -1,6 +1,6 @@ import { sanityFixAll, consistencyFixAll } from "../action/update-all"; -export async function main() { +export async function main(): Promise { try { await sanityFixAll(); } catch(err) { diff --git a/script/main/update.ts b/script/main/update.ts index e5411b181..22c81b03f 100644 --- a/script/main/update.ts +++ b/script/main/update.ts @@ -1,6 +1,6 @@ import { updateAll } from "../action/update-all"; -export async function main() { +export async function main(): Promise { try { await updateAll(); } catch(err) { diff --git a/test/index.test.ts b/test/index.test.ts index 45c2efd6e..f17c42700 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -13,8 +13,6 @@ import { calculateTargetSize } from "../script/common/image"; import { - mapList, - mapListTolower, sortElements, makeUnique, arrayDiff, @@ -74,15 +72,11 @@ describe("Test image helpers", () => { }); describe("Test type helpers", () => { - test(`Test mapList`, () => { - expect(mapList(["a", "b", "c"]), `3 elems`).toEqual({"a": "", "b":"", "c": ""}); - expect(mapList(["a", "b", "C"]), `3 elems`).toEqual({"a": "", "b":"", "C": ""}); - expect(mapListTolower(["a", "b", "C"]), `3 elems`).toEqual({"a": "", "b":"", "c": ""}); - }); test(`Test sortElements`, () => { expect(sortElements(["c", "a", "b"]), `3 elems`).toEqual(["a", "b", "c"]); expect(sortElements(["C", "a", "b"]), `mixed case`).toEqual(["a", "b", "C"]); - expect(sortElements(["1", "2", "11"]), `numerical`).toEqual(["1", "2", "11"]); + expect(sortElements(["1", "2", "11"]), `numerical string`).toEqual(["1", "2", "11"]); + expect(sortElements([1, 2, 11]), `numerical`).toEqual([1, 2, 11]); expect(sortElements(["C", "a", "1", "b", "2", "11"]), `complex`).toEqual(["1", "2", "11", "a", "b", "C"]); }); test(`Test makeUnique`, () => { @@ -124,8 +118,8 @@ describe("Test type helpers", () => { describe("Test action binance", () => { test(`Test findImagesToFetch`, () => { - const assetsInfoListNonexisting: any[] = [{asset: "A1", assetImg: "imgurl1"}, {asset: "A2", assetImg: "imgurl2"}]; - const assetsInfoListExisting: any[] = [{asset: "BUSD-BD1", assetImg: "imgurlBUSD"}, {asset: "ETH-1C9", assetImg: "imgurlETH"}]; + const assetsInfoListNonexisting = [{asset: "A1", assetImg: "imgurl1"}, {asset: "A2", assetImg: "imgurl2"}]; + const assetsInfoListExisting = [{asset: "BUSD-BD1", assetImg: "imgurlBUSD"}, {asset: "ETH-1C9", assetImg: "imgurlETH"}]; const denyListEmpty: string[] = []; const denyListA1: string[] = ["A1"]; expect(findImagesToFetch(assetsInfoListNonexisting, denyListEmpty), `2 nonexisting`).toEqual(assetsInfoListNonexisting);