diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..3d0a9346 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +resources +openapi diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..31d47702 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "@openstapps" +} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a1fd300c..01fe61a5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,6 +3,10 @@ image: registry.gitlab.com/openstapps/projectmanagement/node before_script: - npm ci +default: + tags: + - performance + stages: - build - test @@ -39,7 +43,7 @@ docker image builder: - docker build -t registry.gitlab.com/openstapps/projectmanagement/builder -f images/builder/Dockerfile . - docker push registry.gitlab.com/openstapps/projectmanagement/builder tags: - - docker + - secrecy docker image node: image: registry.gitlab.com/openstapps/projectmanagement/builder @@ -56,7 +60,7 @@ docker image node: - docker build -t registry.gitlab.com/openstapps/projectmanagement/node -f images/node/Dockerfile images/node - docker push registry.gitlab.com/openstapps/projectmanagement/node tags: - - docker + - secrecy npm audit: allow_failure: true @@ -119,7 +123,7 @@ pages: paths: - public -package: +npm package: dependencies: - npm build tags: @@ -166,7 +170,7 @@ renovate: variables: - $RENOVATE == "true" tags: - - gitlab-org-docker + - secrecy artifacts: when: always expire_in: 1d diff --git a/package-lock.json b/package-lock.json index 598c523a..76faa0a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,27 +24,27 @@ } }, "@babel/compat-data": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.6.tgz", - "integrity": "sha512-tzulrgDT0QD6U7BJ4TKVk2SDDg7wlP39P9yAx1RfLy7vP/7rsDRlWVfbWxElslu56+r7QOhB2NSDsabYYruoZQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", + "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", "dev": true }, "@babel/core": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.6.tgz", - "integrity": "sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.6", - "@babel/helper-compilation-targets": "^7.18.6", - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helpers": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -61,12 +61,12 @@ } }, "@babel/generator": { - "version": "7.18.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.7.tgz", - "integrity": "sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", + "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", "dev": true, "requires": { - "@babel/types": "^7.18.7", + "@babel/types": "^7.19.3", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -85,14 +85,14 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz", - "integrity": "sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "requires": { - "@babel/compat-data": "^7.18.6", + "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "dependencies": { @@ -105,19 +105,19 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.6.tgz", - "integrity": "sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true }, "@babel/helper-function-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.6.tgz", - "integrity": "sha512-0mWMxV1aC97dhjCah5U5Ua7668r5ZmSC2DLfH2EZnf9c3/dHZKiFa5pRLMH5tjSl471tY6496ZWk/kjNONBxhw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "requires": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { @@ -139,19 +139,19 @@ } }, "@babel/helper-module-transforms": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.6.tgz", - "integrity": "sha512-L//phhB4al5uucwzlimruukHB3jRd5JGClwRMD/ROrVjXfLqovYnvQrK/JK36WYyVwGGO7OD3kMyVTjx+WVPhw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-simple-access": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" } }, "@babel/helper-simple-access": { @@ -172,10 +172,16 @@ "@babel/types": "^7.18.6" } }, + "@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/helper-validator-option": { @@ -185,14 +191,14 @@ "dev": true }, "@babel/helpers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.6.tgz", - "integrity": "sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", + "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", "dev": true, "requires": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" } }, "@babel/highlight": { @@ -259,47 +265,56 @@ } }, "@babel/parser": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.6.tgz", - "integrity": "sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", + "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", "dev": true }, "@babel/template": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz", - "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6" + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.6.tgz", - "integrity": "sha512-zS/OKyqmD7lslOtFqbscH6gMLFYOfG1YPqCKfAW5KrTeolKqvB8UelR49Fpr6y93kYkW2Ik00mT1LOGiAGvizw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", + "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.6", - "@babel/helper-function-name": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.6", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, "@babel/types": { - "version": "7.18.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.7.tgz", - "integrity": "sha512-QG3yxTcTIBoAcQmkCs+wAPYZhu7Dk9rXKacINfNbdJDNERTbLQbHGyVG8q/YGMPeCJRIhSY0+fTc5+xuh6WPSQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", + "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -324,6 +339,105 @@ } } }, + "@es-joy/jsdoccomment": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", + "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", + "dev": true, + "requires": { + "comment-parser": "1.3.1", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "~3.1.0" + } + }, + "@eslint/eslintrc": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "brace-expansion": { + "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" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "brace-expansion": { + "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" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, "@hutson/parse-repository-url": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", @@ -341,6 +455,33 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, "@istanbuljs/schema": { @@ -360,9 +501,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.8.tgz", - "integrity": "sha512-YK5G9LaddzGbcucK4c8h5tWFmMPBvRZ/uyWmN1/SbBdIvqGUdWGkJ5BAaccgs6XbzVLsqbPJrBSFwKv3kT9i7w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, "@jridgewell/set-array": { @@ -378,9 +519,9 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", - "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -392,27 +533,51 @@ "resolved": "https://registry.npmjs.org/@krlwlfrt/async-pool/-/async-pool-0.4.1.tgz", "integrity": "sha512-mSLEhCiL6jvWuF5vtBUFzMlgvwt1Tte4io7A3B2slClFBVsajmonDV1qk2myq5EQvNy3g5KkN2QNSLoCE4r8og==" }, - "@openstapps/configuration": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/@openstapps/configuration/-/configuration-0.29.1.tgz", - "integrity": "sha512-H6DNB1HrujC5LwOF17rYkXQPFaEWTaA5T3IPsfccSuKHSUhB0ry6V5OkMwmvls2nOSrbpuRpyQoM7ulwZ9X9Bw==", + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@types/node": "14.18.18", - "@types/semver": "7.3.9", + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@openstapps/configuration": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@openstapps/configuration/-/configuration-0.33.0.tgz", + "integrity": "sha512-sum9DB8+2r5eXnJhie1UPcQQTPupd0m3Xgsft+D6LVvbjbmt/XCpCMvlZSoM+LE1ZkUdgUmbFJ81mqjWKgCsJA==", + "dev": true, + "requires": { + "@types/node": "14.18.24", + "@types/semver": "7.3.12", "@types/yaml": "1.9.7", "chalk": "4.1.2", - "commander": "9.2.0", + "commander": "9.4.0", "semver": "7.3.7", - "tslint": "6.1.3", - "tslint-eslint-rules": "5.4.0", "yaml": "1.10.2" }, "dependencies": { "@types/node": { - "version": "14.18.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", - "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==", + "version": "14.18.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.24.tgz", + "integrity": "sha512-aJdn8XErcSrfr7k8ZDDfU6/2OgjZcB2Fu9d+ESK8D7Oa5mtsv8Fa8GpcwTA0v60kuZBaalKPzuzun4Ov1YWO/w==", "dev": true }, "chalk": { @@ -426,13 +591,19 @@ } }, "commander": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz", - "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", + "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", "dev": true } } }, + "@openstapps/eslint-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@openstapps/eslint-config/-/eslint-config-1.1.0.tgz", + "integrity": "sha512-yhSWgzKB5cU3kTtWdAOEO6y4PjLDBnyJc+Dpmz9Rxg97WSViOiz3Bv9BWTSl0TR56GAnFi0NI8K56RfCqjpk5w==", + "dev": true + }, "@openstapps/gitlab-api": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@openstapps/gitlab-api/-/gitlab-api-0.9.0.tgz", @@ -486,27 +657,27 @@ } }, "@openstapps/logger": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@openstapps/logger/-/logger-0.8.1.tgz", - "integrity": "sha512-Ain5Hb1f0EjhwhiHfv1PhDaNm7f1LUeuoO8Orll6f1icF5VI+R1PKcxk+Z1rO/WVElFNoP+PORD0vB7wDE4xAQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@openstapps/logger/-/logger-1.0.0.tgz", + "integrity": "sha512-ImCfnLJWHWwFJ1W7KCIWgFe7EXI0cAtap0Dznz+758BPAlLZ+hJHSbIbGHWwEAfRNAB53TIABF5npSsKSDq4Sw==", "requires": { - "@types/node": "14.18.18", - "@types/nodemailer": "6.4.4", + "@types/node": "14.18.24", + "@types/nodemailer": "6.4.5", "chalk": "4.1.2", - "flatted": "3.2.5", - "moment": "2.29.3", - "nodemailer": "6.7.5" + "flatted": "3.2.6", + "moment": "2.29.4", + "nodemailer": "6.7.8" }, "dependencies": { "@types/node": { - "version": "14.18.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.18.tgz", - "integrity": "sha512-B9EoJFjhqcQ9OmQrNorItO+OwEOORNn3S31WuiHvZY/dm9ajkB7AKD/8toessEtHHNL+58jofbq7hMMY9v4yig==" + "version": "14.18.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.24.tgz", + "integrity": "sha512-aJdn8XErcSrfr7k8ZDDfU6/2OgjZcB2Fu9d+ESK8D7Oa5mtsv8Fa8GpcwTA0v60kuZBaalKPzuzun4Ov1YWO/w==" }, "@types/nodemailer": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.4.tgz", - "integrity": "sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==", + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.5.tgz", + "integrity": "sha512-zuP3nBRQHI6M2PkXnGGy1Ww4VB+MyYHGgnfV2T+JR9KLkeWqPJuyVUgLpKXuFnA/b7pZaIDFh2sV4759B7jK1g==", "requires": { "@types/node": "*" } @@ -521,14 +692,14 @@ } }, "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", + "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==" }, "nodemailer": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.5.tgz", - "integrity": "sha512-6VtMpwhsrixq1HDYSBBHvW0GwiWawE75dS3oal48VqRhUvKJNnKnJo2RI/bCVQubj1vgrgscMNW4DHaD6xtMCg==" + "version": "6.7.8", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.8.tgz", + "integrity": "sha512-2zaTFGqZixVmTxpJRCFC+Vk5eGRd/fYtvIR+dl5u9QXLTQWGIf48x/JXvo58g9sa0bU6To04XUv554Paykum3g==" } } }, @@ -620,18 +791,18 @@ } }, "@testdeck/core": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@testdeck/core/-/core-0.2.0.tgz", - "integrity": "sha512-2BAzKS18I+nFUb9kH2zK7Bs1CBD0WqaYikaLm+gRaOiQKYa8flvVzqlUGwjyOMmD16JFksgxYml4/7xm4tfEYA==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@testdeck/core/-/core-0.2.1.tgz", + "integrity": "sha512-eMO5LKxCN8/fST2RTrxo6+1rmwT4ZGN3giwaEeD94d8o4FoHk5Xp1SWGZeqYu/M8jfHpCN2MTKQO9viIBPVBAQ==", "dev": true }, "@testdeck/mocha": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@testdeck/mocha/-/mocha-0.2.0.tgz", - "integrity": "sha512-xudmoPiytaV3flmPZnRO02TPsH31IJuLkGGIX9ftOmditOgA57RK9tYDHNpanA9HxC6kQLP97Tut0RfILENn7w==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@testdeck/mocha/-/mocha-0.2.1.tgz", + "integrity": "sha512-8sC4spvA8hlpMIPweohvJ5fBH31TonXuF2X2YTa7NV99BPkvM6GRchyAjOtYgdqVfIwolio5C7iP+gDH/dss4A==", "dev": true, "requires": { - "@testdeck/core": "^0.2.0" + "@testdeck/core": "^0.2.1" } }, "@tsconfig/node10": { @@ -664,9 +835,9 @@ "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" }, "@types/chai": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", - "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "@types/chai-as-promised": { @@ -695,10 +866,16 @@ "@types/node": "*" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" }, "@types/minimist": { "version": "1.2.2", @@ -707,15 +884,15 @@ "dev": true }, "@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-rADY+HtTOA52l9VZWtgQfn4p+UDVM2eDVkMZT1I6syp0YKxW2F9v+0pbRZLsvskhQv/vMb6ZfCay81GHbz5SHg==", "dev": true }, "@types/mustache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.1.3.tgz", - "integrity": "sha512-Bc3wzdDGfHE8kcf6HsDwqq/IDUginRlWLHbs8dYFAo/2jj91lip6/XJFgKvcCbFO6aEVpOBT1RGF72LZgNIbKQ==" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.2.1.tgz", + "integrity": "sha512-gFAlWL9Ik21nJioqjlGCnNYbf9zHi0sVbaZ/1hQEBcCEuxfLJDvz4bVJSV6v6CUaoLOz0XEIoP7mSrhJ6o237w==" }, "@types/node": { "version": "14.18.21", @@ -766,9 +943,9 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, "@types/semver": { - "version": "7.3.9", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", - "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", + "version": "7.3.12", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", + "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", "dev": true }, "@types/tmp": { @@ -798,6 +975,101 @@ "yaml": "*" } }, + "@typescript-eslint/eslint-plugin": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz", + "integrity": "sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.39.0", + "@typescript-eslint/type-utils": "5.39.0", + "@typescript-eslint/utils": "5.39.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.39.0.tgz", + "integrity": "sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.39.0", + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/typescript-estree": "5.39.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz", + "integrity": "sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/visitor-keys": "5.39.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz", + "integrity": "sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.39.0", + "@typescript-eslint/utils": "5.39.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz", + "integrity": "sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz", + "integrity": "sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/visitor-keys": "5.39.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz", + "integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.39.0", + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/typescript-estree": "5.39.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz", + "integrity": "sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.39.0", + "eslint-visitor-keys": "^3.3.0" + } + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -815,9 +1087,15 @@ } }, "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true }, "acorn-walk": { @@ -905,13 +1183,10 @@ "dev": true }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-ify": { "version": "1.0.0", @@ -919,6 +1194,12 @@ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "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 + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -1015,21 +1296,21 @@ "dev": true }, "browserslist": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.1.tgz", - "integrity": "sha512-Nq8MFCSrnJXSc88yliwlzQe3qNe3VntIjhsArW9IJOEPSHNx23FalwApUVbzAWABLhYJJ7y8AynWI/XM8OdfjQ==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001359", - "electron-to-chromium": "^1.4.172", - "node-releases": "^2.0.5", - "update-browserslist-db": "^1.0.4" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, "caching-transform": { @@ -1044,6 +1325,12 @@ "write-file-atomic": "^3.0.0" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -1062,9 +1349,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001363", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001363.tgz", - "integrity": "sha512-HpQhpzTGGPVMnCjIomjt+jvyUu8vNFo3TaDiZ/RcoTrlOq/5+tC8zHdsbgFB6MxmaY+jCpsH09aD80Bb4Ow3Sg==", + "version": "1.0.30001418", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", + "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", "dev": true }, "caseless": { @@ -1127,6 +1414,21 @@ "readdirp": "~3.6.0" } }, + "ci-info": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", + "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", + "dev": true + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -1166,9 +1468,15 @@ } }, "commander": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz", - "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==" + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==" + }, + "comment-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "dev": true }, "commondir": { "version": "1.0.1", @@ -1445,20 +1753,12 @@ "dev": true }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" - }, - "dependencies": { - "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 - } } }, "decamelize": { @@ -1494,6 +1794,12 @@ "type-detect": "^4.0.0" } }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "default-require-extensions": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", @@ -1517,19 +1823,27 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, - "doctrine": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", - "integrity": "sha512-qiB/Rir6Un6Ad/TIgTRzsremsTGWzs8j7woXvp14jgq00676uBiBT5eUOi+FgRywZFVy5Us/c04ISRpZhRbS6w==", + "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": { - "esutils": "^1.1.6", - "isarray": "0.0.1" + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" } }, "dot-prop": { @@ -1551,9 +1865,9 @@ } }, "electron-to-chromium": { - "version": "1.4.178", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.178.tgz", - "integrity": "sha512-aWuhJXkwIdoQzGR8p2QvR3N0OzdUKZSP8+P/hzuMzNQIPZoEa8HiCGM75bQBHjyz+eKT5PB9dVCzkK/tyQ4B5Q==", + "version": "1.4.275", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.275.tgz", + "integrity": "sha512-aJeQQ+Hl9Jyyzv4chBqYJwmVRY46N5i2BEX5Cuyk/5gFCUZ5F3i7Hnba6snZftWla7Gglwc5pIgcd+E7cW+rPg==", "dev": true }, "emoji-regex": { @@ -1589,16 +1903,361 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, + "eslint": { + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.2", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "brace-expansion": { + "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" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true + }, + "eslint-plugin-jsdoc": { + "version": "39.3.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.6.tgz", + "integrity": "sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==", + "dev": true, + "requires": { + "@es-joy/jsdoccomment": "~0.31.0", + "comment-parser": "1.3.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.4.0", + "semver": "^7.3.7", + "spdx-expression-parse": "^3.0.1" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-unicorn": { + "version": "44.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.2.tgz", + "integrity": "sha512-GLIDX1wmeEqpGaKcnMcqRvMVsoabeF0Ton0EX4Th5u6Kmf7RM9WBl705AXFEsns56ESkEs0uyelLuUTvz9Tr0w==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.19.1", + "ci-info": "^3.4.0", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.7", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "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.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha512-RG1ZkUT7iFJG9LSHr7KDuuMSlujfeTtMNIcInURxKAxhMtwQhI3NrQhz26gZQYlsYZQKzsnwtpKrFKj9K9Qu1A==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "eventemitter3": { @@ -1621,11 +2280,54 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1667,15 +2369,25 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, "flatted": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" }, "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, "foreground-child": { "version": "2.0.0", @@ -1762,12 +2474,6 @@ "yargs": "^16.2.0" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -1890,10 +2596,35 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } }, "graceful-fs": { "version": "4.2.10", @@ -1901,10 +2632,10 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, "handlebars": { @@ -2009,6 +2740,22 @@ "sshpk": "^1.7.0" } }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2056,10 +2803,19 @@ "binary-extensions": "^2.0.0" } }, + "is-builtin-module": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", + "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "requires": { "has": "^1.0.3" @@ -2136,9 +2892,9 @@ "dev": true }, "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "isexe": { @@ -2232,15 +2988,21 @@ } }, "istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2248,13 +3010,12 @@ "dev": true }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "jsbn": { @@ -2262,6 +3023,12 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, + "jsdoc-type-pratt-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", + "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "dev": true + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -2290,6 +3057,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -2302,9 +3075,9 @@ "dev": true }, "jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, "jsonparse": { @@ -2330,6 +3103,16 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "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" + } + }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -2392,6 +3175,12 @@ "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -2456,9 +3245,9 @@ "dev": true }, "marked": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.17.tgz", - "integrity": "sha512-Wfk0ATOK5iPxM4ptrORkFemqroz0ZDxp5MWfYA7H/F+wO17NRWV5Ypxi6p3g2Xmw2bKeiYOl6oVnLHKxBA0VhA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", + "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", "dev": true }, "meow": { @@ -2545,6 +3334,22 @@ } } }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -2599,43 +3404,35 @@ } }, "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", - "debug": "4.3.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", - "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", - "minimatch": "4.2.1", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.1", + "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2646,12 +3443,6 @@ "concat-map": "0.0.1" } }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -2693,15 +3484,6 @@ } } }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2712,14 +3494,31 @@ } }, "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + } } }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2762,14 +3561,14 @@ "dev": true }, "moment": { - "version": "2.29.3", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz", - "integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==" + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "mustache": { @@ -2778,9 +3577,15 @@ "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==" }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "neo-async": { @@ -2799,9 +3604,9 @@ } }, "node-releases": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", - "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "nodemailer": { @@ -2906,6 +3711,12 @@ "brace-expansion": "^1.1.7" } }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -2967,6 +3778,20 @@ "wrappy": "1" } }, + "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" + } + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -3050,6 +3875,15 @@ "release-zalgo": "^1.0.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -3086,21 +3920,10 @@ "dev": true }, "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - } - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "pathval": { "version": "1.1.1", @@ -3140,6 +3963,18 @@ "find-up": "^4.0.0" } }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "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 + }, "prepend-file": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/prepend-file/-/prepend-file-1.3.1.tgz", @@ -3170,6 +4005,21 @@ "prepend-file": "1.3.1" } }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -3206,6 +4056,12 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -3250,6 +4106,21 @@ "validate-npm-package-license": "^3.0.1" } }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -3349,6 +4220,18 @@ "strip-indent": "^3.0.0" } }, + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -3439,9 +4322,9 @@ } }, "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "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 }, "retry": { @@ -3449,6 +4332,12 @@ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" }, + "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", @@ -3489,11 +4378,29 @@ } } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -3555,6 +4462,12 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3602,9 +4515,9 @@ } }, "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, "split": { @@ -3784,6 +4697,12 @@ "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -3838,9 +4757,9 @@ "dev": true }, "ts-node": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.2.tgz", - "integrity": "sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -3856,6 +4775,14 @@ "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } } }, "tslib": { @@ -3894,6 +4821,15 @@ "color-convert": "^1.9.0" } }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3904,6 +4840,12 @@ "concat-map": "0.0.1" } }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -3936,6 +4878,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3956,6 +4904,16 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3979,30 +4937,11 @@ "requires": { "has-flag": "^3.0.0" } - } - } - }, - "tslint-eslint-rules": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz", - "integrity": "sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==", - "dev": true, - "requires": { - "doctrine": "0.7.2", - "tslib": "1.9.0", - "tsutils": "^3.0.0" - }, - "dependencies": { - "tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", - "dev": true }, "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -4011,9 +4950,9 @@ } }, "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -4032,6 +4971,15 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, + "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" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -4073,16 +5021,16 @@ "dev": true }, "uglify-js": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.2.tgz", - "integrity": "sha512-AaQNokTNgExWrkEYA24BTNMSjyqEXPSfhqoS0AxmHkCJ4U+Dyy5AvbGV/sqxuxficEfGGoX3zWw9R7QpLFfEsg==", + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz", + "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==", "dev": true, "optional": true }, "update-browserslist-db": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz", - "integrity": "sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "requires": { "escalade": "^3.1.1", @@ -4161,6 +5109,12 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -4168,9 +5122,9 @@ "dev": true }, "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { diff --git a/package.json b/package.json index 64660a00..5833654e 100644 --- a/package.json +++ b/package.json @@ -7,17 +7,17 @@ "url": "git@gitlab.com:openstapps/projectmanagement.git" }, "scripts": { - "build": "npm run tslint && npm run compile", + "build": "npm run lint && npm run compile", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'", "check-configuration": "openstapps-configuration", "compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'", "documentation": "typedoc --out docs --readme README.md --listInvalidSymbolLinks --entryPointStrategy expand src", "postversion": "npm run changelog", - "prepublishOnly": "npm ci && npm run build", + "prepublishOnly": "npm ci && npm run build && npm run test", "preversion": "npm run prepublishOnly", "push": "git push && git push origin \"v$npm_package_version\"", "test": "nyc mocha --require ts-node/register 'test/**/*.spec.ts'", - "tslint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts'" + "lint": "eslint --ext .ts src/" }, "author": "Karl-Philipp Wulfert ", "contributors": [ @@ -31,32 +31,41 @@ "dependencies": { "@krlwlfrt/async-pool": "0.4.1", "@openstapps/gitlab-api": "0.9.0", - "@openstapps/logger": "0.8.1", + "@openstapps/logger": "1.0.0", "@slack/client": "5.0.2", "@types/glob": "7.2.0", - "@types/mustache": "4.1.3", + "@types/mustache": "4.2.1", "@types/node": "14.18.21", "@types/tmp": "0.2.3", - "commander": "9.3.0", + "commander": "9.4.1", "glob": "8.0.3", - "moment": "2.29.3", + "moment": "2.29.4", "mustache": "4.2.0", "tmp": "0.2.1" }, "devDependencies": { - "@openstapps/configuration": "0.29.1", - "@testdeck/mocha": "0.2.0", - "@types/chai": "4.3.1", + "@openstapps/configuration": "0.33.0", + "@openstapps/eslint-config": "1.1.0", + "@testdeck/mocha": "0.2.1", + "@types/chai": "4.3.3", "@types/chai-as-promised": "7.1.5", - "@types/mocha": "9.1.1", + "@types/mocha": "10.0.0", + "@typescript-eslint/eslint-plugin": "5.39.0", + "@typescript-eslint/parser": "5.39.0", "chai": "4.3.6", "chai-as-promised": "7.1.1", "conventional-changelog-cli": "2.2.2", - "mocha": "9.2.2", + "eslint": "8.24.0", + "eslint-config-prettier": "8.5.0", + "eslint-plugin-jsdoc": "39.3.6", + "eslint-plugin-prettier": "4.2.1", + "eslint-plugin-unicorn": "44.0.2", + "mocha": "10.0.0", "nyc": "15.1.0", "prepend-file-cli": "1.0.6", + "prettier": "2.7.1", "rimraf": "3.0.2", - "ts-node": "10.8.2", + "ts-node": "10.9.1", "tslint": "6.1.3", "typedoc": "0.22.17", "typescript": "4.4.4" diff --git a/renovate.json b/renovate.json index afb94f53..aef4c91d 100644 --- a/renovate.json +++ b/renovate.json @@ -53,7 +53,6 @@ "reviewers": [ "abcdev", "jovankrunic", - "FrankNagel", "theaninova" ] } diff --git a/src/cli.ts b/src/cli.ts index 3f7ed521..6536fbb5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 StApps + * Copyright (C) 2019-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -18,7 +18,7 @@ import {AddLogLevel} from '@openstapps/logger/lib/transformations/add-log-level' import {Colorize} from '@openstapps/logger/lib/transformations/colorize'; import {Command} from 'commander'; import {existsSync, readFileSync} from 'fs'; -import {join, resolve} from 'path'; +import path from 'path'; import {cwd, stdout} from 'process'; import {GITLAB_API_URL} from './configuration'; import {getUsedVersionMajorMinor} from './tasks/get-used-version'; @@ -27,12 +27,10 @@ import {tidy} from './tasks/tidy'; import {unlabel} from './tasks/unlabel'; // add default handler for unhandled rejections -process.on('unhandledRejection', async (reason) => { - if (reason instanceof Error) { - await Logger.error('Unhandled rejection', reason.stack); - } else { - await Logger.error('Unhandled rejection', reason); - } +process.on('unhandledRejection', async reason => { + await (reason instanceof Error + ? Logger.error('Unhandled rejection', reason.stack) + : Logger.error('Unhandled rejection', reason)); process.exit(1); }); @@ -42,54 +40,46 @@ const commander = new Command('openstapps-projectmanagement'); // error on unknown commands commander.on('command:*', async () => { - await Logger.error('Invalid command: %s\nSee --help for a list of available commands.', commander.args.join(' ')); + await Logger.error( + 'Invalid command: %s\nSee --help for a list of available commands.', + commander.args.join(' '), + ); process.exit(1); }); const gitlabApi = new Api(GITLAB_API_URL, process.env.GITLAB_PRIVATE_TOKEN as string); -Logger.setTransformations([ - new AddLogLevel(), - new Colorize(), -]); +Logger.setTransformations([new AddLogLevel(), new Colorize()]); -if (existsSync(join(__dirname, 'package.json'))) { - commander.version(JSON.parse(readFileSync(join(__dirname, '..', 'package.json')) - .toString()).version); +// eslint-disable-next-line unicorn/prefer-module +if (existsSync(path.join(__dirname, 'package.json'))) { + // eslint-disable-next-line unicorn/prefer-module + commander.version(JSON.parse(readFileSync(path.join(__dirname, '..', 'package.json')).toString()).version); } -commander - .command('unlabel') - .action(async () => { - await unlabel(gitlabApi); - Logger.ok('Done!'); - }); +commander.command('unlabel').action(async () => { + await unlabel(gitlabApi); + Logger.ok('Done!'); +}); -commander - .command('tidy') - .action(async () => { - await tidy(gitlabApi); - Logger.ok('Done!'); - }); +commander.command('tidy').action(async () => { + await tidy(gitlabApi); + Logger.ok('Done!'); +}); -commander - .command('remind') - .action(async () => { - await remind(gitlabApi); - Logger.ok('Done!'); - }); +commander.command('remind').action(async () => { + await remind(gitlabApi); + Logger.ok('Done!'); +}); -commander - .command('get-used-version [path]') - .action(async (dependency, path) => { - let fallbackPath = cwd(); - if (typeof path === 'string' && path.length > 0) { - fallbackPath = resolve(path); - } +commander.command('get-used-version [path]').action(async (dependency, filePath) => { + let fallbackPath = cwd(); + if (typeof filePath === 'string' && filePath.length > 0) { + fallbackPath = path.resolve(filePath); + } - stdout.write(await getUsedVersionMajorMinor(fallbackPath, dependency)); - }); + stdout.write(await getUsedVersionMajorMinor(fallbackPath, dependency)); +}); -commander - .parse(process.argv); +commander.parse(process.argv); diff --git a/src/common.ts b/src/common.ts index daf9ff30..310c2da8 100644 --- a/src/common.ts +++ b/src/common.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2019 StApps + * Copyright (C) 2018-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -39,7 +39,7 @@ export const writeFilePromisified = promisify(writeFile); export async function getProjects(api: Api, groups: number[]): Promise { Logger.info(`Fetching all projects for specified groups (${groups.length})...`); - const projectResults = await asyncPool(CONCURRENCY, groups, async (groupId) => { + const projectResults = await asyncPool(CONCURRENCY, groups, async groupId => { return api.getProjectsForGroup(groupId); }); @@ -57,16 +57,19 @@ export async function getProjects(api: Api, groups: number[]): Promise { - return flatten2dArray(await asyncPool(CONCURRENCY, groups, async (groupId) => { - return api.getSubGroupsForGroup(groupId); - })); + return flatten2dArray( + await asyncPool(CONCURRENCY, groups, async groupId => { + return api.getSubGroupsForGroup(groupId); + }), + ); } /** * Flatten 2d array * - * @param arr Flattened array + * @param array Flattened array */ -export function flatten2dArray(arr: T[][]): T[] { - return ([] as T[]).concat(...arr); +export function flatten2dArray(array: T[][]): T[] { + // eslint-disable-next-line unicorn/prefer-spread + return ([] as T[]).concat(...array); } diff --git a/src/configuration.ts b/src/configuration.ts index edf9a6d7..5b6e4776 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2019 StApps + * Copyright (C) 2018-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -18,38 +18,35 @@ import moment from 'moment'; /** * List of schools with their IDs */ -export const SCHOOLS: { [school: string]: number; } = {}; +export const SCHOOLS: {[school: string]: number} = {}; /** * ID OF openstapps main group */ -const STAPPS_GROUP_ID = 4088298; +const STAPPS_GROUP_ID = 4_088_298; /** * List of group IDs to fetch issues for */ -export const GROUPS: number[] = [STAPPS_GROUP_ID] - .concat(Object.keys(SCHOOLS) - .map((school) => { - return SCHOOLS[school]; - }), - ); +export const GROUPS: number[] = [ + STAPPS_GROUP_ID, + ...Object.keys(SCHOOLS).map(school => { + return SCHOOLS[school]; + }), +]; /** * */ -export const LABEL_WEIGHTS: { [key: string]: number; } = { - 'bug': 1, - 'critical': 2, +export const LABEL_WEIGHTS: {[key: string]: number} = { + bug: 1, + critical: 2, }; /** * List of labels to print bold in report */ -export const BOLD_LABELS: string[] = [ - 'bug', - 'critical', -]; +export const BOLD_LABELS: string[] = ['bug', 'critical']; /** * GitLab API URL @@ -59,124 +56,122 @@ export const GITLAB_API_URL = 'https://gitlab.com/api/v4/'; /** * Milestones to add to projects */ -export const NEEDED_MILESTONES = [ - 'Backlog', -]; +export const NEEDED_MILESTONES = ['Backlog']; /** * Protected branches */ -export const PROTECTED_BRANCHES = [ - 'develop', - 'master', -]; +export const PROTECTED_BRANCHES = ['develop', 'master']; /** * Labels to add to all projects */ -export const NEEDED_LABELS: Label[] = [{ - color: '#FF0000', - description: 'An error/something that is not working as expected', - name: 'bug', -}, - { - color: '#5CB85C', - name: 'consistency', - }, - { - color: '#FF0000', - name: 'confirmed', - }, - { - color: '#FF0000', - description: 'A blocking issue/something that needs to be fixed ASAP', - name: 'critical', - }, - { - color: '#428BCA', - name: 'design', - }, - { - color: '#0033CC', - description: 'An issue about the documentation of the software', - name: 'documentation', - }, - { - color: '#5CB85C', - name: 'Doing', - }, - { - color: '#5CB85C', - description: 'A feature proposal/something that will be developed', - name: 'feature', - }, - { - color: '#7F8C8D', - description: 'An issue that is unimportant or invalid', - name: 'invalid', - }, - { - color: '#FFFF88', - name: 'meeting', - }, - { - color: '#8E44AD', - name: 'organization', - }, - { - color: '#FF0000', - description: 'An issue with the performance of the software', - name: 'performance', - }, - { - color: '#69D100', - name: 'refactoring', - }, - { - color: '#FF0000', - description: 'An issue with the security of the software', - name: 'security', - }, - { - color: '#D1D100', - description: 'An issue about the testing procedure of the software', - name: 'testing', - }, - { - color: '#F0AD4E', - name: 'To Do', - }, - { - color: '#A8D695', - description: 'An issue with low priority', - name: 'unimportant', - }, - { - color: '#D10069', - description: 'An issue with the usability of the software', - name: 'usability', - }, - { - color: '#428BCA', - description: 'Feedback from the feedback-module of the app', - name: 'user-feedback', - }] - .concat(Object.keys(SCHOOLS) - .map((school) => { - return { - color: '#F0AD4E', - description: 'An issue that specifically applies to this school', - name: `school-${school}`, - }; - })) - .concat(['android', 'iOS', 'web', 'node'] - .map((platform) => { - return { - color: '#FFECDB', - description: 'An issue that specifically applies to this platform', - name: `platform::${platform}`, - }; - })); +export const NEEDED_LABELS: Label[] = [ + // eslint-disable-next-line unicorn/no-useless-spread + ...[ + { + color: '#FF0000', + description: 'An error/something that is not working as expected', + name: 'bug', + }, + { + color: '#5CB85C', + name: 'consistency', + }, + { + color: '#FF0000', + name: 'confirmed', + }, + { + color: '#FF0000', + description: 'A blocking issue/something that needs to be fixed ASAP', + name: 'critical', + }, + { + color: '#428BCA', + name: 'design', + }, + { + color: '#0033CC', + description: 'An issue about the documentation of the software', + name: 'documentation', + }, + { + color: '#5CB85C', + name: 'Doing', + }, + { + color: '#5CB85C', + description: 'A feature proposal/something that will be developed', + name: 'feature', + }, + { + color: '#7F8C8D', + description: 'An issue that is unimportant or invalid', + name: 'invalid', + }, + { + color: '#FFFF88', + name: 'meeting', + }, + { + color: '#8E44AD', + name: 'organization', + }, + { + color: '#FF0000', + description: 'An issue with the performance of the software', + name: 'performance', + }, + { + color: '#69D100', + name: 'refactoring', + }, + { + color: '#FF0000', + description: 'An issue with the security of the software', + name: 'security', + }, + { + color: '#D1D100', + description: 'An issue about the testing procedure of the software', + name: 'testing', + }, + { + color: '#F0AD4E', + name: 'To Do', + }, + { + color: '#A8D695', + description: 'An issue with low priority', + name: 'unimportant', + }, + { + color: '#D10069', + description: 'An issue with the usability of the software', + name: 'usability', + }, + { + color: '#428BCA', + description: 'Feedback from the feedback-module of the app', + name: 'user-feedback', + }, + ], + ...Object.keys(SCHOOLS).map(school => { + return { + color: '#F0AD4E', + description: 'An issue that specifically applies to this school', + name: `school-${school}`, + }; + }), + ...['android', 'iOS', 'web', 'node'].map(platform => { + return { + color: '#FFECDB', + description: 'An issue that specifically applies to this platform', + name: `platform::${platform}`, + }; + }), +]; /** * Prefix for automatically created notes @@ -215,5 +210,4 @@ if (NEXT_MEETING.isBefore(moment())) { /** * Last meeting */ -export const LAST_MEETING = moment(NEXT_MEETING) - .subtract(1, 'week'); +export const LAST_MEETING = moment(NEXT_MEETING).subtract(1, 'week'); diff --git a/src/tasks/get-used-version.ts b/src/tasks/get-used-version.ts index 3736bb7a..92509785 100644 --- a/src/tasks/get-used-version.ts +++ b/src/tasks/get-used-version.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 StApps + * Copyright (C) 2019-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -13,33 +13,33 @@ * this program. If not, see . */ import {existsSync, PathLike} from 'fs'; -import {join} from 'path'; +import path from 'path'; import {readFilePromisified} from '../common'; /** * Get used version of a dependency of a project referenced by a path * - * @param path Path to a Node.js project directory + * @param directoryPath Path to a Node.js project directory * @param dependency Dependency to get used version of */ -export async function getUsedVersion(path: PathLike, dependency: string): Promise { - if (!existsSync(join(path.toString(), 'package.json'))) { - throw new Error(`'package.json' does not exist in '${path}'. Not a Node.js project?`); +export async function getUsedVersion(directoryPath: PathLike, dependency: string): Promise { + if (!existsSync(path.join(directoryPath.toString(), 'package.json'))) { + throw new Error(`'package.json' does not exist in '${directoryPath}'. Not a Node.js project?`); } - const buffer = await readFilePromisified(join(path.toString(), 'package.json')); + const buffer = await readFilePromisified(path.join(directoryPath.toString(), 'package.json')); const content = buffer.toString(); - const pkgJson = JSON.parse(content); + const packageJson = JSON.parse(content); - if (typeof pkgJson.dependencies !== 'object') { - throw new Error(`Project in '${path}' has no dependencies!`); + if (typeof packageJson.dependencies !== 'object') { + throw new TypeError(`Project in '${directoryPath}' has no dependencies!`); } - if (typeof pkgJson.dependencies[dependency] !== 'string') { - throw new Error(`Project in '${path}' does not depend on '${dependency}'.`); + if (typeof packageJson.dependencies[dependency] !== 'string') { + throw new TypeError(`Project in '${directoryPath}' does not depend on '${dependency}'.`); } - return pkgJson.dependencies[dependency]; + return packageJson.dependencies[dependency]; } /** @@ -51,7 +51,8 @@ export async function getUsedVersion(path: PathLike, dependency: string): Promis * @param dependency see [[getUsedVersion]] */ export async function getUsedVersionMajorMinor(path: PathLike, dependency: string): Promise { - const versionMatch = (await getUsedVersion(path, dependency)).match(/([0-9]+\.[0-9]+)\.[0-9]+/); + const usedVersions = await getUsedVersion(path, dependency); + const versionMatch = usedVersions.match(/([0-9]+\.[0-9]+)\.[0-9]+/); // istanbul ignore if if (versionMatch === null) { diff --git a/src/tasks/remind.ts b/src/tasks/remind.ts index 67f89a7b..132d1dd2 100644 --- a/src/tasks/remind.ts +++ b/src/tasks/remind.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 StApps + * Copyright (C) 2019-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -33,17 +33,20 @@ import {CONCURRENCY, GROUPS, MAX_DEPTH_FOR_REMINDER, NOTE_PREFIX, SLACK_CHANNEL} */ export async function remind(api: Api): Promise { // get list of open merge requests - const allMergeRequests = await api - .getMergeRequests(MembershipScope.GROUPS, GROUPS[0], MergeRequestState.OPENED); + const allMergeRequests = await api.getMergeRequests( + MembershipScope.GROUPS, + GROUPS[0], + MergeRequestState.OPENED, + ); - const mergeRequests = allMergeRequests.filter((mergeRequest) => { + const mergeRequests = allMergeRequests.filter(mergeRequest => { const parts = mergeRequest.web_url.split('/'); // remove protocol, server name and main group parts.splice(0, parts.indexOf('gitlab.com') + 1 + 1); // remove merge_requests and INDEX parts - parts.splice(parts.length - 1 - 1); + parts.splice(-1 - 1); return parts.length <= MAX_DEPTH_FOR_REMINDER; }); @@ -51,18 +54,19 @@ export async function remind(api: Api): Promise { Logger.info(`Found ${mergeRequests.length} open merge requests.`); // instantiate slack client - const client = typeof process.env.SLACK_API_TOKEN !== 'undefined' ? - new WebClient(process.env.SLACK_API_TOKEN) : - undefined; + const client = + typeof process.env.SLACK_API_TOKEN !== 'undefined' + ? new WebClient(process.env.SLACK_API_TOKEN) + : undefined; // get members of main group const members = await api.getMembers(MembershipScope.GROUPS, GROUPS[0]); // filter members with at least maintainer status - const maintainers = members.filter((member) => member.access_level >= AccessLevel.Maintainer); + const maintainers = members.filter(member => member.access_level >= AccessLevel.Maintainer); // extract maintainer's usernames - const maintainerUsernames = maintainers.map((maintainer) => maintainer.username); + const maintainerUsernames = maintainers.map(maintainer => maintainer.username); // sort maintainer's usernames alphabetically maintainerUsernames.sort((a, b) => { @@ -71,7 +75,7 @@ export async function remind(api: Api): Promise { Logger.info(`Found ${maintainers.length} maintainer(s).`); - await asyncPool(CONCURRENCY, mergeRequests, async (mergeRequest) => { + await asyncPool(CONCURRENCY, mergeRequests, async mergeRequest => { // check if merge request is WIP if (mergeRequest.work_in_progress) { Logger.info(`Merge request '${mergeRequest.title}' is WIP.`); @@ -86,8 +90,8 @@ export async function remind(api: Api): Promise { const discussions = await api.getMergeRequestDiscussions(mergeRequest.project_id, mergeRequest.iid); // check if at least one of the discussions is unresolved - const hasUnresolvedDiscussions = discussions.some((discussion) => { - return discussion.notes.some((note) => { + const hasUnresolvedDiscussions = discussions.some(discussion => { + return discussion.notes.some(note => { return note.resolvable && (typeof note.resolved === 'undefined' || !note.resolved); }); }); @@ -116,7 +120,7 @@ export async function remind(api: Api): Promise { // get possible appropers, prefixed with '@' and joined with commas const possibleApprovers = maintainerUsernames - .filter((username) => { + .filter(username => { if (mergeRequest.assignee.username === username) { return false; } @@ -128,22 +132,24 @@ export async function remind(api: Api): Promise { return true; } - return approval.approved_by.find((approver: { - /** - * Possible approver - */ - user: User; - }) => { - return approver.user.username !== username; - }); + return approval.approved_by.find( + (approver: { + /** + * Possible approver + */ + user: User; + }) => { + return approver.user.username !== username; + }, + ); }) - .map((username) => `@${username}`) + .map(username => `@${username}`) .join(' '); // send message to slack await client?.chat.postMessage({ - channel: SLACK_CHANNEL, - text: `Merge request '${mergeRequest.title}' needs more approvals! See ${mergeRequest.web_url}!`, + channel: SLACK_CHANNEL, + text: `Merge request '${mergeRequest.title}' needs more approvals! See ${mergeRequest.web_url}!`, }); // assign reviewers @@ -153,22 +159,21 @@ export async function remind(api: Api): Promise { mergeRequest.iid, `/assign_reviewer ${possibleApprovers}`, ); - } else { Logger.log(`Merge request '${mergeRequest.title}' is ready to be merged!`); // send message to slack await client?.chat.postMessage({ - channel: SLACK_CHANNEL, - text: `Merge request '${mergeRequest.title}' is ready to be merged! See ${mergeRequest.web_url}!`, + channel: SLACK_CHANNEL, + text: `Merge request '${mergeRequest.title}' is ready to be merged! See ${mergeRequest.web_url}!`, }); // prefix maintainers with '@' and join with commas const possibleMergers = maintainerUsernames - .filter((username) => { - return mergeRequest.assignee.username !== username; + .filter(username => { + return mergeRequest.assignee.username !== username; }) - .map((username) => `@${username}`) + .map(username => `@${username}`) .join(', '); // create note in merge request diff --git a/src/tasks/report.ts b/src/tasks/report.ts index e72d5142..a8c0f2c2 100644 --- a/src/tasks/report.ts +++ b/src/tasks/report.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2019 StApps + * Copyright (C) 2018-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -14,11 +14,18 @@ */ import {asyncPool} from '@krlwlfrt/async-pool'; import {Api} from '@openstapps/gitlab-api'; -import {Issue, IssueState, MembershipScope, MergeRequestState, Project, User} from '@openstapps/gitlab-api/lib/types'; +import { + Issue, + IssueState, + MembershipScope, + MergeRequestState, + Project, + User, +} from '@openstapps/gitlab-api/lib/types'; import {Logger} from '@openstapps/logger'; import moment from 'moment'; import {render} from 'mustache'; -import {join, resolve} from 'path'; +import path from 'path'; import {cwd} from 'process'; import {flatten2dArray, getProjects, readFilePromisified, writeFilePromisified} from '../common'; import {BOLD_LABELS, CONCURRENCY, GROUPS, LABEL_WEIGHTS, NEXT_MEETING} from '../configuration'; @@ -139,8 +146,10 @@ export interface MergeRequestsForProjects { * * @param state State to check */ -export function issueStateIsOpenedOrClosed(state: IssueState): state is IssueState.OPENED | IssueState.CLOSED { - return ['opened', 'closed'].indexOf(state) >= 0; +export function issueStateIsOpenedOrClosed( + state: IssueState, +): state is IssueState.OPENED | IssueState.CLOSED { + return ['opened', 'closed'].includes(state); } /** @@ -150,19 +159,24 @@ export function issueStateIsOpenedOrClosed(state: IssueState): state is IssueSta * @param projectId Project ID to get data about merge requests for * @param issueIid Issue IID in certain project (relative ID, and not issue's GitLab API ID) */ -export function getMergeRequestUrls(projectMergeRequests: MergeRequestsForProjects, - projectId: number, - issueIid: number): string[] { - if (typeof projectMergeRequests[projectId] === 'undefined' || projectMergeRequests[projectId].length === 0) { +export function getMergeRequestUrls( + projectMergeRequests: MergeRequestsForProjects, + projectId: number, + issueIid: number, +): string[] { + if ( + typeof projectMergeRequests[projectId] === 'undefined' || + projectMergeRequests[projectId].length === 0 + ) { return []; } return projectMergeRequests[projectId] - .filter((obj) => { - return obj.issue_iid === issueIid; + .filter(object => { + return object.issue_iid === issueIid; }) - .map((obj) => { - return obj.web_url; + .map(object => { + return object.web_url; }); } @@ -174,16 +188,15 @@ export function getMergeRequestUrls(projectMergeRequests: MergeRequestsForProjec * @param groups List of groups to get issues for */ export async function getIssues(api: Api, label: string, groups: number[]): Promise { - const issueResults = await asyncPool(CONCURRENCY, groups, async (groupId) => { + const issueResults = await asyncPool(CONCURRENCY, groups, async groupId => { return api.getIssues({ groupId: groupId, }); }); - const issues = flatten2dArray(issueResults) - .filter((issue) => { - return issue.labels.indexOf(label) >= 0; - }); + const issues = flatten2dArray(issueResults).filter(issue => { + return issue.labels.includes(label); + }); Logger.log(`Fetched ${issues.length} issue(s).`); @@ -196,24 +209,22 @@ export async function getIssues(api: Api, label: string, groups: number[]): Prom * @param api GitLab API To make requests with * @param projects List of projects */ -export async function getIssueBranches( - api: Api, - projects: Project[]): Promise<{ [k: string]: number[]; }> { - const projectBranches: { [k: string]: number[]; } = {}; +export async function getIssueBranches(api: Api, projects: Project[]): Promise<{[k: string]: number[]}> { + const projectBranches: {[k: string]: number[]} = {}; - await asyncPool(CONCURRENCY, projects, async (project) => { + await asyncPool(CONCURRENCY, projects, async project => { const branches = await api.getBranchesForProject(project.id); // extract issue number from branch projectBranches[project.id] = branches - .map((branch) => { + .map(branch => { return branch.name.split('-')[0]; }) - .filter((branchNameStart) => { + .filter(branchNameStart => { return branchNameStart.match(/^[0-9]+$/); }) - .map((branchNameStart) => { - return parseInt(branchNameStart, 10); + .map(branchNameStart => { + return Number.parseInt(branchNameStart, 10); }); }); @@ -229,26 +240,26 @@ export async function getIssueBranches( export async function getIssuesGroupedByAssignees(api: Api, label: string): Promise { const issuesByAssignee: IssuesGroupedByAssigneeId = {}; - const groups = flatten2dArray(await asyncPool(CONCURRENCY, GROUPS, async (groupId) => { - return (await api.getSubGroupsForGroup(groupId)).map((group) => { - return group.id; - }); - })); - groups.push.apply(groups, GROUPS); + const groups = flatten2dArray( + await asyncPool(CONCURRENCY, GROUPS, async groupId => { + const subGroups = await api.getSubGroupsForGroup(groupId); + return subGroups.map(group => { + return group.id; + }); + }), + ); + groups.push(...groups, ...GROUPS); - const [issues, projects] = await Promise.all([ - getIssues(api, label, groups), - getProjects(api, groups), - ]); + const [issues, projects] = await Promise.all([getIssues(api, label, groups), getProjects(api, groups)]); const issueBranches = await getIssueBranches(api, projects); const mergeRequests = await getMergeRequests(api, projects); - issues.forEach((issue) => { + for (const issue of issues) { if (issue.assignee === null) { Logger.warn('Issue without assignee!', issue.web_url); - return; + continue; } if (typeof issuesByAssignee[issue.assignee.id] === 'undefined') { @@ -267,33 +278,33 @@ export async function getIssuesGroupedByAssignees(api: Api, label: string): Prom issue.state = IssueState.OPENED; } + const issueMeta = { + $branchExists: + typeof issueBranches[issue.project_id] !== 'undefined' && + issueBranches[issue.project_id].includes(issue.iid), + $closed: issue.state === IssueState.CLOSED, + $issue: issue, + $labels: issue.labels.map((issueLabel: string) => { + return { + bold: BOLD_LABELS.includes(issueLabel), + label: issueLabel, + }; + }), + $mergeRequestUrl: getMergeRequestUrls(mergeRequests, issue.project_id, issue.iid)[0], + $project: issue.web_url.replace('https://gitlab.com/', '').split('/-/issues/')[0], + $weeksOpen: moment().diff(moment(issue.created_at), 'weeks'), + }; + const issueWithMeta: IssueWithMeta = { ...issue, - ...{ - $branchExists: typeof issueBranches[issue.project_id] !== 'undefined' - && issueBranches[issue.project_id].indexOf(issue.iid) >= 0, - $closed: issue.state === IssueState.CLOSED, - $issue: issue, - $labels: issue.labels.map((issueLabel: string) => { - return { - bold: BOLD_LABELS.includes(issueLabel), - label: issueLabel, - }; - }), - $mergeRequestUrl: getMergeRequestUrls(mergeRequests, issue.project_id, issue.iid)[0], - $project: issue.web_url - .replace('https://gitlab.com/', '') - .split('/-/issues/')[0], - $weeksOpen: moment() - .diff(moment(issue.created_at), 'weeks'), - }, + ...issueMeta, }; if (issueStateIsOpenedOrClosed(issue.state)) { issuesByAssignee[issue.assignee.id].issueCounts[issue.state]++; issuesByAssignee[issue.assignee.id].issues.push(issueWithMeta); } - }); + } // calculate quota for (const _assigneeId in issuesByAssignee) { @@ -301,13 +312,14 @@ export async function getIssuesGroupedByAssignees(api: Api, label: string): Prom continue; } - const assigneeId = parseInt(_assigneeId, 10); + const assigneeId = Number.parseInt(_assigneeId, 10); issuesByAssignee[assigneeId].quota = Math.floor( - issuesByAssignee[assigneeId].issueCounts.closed - / (issuesByAssignee[assigneeId].issueCounts.opened - // tslint:disable-next-line:no-magic-numbers - + issuesByAssignee[assigneeId].issueCounts.closed) * 100, + (issuesByAssignee[assigneeId].issueCounts.closed / + (issuesByAssignee[assigneeId].issueCounts.opened + + // tslint:disable-next-line:no-magic-numbers + issuesByAssignee[assigneeId].issueCounts.closed)) * + 100, ); } @@ -317,7 +329,7 @@ export async function getIssuesGroupedByAssignees(api: Api, label: string): Prom continue; } - const assigneeId = parseInt(_assigneeId, 10); + const assigneeId = Number.parseInt(_assigneeId, 10); issuesByAssignee[assigneeId].issues.sort((a, b) => { let weightA = 0; @@ -328,11 +340,11 @@ export async function getIssuesGroupedByAssignees(api: Api, label: string): Prom continue; } - if (a.labels.indexOf(issueLabel) >= 0) { + if (a.labels.includes(issueLabel)) { weightA += LABEL_WEIGHTS[issueLabel]; } - if (b.labels.indexOf(issueLabel) >= 0) { + if (b.labels.includes(issueLabel)) { weightB += LABEL_WEIGHTS[issueLabel]; } } @@ -372,32 +384,35 @@ export function getNextMeetingDay() { * @param api GitLab API to make requests with * @param projects List of projects */ -export async function getMergeRequests(api: Api, - projects: Project[]): Promise { +export async function getMergeRequests(api: Api, projects: Project[]): Promise { const projectMergeRequests: MergeRequestsForProjects = {}; // iterate over projects - await asyncPool(CONCURRENCY, projects, async (project) => { + await asyncPool(CONCURRENCY, projects, async project => { // check if project can have merge requests if (!project.merge_requests_enabled) { return; } // get all merge requests for project - const mergeRequests = await api.getMergeRequests(MembershipScope.PROJECTS, project.id, MergeRequestState.OPENED); + const mergeRequests = await api.getMergeRequests( + MembershipScope.PROJECTS, + project.id, + MergeRequestState.OPENED, + ); // extract issue number from merge request projectMergeRequests[project.id] = mergeRequests - .map((mergeRequest) => { + .map(mergeRequest => { // keep information about web url too return {issue_iid: mergeRequest.source_branch.split('-')[0], web_url: mergeRequest.web_url}; }) - .filter((branchNameStartAndUrl) => { + .filter(branchNameStartAndUrl => { return branchNameStartAndUrl.issue_iid.match(/^[0-9]+$/); }) - .map((branchNameStartAndUrl) => { + .map(branchNameStartAndUrl => { return { - issue_iid: parseInt(branchNameStartAndUrl.issue_iid, 10), + issue_iid: Number.parseInt(branchNameStartAndUrl.issue_iid, 10), web_url: branchNameStartAndUrl.web_url, }; }); @@ -419,14 +434,10 @@ export async function generateReport(api: Api, label: string, template: string): const structureForTemplate: StructureForTemplate = { issuesByAssignee: issuesGroupedByAssignee, meetingDay: getNextMeetingDay(), - timestamp: moment() - .format('LLL'), + timestamp: moment().format('LLL'), }; - return render( - template, - structureForTemplate, - ); + return render(template, structureForTemplate); } /** @@ -438,16 +449,17 @@ export async function generateReport(api: Api, label: string, template: string): export async function report(api: Api, label: string) { const meetingDay = getNextMeetingDay(); - const markdown = await generateReport( - api, - label, - (await readFilePromisified(resolve(__dirname, '..', '..', 'templates', 'report.md.mustache'))).toString(), + const readReportFile = await readFilePromisified( + // eslint-disable-next-line unicorn/prefer-module + path.resolve(__dirname, '..', '..', 'templates', 'report.md.mustache'), ); - let filename = join(cwd(), 'reports', `${meetingDay}.md`); + const markdown = await generateReport(api, label, readReportFile.toString()); + + let filename = path.join(cwd(), 'reports', `${meetingDay}.md`); if (label !== 'meeting') { - filename = join(cwd(), 'reports', `${label}.md`); + filename = path.join(cwd(), 'reports', `${label}.md`); } await writeFilePromisified(filename, markdown); diff --git a/src/tasks/tidy.ts b/src/tasks/tidy.ts index 1759fac0..0508bf57 100644 --- a/src/tasks/tidy.ts +++ b/src/tasks/tidy.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2019 StApps + * Copyright (C) 2018-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -14,7 +14,15 @@ */ import {asyncPool} from '@krlwlfrt/async-pool'; import {Api} from '@openstapps/gitlab-api'; -import {AccessLevel, IssueState, MembershipScope, MergeRequestState, Milestone, Project, Scope} from '@openstapps/gitlab-api/lib/types'; +import { + AccessLevel, + IssueState, + MembershipScope, + MergeRequestState, + Milestone, + Project, + Scope, +} from '@openstapps/gitlab-api/lib/types'; import {Logger} from '@openstapps/logger'; import {flatten2dArray, getProjects} from '../common'; import { @@ -36,7 +44,7 @@ import { */ export async function tidyIssuesWithoutMilestone(api: Api): Promise { // fetch issues without milestone from all groups - const issueResults = await asyncPool(CONCURRENCY, GROUPS, async (groupId) => { + const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => { return api.getIssues({ groupId: groupId, milestone: 'No Milestone', @@ -49,22 +57,22 @@ export async function tidyIssuesWithoutMilestone(api: Api): Promise { Logger.info(`Found '${issuesWithoutMilestone.length}' issue(s) without milestone.`); - const milestoneCache: { [s: number]: Milestone[]; } = {}; + const milestoneCache: {[s: number]: Milestone[]} = {}; - await asyncPool(CONCURRENCY, issuesWithoutMilestone, async (issue) => { + await asyncPool(CONCURRENCY, issuesWithoutMilestone, async issue => { if (typeof milestoneCache[issue.project_id] === 'undefined') { milestoneCache[issue.project_id] = await api.getMilestonesForProject(issue.project_id); } - let milestoneId = null; + let milestoneId; - milestoneCache[issue.project_id].forEach((milestone) => { + for (const milestone of milestoneCache[issue.project_id]) { if (milestone.title === 'Meeting') { milestoneId = milestone.id; } - }); + } - if (milestoneId === null) { + if (typeof milestoneId === 'undefined') { Logger.warn(`Milestone 'Meeting' was not available for issue ${issue.title} (${issue.web_url}).`); return; @@ -94,7 +102,7 @@ export async function tidyIssuesWithoutMilestone(api: Api): Promise { */ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise { // fetch all open issues - const issueResults = await asyncPool(CONCURRENCY, GROUPS, async (groupId) => { + const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => { return api.getIssues({ groupId: groupId, state: IssueState.OPENED, @@ -107,13 +115,13 @@ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise Logger.info(`Found ${openIssues.length} open issue(s).`); // filter issues without meeting label - const openIssuesWithoutMeetingLabel = openIssues.filter((openIssue) => { - return openIssue.labels.indexOf('meeting') === -1; + const openIssuesWithoutMeetingLabel = openIssues.filter(openIssue => { + return !openIssue.labels.includes('meeting'); }); Logger.info(`Filtered ${openIssuesWithoutMeetingLabel.length} open issue(s) without label 'meeting'.`); - await asyncPool(CONCURRENCY, openIssuesWithoutMeetingLabel, async (issue) => { + await asyncPool(CONCURRENCY, openIssuesWithoutMeetingLabel, async issue => { if (issue.milestone !== null && issue.milestone.title === 'Backlog') { Logger.info(`Skipping issue "${issue.title}" because it is in backlog.`); @@ -124,7 +132,8 @@ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise issue.project_id, Scope.ISSUES, issue.iid, - `${NOTE_PREFIX} Automatically adding label 'meeting'\n\n/label ~meeting`); + `${NOTE_PREFIX} Automatically adding label 'meeting'\n\n/label ~meeting`, + ); }); Logger.ok(`Tidied open issues without label 'meeting'.`); @@ -137,28 +146,28 @@ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise * @param projects List of projects to tidy labels on */ export async function tidyLabels(api: Api, projects: Project[]): Promise { - await asyncPool(CONCURRENCY, projects, async (project) => { + await asyncPool(CONCURRENCY, projects, async project => { const labels = await api.getLabels(project.id); - const neededLabels = NEEDED_LABELS.slice(0); + const neededLabels = [...NEEDED_LABELS]; // const extraneousLabels: Label[] = []; - labels.forEach((label) => { + for (const label of labels) { // let needed = false; - neededLabels.forEach((neededLabel, neededLabelIdx) => { + for (const [neededLabelIndex, neededLabel] of neededLabels.entries()) { if (neededLabel.name.toLowerCase() === label.name.toLowerCase()) { - neededLabels.splice(neededLabelIdx, 1); + neededLabels.splice(neededLabelIndex, 1); // needed = true; } - }); + } /* if (!needed) { extraneousLabels.push(label); } */ - }); + } - await asyncPool(CONCURRENCY, neededLabels, async (neededLabel) => { + await asyncPool(CONCURRENCY, neededLabels, async neededLabel => { await api.createLabel(project.id, neededLabel.name, neededLabel.description, neededLabel.color); Logger.log(`Created label '${neededLabel.name}' in '${project.name_with_namespace}'.`); @@ -181,20 +190,20 @@ export async function tidyLabels(api: Api, projects: Project[]): Promise { * @param projects List of projects to tidy milestones on */ export async function tidyMilestones(api: Api, projects: Project[]): Promise { - await asyncPool(CONCURRENCY, projects, async (project) => { + await asyncPool(CONCURRENCY, projects, async project => { const milestones = await api.getMilestonesForProject(project.id); - const missingMilestones = NEEDED_MILESTONES.slice(0); + const missingMilestones = [...NEEDED_MILESTONES]; - milestones.forEach((milestone) => { - const idx = missingMilestones.indexOf(milestone.title); + for (const milestone of milestones) { + const index = missingMilestones.indexOf(milestone.title); - if (idx >= 0) { - missingMilestones.splice(idx, 1); + if (index >= 0) { + missingMilestones.splice(index, 1); } - }); + } if (missingMilestones.length > 0 && !project.archived) { - await asyncPool(CONCURRENCY, missingMilestones, async (milestone) => { + await asyncPool(CONCURRENCY, missingMilestones, async milestone => { await api.createMilestone(project.id, milestone); Logger.log(`Created milestone '${milestone}' for project ${project.name_with_namespace}'.`); }); @@ -211,18 +220,18 @@ export async function tidyMilestones(api: Api, projects: Project[]): Promise { - await asyncPool(CONCURRENCY, projects, async (project) => { + await asyncPool(CONCURRENCY, projects, async project => { const branches = await api.getBranchesForProject(project.id); - const protectableBranches = branches.filter((branch) => { - return PROTECTED_BRANCHES.indexOf(branch.name) >= 0; + const protectableBranches = branches.filter(branch => { + return PROTECTED_BRANCHES.includes(branch.name); }); - const unprotectedBranches = protectableBranches.filter((branch) => { + const unprotectedBranches = protectableBranches.filter(branch => { return !branch.protected; }); - await asyncPool(CONCURRENCY, unprotectedBranches, async (branch) => { + await asyncPool(CONCURRENCY, unprotectedBranches, async branch => { await api.protectBranch(project.id, branch.name); Logger.log(`Added protected branch '${branch.name}' in project '${project.name_with_namespace}'...`); @@ -239,9 +248,9 @@ export async function tidyProtectedBranches(api: Api, projects: Project[]): Prom * @param projects List of projects to tidy protected tags on */ export async function tidyProtectedTags(api: Api, projects: Project[]): Promise { - await asyncPool(CONCURRENCY, projects, async (project) => { + await asyncPool(CONCURRENCY, projects, async project => { // TODO: move this to GitLab API - const protectedTags = await api.makeGitLabAPIRequest(`projects/${project.id}/protected_tags`) as Array<{ + const protectedTags = (await api.makeGitLabAPIRequest(`projects/${project.id}/protected_tags`)) as Array<{ /** * List of access levels to create a tag */ @@ -261,9 +270,11 @@ export async function tidyProtectedTags(api: Api, projects: Project[]): Promise< name: string; }>; - if (protectedTags.findIndex((protectedTag) => { - return protectedTag.name === 'v*'; - }) === -1) { + if ( + protectedTags.findIndex(protectedTag => { + return protectedTag.name === 'v*'; + }) === -1 + ) { await api.makeGitLabAPIRequest(`projects/${project.id}/protected_tags`, { data: { create_access_level: AccessLevel.Maintainer, @@ -286,29 +297,28 @@ export async function tidyProtectedTags(api: Api, projects: Project[]): Promise< */ export async function tidySubGroupMembers(api: Api): Promise { const stappsMembers = await api.getMembers(MembershipScope.GROUPS, GROUPS[0]); - const stappsMemberIds = stappsMembers.map((member) => member.id); + const stappsMemberIds = new Set(stappsMembers.map(member => member.id)); - const groupIdsToSchool: { [id: number]: string; } = {}; + const groupIdsToSchool: {[id: number]: string} = {}; - Object.keys(SCHOOLS) - .map((school) => { - groupIdsToSchool[SCHOOLS[school]] = school; - }); + Object.keys(SCHOOLS).map(school => { + groupIdsToSchool[SCHOOLS[school]] = school; + }); - await asyncPool(CONCURRENCY, GROUPS.slice(1), async (groupId) => { + await asyncPool(CONCURRENCY, GROUPS.slice(1), async groupId => { const members = await api.getMembers(MembershipScope.GROUPS, groupId); - const memberIds = members.map((member) => member.id); + const memberIds = new Set(members.map(member => member.id)); - await asyncPool(CONCURRENCY, stappsMembers, async (stappsMember) => { - if (memberIds.indexOf(stappsMember.id) === -1) { + await asyncPool(CONCURRENCY, stappsMembers, async stappsMember => { + if (!memberIds.has(stappsMember.id)) { await api.addMember(MembershipScope.GROUPS, groupId, stappsMember.id, AccessLevel.Developer); Logger.log(`Added '${stappsMember.name}' to group '${groupIdsToSchool[groupId]}'.`); } }); - await asyncPool(CONCURRENCY, members, async (member) => { - if (stappsMemberIds.indexOf(member.id) === -1) { + await asyncPool(CONCURRENCY, members, async member => { + if (!stappsMemberIds.has(member.id)) { await api.deleteMember(MembershipScope.GROUPS, groupId, member.id); Logger.log(`Deleted member '${member.name}' from group '${groupIdsToSchool[groupId]}'.`); @@ -328,7 +338,7 @@ export async function tidySubGroupMembers(api: Api): Promise { */ export async function tidyIssuesWithoutAssignee(api: Api): Promise { // fetch issues without milestone from all groups - const issueResults = await asyncPool(CONCURRENCY, GROUPS, async (groupId) => { + const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => { return api.getIssues({ groupId: groupId, state: IssueState.OPENED, @@ -338,13 +348,13 @@ export async function tidyIssuesWithoutAssignee(api: Api): Promise { // flatten structure, e.g. put all issues in one array const issues = flatten2dArray(issueResults); - const issuesWithoutAssignee = issues.filter((issue) => { + const issuesWithoutAssignee = issues.filter(issue => { return issue.assignee === null; }); Logger.info(`Found '${issuesWithoutAssignee.length}' issue(s) without assignee.`); - await asyncPool(CONCURRENCY, issuesWithoutAssignee, async (issue) => { + await asyncPool(CONCURRENCY, issuesWithoutAssignee, async issue => { await api.setAssigneeForIssue(issue, issue.author.id); Logger.log(`Set assignee for '${issue.title}' to '${issue.author.name}'.`); @@ -368,24 +378,20 @@ export async function tidyIssuesWithoutAssignee(api: Api): Promise { * @param api GitLab API instance to use for the requests */ export async function tidyMergeRequestsWithoutAssignee(api: Api): Promise { - const mergeRequestResults = await asyncPool(CONCURRENCY, GROUPS, async (groupId) => { - return api.getMergeRequests( - MembershipScope.GROUPS, - groupId, - MergeRequestState.OPENED, - ); + const mergeRequestResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => { + return api.getMergeRequests(MembershipScope.GROUPS, groupId, MergeRequestState.OPENED); }); // flatten structure, e.g. put all issues in one array const mergeRequests = flatten2dArray(mergeRequestResults); - const mergeRequestsWithoutAssignee = mergeRequests.filter((mergeRequest) => { + const mergeRequestsWithoutAssignee = mergeRequests.filter(mergeRequest => { return mergeRequest.assignee === null; }); Logger.info(`Found '${mergeRequestsWithoutAssignee.length}' merge requests without assignee.`); - await asyncPool(CONCURRENCY, mergeRequestsWithoutAssignee, async (mergeRequest) => { + await asyncPool(CONCURRENCY, mergeRequestsWithoutAssignee, async mergeRequest => { await api.setAssigneeForMergeRequest(mergeRequest, mergeRequest.author.id); Logger.log(`Set assignee for '${mergeRequest.title}' to '${mergeRequest.author.name}'.`); @@ -408,8 +414,9 @@ export async function tidyMergeRequestsWithoutAssignee(api: Api): Promise */ export async function tidy(api: Api) { // get first level sub groups - const groups = GROUPS.slice(); - groups.push.apply(groups, (await api.getSubGroupsForGroup(groups[0])).map((group) => group.id)); + const groups = [...GROUPS]; + const subGroups = await api.getSubGroupsForGroup(groups[0]); + groups.push(...groups, ...subGroups.map(group => group.id)); // get non archived projects of groups let projects = await getProjects(api, groups); diff --git a/src/tasks/unlabel.ts b/src/tasks/unlabel.ts index 84a5c70d..f3434a75 100644 --- a/src/tasks/unlabel.ts +++ b/src/tasks/unlabel.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2019 StApps + * Copyright (C) 2018-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -26,7 +26,7 @@ import {CONCURRENCY, GROUPS, LAST_MEETING, NOTE_PREFIX} from '../configuration'; * @param api Instance of GitLabAPI to send requests with */ export async function unlabel(api: Api) { - const issueResults = await asyncPool(CONCURRENCY, GROUPS, async (groupId) => { + const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => { return api.getIssues({ groupId: groupId, state: IssueState.CLOSED, @@ -37,21 +37,21 @@ export async function unlabel(api: Api) { Logger.log(`Fetched ${issues.length} closed issue(s).`); - await asyncPool(CONCURRENCY, issues, async (issue) => { - if (issue.labels.indexOf('meeting') >= 0 && issue.closed_at !== null) { + await asyncPool(CONCURRENCY, issues, async issue => { + if ( + issue.labels.includes('meeting') && + issue.closed_at !== null && + moment(issue.closed_at).isBefore(LAST_MEETING) + ) { + Logger.info(`Issue ${issue.title} is closed before last meeting and has label "meeting". Removing it.`); - if (moment(issue.closed_at) - .isBefore(LAST_MEETING)) { - Logger.info(`Issue ${issue.title} is closed before last meeting and has label "meeting". Removing it.`); - - await api.createNote( - issue.project_id, - Scope.ISSUES, - issue.iid, - `${NOTE_PREFIX} Removed label \`meeting\` automatically. + await api.createNote( + issue.project_id, + Scope.ISSUES, + issue.iid, + `${NOTE_PREFIX} Removed label \`meeting\` automatically. /unlabel ~meeting`, - ); - } + ); } }); diff --git a/tslint.json b/tslint.json deleted file mode 100644 index f125abb0..00000000 --- a/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "./node_modules/@openstapps/configuration/tslint.json" -}