From 80163b5152ce21199389670d677a89e425192f1b Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Wed, 26 Jan 2022 18:56:31 +0100 Subject: [PATCH 01/51] update #80 #70 --- .editorconfig | 8 +- .eslintrc.js | 13 +- Dockerfile | 2 +- declarations.d.ts | 19 - jest.config.js | 11 + package-lock.json | 13821 ++++++++++++++++++++---- package.json | 48 +- src/api/Route.ts | 149 +- src/api/index.ts | 392 +- src/bot.ts | 112 +- src/config/index.ts | 290 +- src/database/drivers/Driver.ts | 52 +- src/database/drivers/GenericDriver.ts | 157 +- src/handleBurritos.ts | 121 + src/lib/boot.ts | 56 +- src/lib/emojis.ts | 21 + src/lib/mapper.ts | 34 +- src/lib/parseMessage.ts | 89 +- src/lib/themeHandler.ts | 150 +- src/lib/utils.ts | 134 +- src/lib/validator.ts | 102 +- src/middleware.ts | 243 +- src/server.ts | 87 +- src/slack/Rtm.ts | 2 +- src/slack/Wbc.ts | 72 +- src/slack/index.ts | 8 +- src/store/BurritoStore.ts | 299 +- src/store/LocalStore.ts | 11 +- src/store/_BurritoStore.old.ts | 115 + src/types/Score.interface.ts | 3 +- src/web/index.ts | 2 +- src/wss/index.ts | 33 +- test/Wbc-test.ts | 17 - test/burritostore-test.ts | 135 - test/burritostore.test.ts | 121 + test/globals.ts | 7 - test/lib/seedDatabase.ts | 10 +- test/mapper-test.ts | 51 - test/mapper.test.ts | 49 + test/mocha.opts | 0 test/parseMessage-test.ts | 242 - test/parseMessage.test.ts | 239 + test/setup.ts | 3 + test/utils-test.ts | 76 - test/utils.test.ts | 73 + test/validator-test.ts | 98 - test/validator.test.ts | 94 + test/wbc.test.ts | 16 + tsconfig.json | 31 +- 49 files changed, 13903 insertions(+), 4015 deletions(-) delete mode 100644 declarations.d.ts create mode 100644 jest.config.js create mode 100644 src/handleBurritos.ts create mode 100644 src/lib/emojis.ts create mode 100644 src/store/_BurritoStore.old.ts delete mode 100644 test/Wbc-test.ts delete mode 100644 test/burritostore-test.ts create mode 100644 test/burritostore.test.ts delete mode 100644 test/globals.ts delete mode 100644 test/mapper-test.ts create mode 100644 test/mapper.test.ts delete mode 100644 test/mocha.opts delete mode 100644 test/parseMessage-test.ts create mode 100644 test/parseMessage.test.ts create mode 100644 test/setup.ts delete mode 100644 test/utils-test.ts create mode 100644 test/utils.test.ts delete mode 100644 test/validator-test.ts create mode 100644 test/validator.test.ts create mode 100644 test/wbc.test.ts diff --git a/.editorconfig b/.editorconfig index 8216ece..013ce0c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,14 +7,16 @@ end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true - indent_style = space [*.ts] -indent_size = 4 +indent_size = 2 [*.js] -indent_size = 4 +indent_size = 2 + +[*.json] +indent_size = 2 [package.json] indent_size = 2 diff --git a/.eslintrc.js b/.eslintrc.js index 04ef3c4..9fb64c5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,9 +1,8 @@ module.exports = { - extends: ['airbnb-typescript/base'], - "rules": { - "max-len": ["warn", { "code": 140 }], - "quotes": [2, "single", { "avoidEscape": true }], - "@typescript-eslint/indent": ["error", 4], - - } + extends: ['airbnb-typescript/base'], + "rules": { + "max-len": ["warn", { "code": 140 }], + "quotes": [2, "single", { "avoidEscape": true }], + "@typescript-eslint/indent": ["error", 2], + } }; diff --git a/Dockerfile b/Dockerfile index 776bef3..e56b990 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -FROM node:erbium +FROM node:gallium RUN apt-get update && apt-get install -y diff --git a/declarations.d.ts b/declarations.d.ts deleted file mode 100644 index febbb8f..0000000 --- a/declarations.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* -* Declare JS modules that we want to use -*/ -declare module 'bog'; -declare module 'mongodb'; -declare module 'dotenv'; -declare module 'path'; -declare module '@slack/rtm-api'; -declare module '@slack/web-api'; -declare module 'ws'; -declare module 'git-clone-repo'; -declare module 'http'; - -// For tests -declare module 'chai'; -declare module 'sinon'; -declare module 'fs'; -declare module 'proxyquire'; -declare module 'mongodb-memory-server'; diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..d19017f --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +module.exports = { + clearMocks: true, + setupFilesAfterEnv: ['/test/setup.ts'], + roots: [ + "/test" + ], + transform: { + "^.+\\.(ts|js)x?$": "ts-jest" + }, + reporters: ['default'], +}; diff --git a/package-lock.json b/package-lock.json index e0e025e..1702e93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,73 +1,8487 @@ { "name": "heyburrito", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "heyburrito", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@slack/rtm-api": "^6.0.0", + "@slack/web-api": "^6.6.0", + "dotenv": "^14.3.0", + "loglevel": "^1.8.0", + "mongodb": "^4.3.1", + "ts-node": "^10.4.0", + "typescript": "^4.5.5", + "ws": "^8.4.2" + }, + "devDependencies": { + "@types/dotenv": "^6.1.1", + "@types/jest": "^27.4.0", + "@types/loglevel": "^1.6.3", + "@types/node": "^17.0.10", + "@typescript-eslint/eslint-plugin": "^5.10.1", + "@typescript-eslint/parser": "^5.10.1", + "eslint": "^8.7.0", + "eslint-config-airbnb-typescript": "^16.1.0", + "eslint-plugin-import": "^2.25.4", + "jest": "^27.4.7", + "mongodb-memory-server": "8.2.0", + "nodemon": "^2.0.15", + "proxyquire": "^2.1.3", + "ts-jest": "^27.1.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", + "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", + "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.12", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.10", + "@babel/types": "^7.16.8", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", + "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.8", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", + "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", + "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.10", + "@babel/types": "^7.16.8", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@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 + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/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, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/types": "^27.4.2", + "expect": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/source-map": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.4.6", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.4.2", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@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, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@slack/logger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-2.0.0.tgz", + "integrity": "sha512-OkIJpiU2fz6HOJujhlhfIGrc8hB4ibqtf7nnbJQDerG0BqwZCfmgtK5sWzZ0TkXVRBKD5MpLrTmCYyMxoMCgPw==", + "dependencies": { + "@types/node": ">=8.9.0" + }, + "engines": { + "node": ">= 8.9.0", + "npm": ">= 5.5.1" + } + }, + "node_modules/@slack/rtm-api": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@slack/rtm-api/-/rtm-api-6.0.0.tgz", + "integrity": "sha512-4jgONmC10/RdV6Q07e6PRUXrORPs2Xhe2gWKcGo49D2rCFy8H8SpM1RxowrVLYXqXUoMt3fIrqu050SuF4iVVA==", + "dependencies": { + "@slack/logger": ">=1.0.0 <3.0.0", + "@slack/web-api": "^5.3.0", + "@types/node": ">=12.0.0", + "@types/p-queue": "^2.3.2", + "@types/ws": "^7.2.5", + "eventemitter3": "^3.1.0", + "finity": "^0.5.4", + "p-cancelable": "^1.1.0", + "p-queue": "^2.4.2", + "ws": "^5.2.0" + }, + "engines": { + "node": ">= 12.13.0", + "npm": ">= 6.12.0" + } + }, + "node_modules/@slack/rtm-api/node_modules/@slack/types": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-1.10.0.tgz", + "integrity": "sha512-tA7GG7Tj479vojfV3AoxbckalA48aK6giGjNtgH6ihpLwTyHE3fIgRrvt8TWfLwW8X8dyu7vgmAsGLRG7hWWOg==", + "engines": { + "node": ">= 8.9.0", + "npm": ">= 5.5.1" + } + }, + "node_modules/@slack/rtm-api/node_modules/@slack/web-api": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.15.0.tgz", + "integrity": "sha512-tjQ8Zqv/Fmj9SOL9yIEd7IpTiKfKHi9DKAkfRVeotoX0clMr3SqQtBqO+KZMX27gm7dmgJsQaDKlILyzdCO+IA==", + "dependencies": { + "@slack/logger": ">=1.0.0 <3.0.0", + "@slack/types": "^1.7.0", + "@types/is-stream": "^1.1.0", + "@types/node": ">=8.9.0", + "axios": "^0.21.1", + "eventemitter3": "^3.1.0", + "form-data": "^2.5.0", + "is-stream": "^1.1.0", + "p-queue": "^6.6.1", + "p-retry": "^4.0.0" + }, + "engines": { + "node": ">= 8.9.0", + "npm": ">= 5.5.1" + } + }, + "node_modules/@slack/rtm-api/node_modules/@slack/web-api/node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@slack/rtm-api/node_modules/@slack/web-api/node_modules/p-queue/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/@slack/rtm-api/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/@slack/rtm-api/node_modules/ws": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz", + "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@slack/types": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-2.4.0.tgz", + "integrity": "sha512-0k8UlVEH9gUVwTbwcanS1JT2vCROkr1WESgdXW7d2maWYTuwbVEx87YvXPjsemAJfdu+RYqxGhO2oGTigprepA==", + "engines": { + "node": ">= 12.13.0", + "npm": ">= 6.12.0" + } + }, + "node_modules/@slack/web-api": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-6.6.0.tgz", + "integrity": "sha512-4z8tBBIQFojH9uSrsmnI0pGDpOZmJ3UO+Ewwtj3SfkokAUJz3d2dSH5sPk9jKcGfx39e34LoJ+l1YSavvHQeeg==", + "dependencies": { + "@slack/logger": "^3.0.0", + "@slack/types": "^2.0.0", + "@types/is-stream": "^1.1.0", + "@types/node": ">=12.0.0", + "axios": "^0.25.0", + "eventemitter3": "^3.1.0", + "form-data": "^2.5.0", + "is-electron": "2.2.0", + "is-stream": "^1.1.0", + "p-queue": "^6.6.1", + "p-retry": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0", + "npm": ">= 6.12.0" + } + }, + "node_modules/@slack/web-api/node_modules/@slack/logger": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-3.0.0.tgz", + "integrity": "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA==", + "dependencies": { + "@types/node": ">=12.0.0" + }, + "engines": { + "node": ">= 12.13.0", + "npm": ">= 6.12.0" + } + }, + "node_modules/@slack/web-api/node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@slack/web-api/node_modules/p-queue/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, + "node_modules/@types/babel__core": { + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/dotenv": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz", + "integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", + "dev": true, + "dependencies": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/loglevel": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@types/loglevel/-/loglevel-1.6.3.tgz", + "integrity": "sha512-v2YWQQgqtNXAzybOT9qV3CIJqSeoaMUwmBfIMTQdvhsWUybYic/zNGccKH494naWKJ7zUm+VTgFepJfTrbCCJQ==", + "deprecated": "This is a stub types definition. loglevel provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "loglevel": "*" + } + }, + "node_modules/@types/node": { + "version": "17.0.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz", + "integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==" + }, + "node_modules/@types/p-queue": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz", + "integrity": "sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ==" + }, + "node_modules/@types/prettier": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", + "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==", + "dev": true + }, + "node_modules/@types/webidl-conversions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz", + "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz", + "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.1.tgz", + "integrity": "sha512-xN3CYqFlyE/qOcy978/L0xLR2HlcAGIyIK5sMOasxaaAPfQRj/MmMV6OC3I7NZO84oEUdWCOju34Z9W8E0pFDQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.10.1", + "@typescript-eslint/type-utils": "5.10.1", + "@typescript-eslint/utils": "5.10.1", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.1.tgz", + "integrity": "sha512-GReo3tjNBwR5RnRO0K2wDIDN31cM3MmDtgyQ85oAxAmC5K3j/g85IjP+cDfcqDsDDBf1HNKQAD0WqOYL8jXqUA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.10.1", + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/typescript-estree": "5.10.1", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.1.tgz", + "integrity": "sha512-Lyvi559Gvpn94k7+ElXNMEnXu/iundV5uFmCUNnftbFrUbAJ1WBoaGgkbOBm07jVZa682oaBU37ao/NGGX4ZDg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/visitor-keys": "5.10.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.1.tgz", + "integrity": "sha512-AfVJkV8uck/UIoDqhu+ptEdBoQATON9GXnhOpPLzkQRJcSChkvD//qsz9JVffl2goxX+ybs5klvacE9vmrQyCw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.10.1", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.1.tgz", + "integrity": "sha512-ZvxQ2QMy49bIIBpTqFiOenucqUyjTQ0WNLhBM6X1fh1NNlYAC6Kxsx8bRTY3jdYsYg44a0Z/uEgQkohbR0H87Q==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.1.tgz", + "integrity": "sha512-PwIGnH7jIueXv4opcwEbVGDATjGPO1dx9RkUl5LlHDSe+FXxPwFL5W/qYd5/NHr7f6lo/vvTrAzd0KlQtRusJQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/visitor-keys": "5.10.1", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.1.tgz", + "integrity": "sha512-RRmlITiUbLuTRtn/gcPRi4202niF+q7ylFLCKu4c+O/PcpRvZ/nAUwQ2G00bZgpWkhrNLNnvhZLbDn8Ml0qsQw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.10.1", + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/typescript-estree": "5.10.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.1.tgz", + "integrity": "sha512-NjQ0Xinhy9IL979tpoTRuLKxMc0zJC7QVSdeerXs2/QvOy2yRkzX5dRb10X5woNUdJgU8G3nYRDlI33sq1K4YQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.10.1", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/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 + }, + "node_modules/array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "node_modules/async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "dev": true, + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "dependencies": { + "follow-redirects": "^1.14.7" + } + }, + "node_modules/babel-jest": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.4.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.4.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/bson": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.1.tgz", + "integrity": "sha512-I1LQ7Hz5zgwR4QquilLNZwbhPw0Apx7i7X9kGMBTsqPdml/03Q9NBtD9nt/19ahjlphktQImrnderxqpzeVDjw==", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001301", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz", + "integrity": "sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/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 + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/denque": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", + "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/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, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-14.3.0.tgz", + "integrity": "sha512-PCTcOQSXVo9FI1dB7AichJXMEvmiGCq0gnCpjfDUc8505uR+2MeLXWe+Ue4PN5UXa2isHSa78sr7L59fk+2mnQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.52", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.52.tgz", + "integrity": "sha512-JGkh8HEh5PnVrhU4HbpyyO0O791dVY6k7AdqfDeqbcRMeoGxtNHWT77deR2nhvbLe4dKpxjlDEvdEwrvRLGu2Q==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", + "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "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.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.2.0", + "espree": "^9.3.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "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", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-config-airbnb-typescript": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-16.1.0.tgz", + "integrity": "sha512-W5Cq20KpEx5ZLC54bnVrC37zq2+WD956Kp/Ma3nYFRjT1v9KM63v+DPkrrmmrVqrlDKaD0ivm/qeYmyHV6qKlw==", + "dev": true, + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/parser": "^5.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.2", + "has": "^1.0.3", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.12.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/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, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/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, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/espree": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "dev": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/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, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/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, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/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, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", + "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", + "dev": true, + "dependencies": { + "is-object": "~1.0.1", + "merge-descriptors": "~1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/finity": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/finity/-/finity-0.5.4.tgz", + "integrity": "sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA==" + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-electron": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.0.tgz", + "integrity": "sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q==" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", + "dev": true, + "dependencies": { + "@jest/core": "^27.4.7", + "import-local": "^3.0.2", + "jest-cli": "^27.4.7" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.4.6", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", + "dev": true, + "dependencies": { + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.4.7", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.6", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.4.6", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", + "dev": true, + "dependencies": { + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.4.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", + "dev": true, + "dependencies": { + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-serializer": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.4.6", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", + "natural-compare": "^1.4.0", + "pretty-format": "^27.4.6", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.4", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.4.2", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.4.0", + "leven": "^3.1.0", + "pretty-format": "^27.4.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.4.2", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-worker": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/ws": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/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 + }, + "node_modules/loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/md5-file": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", + "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==", + "dev": true, + "bin": { + "md5-file": "cli.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/module-not-found-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", + "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=", + "dev": true + }, + "node_modules/mongodb": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.3.1.tgz", + "integrity": "sha512-sNa8APSIk+r4x31ZwctKjuPSaeKuvUeNb/fu/3B6dRM02HpEgig7hTHM8A/PJQTlxuC/KFWlDlQjhsk/S43tBg==", + "dependencies": { + "bson": "^4.6.1", + "denque": "^2.0.1", + "mongodb-connection-string-url": "^2.4.1", + "socks": "^2.6.1" + }, + "engines": { + "node": ">=12.9.0" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.4.1.tgz", + "integrity": "sha512-d5Kd2bVsKcSA7YI/yo57fSTtMwRQdFkvc5IZwod1RRxJtECeWPPSo7zqcUGJELifRA//Igs4spVtYAmvFCatug==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-memory-server": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.2.0.tgz", + "integrity": "sha512-ahp93rbJzvqVInJ6EOH4pkdfcm3+5gGQ0WjTQvyB8X3n61jn7yITKGCE0wwvg5JME32XemiQUNAp44XdlD+fpg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "mongodb-memory-server-core": "8.2.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/mongodb-memory-server-core": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.2.0.tgz", + "integrity": "sha512-7NO+PJQ74wpo/e/fJYIvjjkbhMRn27yFTQzZZKf94y1Cqw/2pJZ+RSI8QJclT53/lyVyx0BLgA/ik6viKy4hDg==", + "dev": true, + "dependencies": { + "@types/tmp": "^0.2.3", + "async-mutex": "^0.3.2", + "camelcase": "^6.2.1", + "debug": "^4.3.3", + "find-cache-dir": "^3.3.2", + "get-port": "^5.1.1", + "https-proxy-agent": "^5.0.0", + "md5-file": "^5.0.0", + "mongodb": "^4.2.2", + "new-find-package-json": "^1.1.0", + "semver": "^7.3.5", + "tar-stream": "^2.1.4", + "tmp": "^0.2.1", + "tslib": "^2.3.1", + "uuid": "^8.3.1", + "yauzl": "^2.10.0" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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 + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/new-find-package-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-1.1.0.tgz", + "integrity": "sha512-KOH3BNZcTKPzEkaJgG2iSUaurxKmefqRKmCOYH+8xqJytNIgjqU4J88BHfK+gy/UlEzlhccLyuJDJAcCgexSwA==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "node_modules/nodemon": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", + "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-queue": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz", + "integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-retry": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", + "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", + "dependencies": { + "@types/retry": "^0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/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, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pretty-format": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxyquire": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", + "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", + "dev": true, + "dependencies": { + "fill-keys": "^1.0.2", + "module-not-found-error": "^1.0.1", + "resolve": "^1.11.1" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "dependencies": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-jest": { + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": ">=27.0.0 <28", + "esbuild": "~0.14.0", + "jest": "^27.0.0", + "typescript": ">=3.8 <5.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "dependencies": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", + "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, "dependencies": { "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", + "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "dev": true + }, + "@babel/core": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", + "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.12", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.10", + "@babel/types": "^7.16.8", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", + "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.8", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", + "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", + "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.10", + "@babel/types": "^7.16.8", + "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.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@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 + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "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" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "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" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "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": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz", + "integrity": "sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz", + "integrity": "sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==", + "dev": true, + "requires": { + "@jest/console": "^27.4.6", + "@jest/reporters": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^27.4.2", + "jest-config": "^27.4.7", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-resolve-dependencies": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "jest-watcher": "^27.4.6", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz", + "integrity": "sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==", + "dev": true, + "requires": { + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6" + } + }, + "@jest/fake-timers": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz", + "integrity": "sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" + } + }, + "@jest/globals": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz", + "integrity": "sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/types": "^27.4.2", + "expect": "^27.4.6" + } + }, + "@jest/reporters": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz", + "integrity": "sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + } + }, + "@jest/source-map": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz", + "integrity": "sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz", + "integrity": "sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==", + "dev": true, + "requires": { + "@jest/console": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz", + "integrity": "sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@jest/test-result": "^27.4.6", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-runtime": "^27.4.6" } }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "@jest/transform": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz", + "integrity": "sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==", "dev": true, "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" + "@babel/core": "^7.1.0", + "@jest/types": "^27.4.2", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-util": "^27.4.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" } }, - "@sinonjs/commons": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.0.tgz", - "integrity": "sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg==", + "@jest/types": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", + "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", "dev": true, "requires": { - "type-detect": "4.0.8" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" } }, - "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "@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": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - }, - "dependencies": { - "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" - } - } + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" } }, - "@sinonjs/samsam": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-2.1.3.tgz", - "integrity": "sha512-8zNeBkSKhU9a5cRNbpCKau2WWPfan+Q2zDlcXvXyhn9EsMqgYs4qzo0XHNVlXC6ABQL8fT6nV+zzo5RTHJzyXw==", + "@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 }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "@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" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "@slack/logger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-2.0.0.tgz", @@ -77,15 +8491,15 @@ } }, "@slack/rtm-api": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@slack/rtm-api/-/rtm-api-5.0.3.tgz", - "integrity": "sha512-rzNIFst8iuVYyHdE7e3KSrbAtIA7sfS4Pth9ObKUm5KDemX0zyI7YfAijO1kgr1EMriQkjlpKBhlNq9Y+aQr6g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@slack/rtm-api/-/rtm-api-6.0.0.tgz", + "integrity": "sha512-4jgONmC10/RdV6Q07e6PRUXrORPs2Xhe2gWKcGo49D2rCFy8H8SpM1RxowrVLYXqXUoMt3fIrqu050SuF4iVVA==", "requires": { - "@slack/logger": "^1.0.0", - "@slack/web-api": "^5.1.0", - "@types/node": ">=8.9.0", + "@slack/logger": ">=1.0.0 <3.0.0", + "@slack/web-api": "^5.3.0", + "@types/node": ">=12.0.0", "@types/p-queue": "^2.3.2", - "@types/ws": "^5.1.1", + "@types/ws": "^7.2.5", "eventemitter3": "^3.1.0", "finity": "^0.5.4", "p-cancelable": "^1.1.0", @@ -93,23 +8507,58 @@ "ws": "^5.2.0" }, "dependencies": { - "@slack/logger": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-1.1.1.tgz", - "integrity": "sha512-PAC5CMnNAv/FPtJ0le+YD2wUV+tZ7n3Bnjj9dBI+deIcHsExCnQkQmZE79cLvfuYXbz3PWyv5coti30MJQhEjA==", + "@slack/types": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-1.10.0.tgz", + "integrity": "sha512-tA7GG7Tj479vojfV3AoxbckalA48aK6giGjNtgH6ihpLwTyHE3fIgRrvt8TWfLwW8X8dyu7vgmAsGLRG7hWWOg==" + }, + "@slack/web-api": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.15.0.tgz", + "integrity": "sha512-tjQ8Zqv/Fmj9SOL9yIEd7IpTiKfKHi9DKAkfRVeotoX0clMr3SqQtBqO+KZMX27gm7dmgJsQaDKlILyzdCO+IA==", "requires": { - "@types/node": ">=8.9.0" + "@slack/logger": ">=1.0.0 <3.0.0", + "@slack/types": "^1.7.0", + "@types/is-stream": "^1.1.0", + "@types/node": ">=8.9.0", + "axios": "^0.21.1", + "eventemitter3": "^3.1.0", + "form-data": "^2.5.0", + "is-stream": "^1.1.0", + "p-queue": "^6.6.1", + "p-retry": "^4.0.0" + }, + "dependencies": { + "p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "requires": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "dependencies": { + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + } + } + } } }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } }, "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz", + "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==", "requires": { "async-limiter": "~1.0.0" } @@ -117,72 +8566,147 @@ } }, "@slack/types": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@slack/types/-/types-1.3.0.tgz", - "integrity": "sha512-3AjHsDJjJKT3q0hQzFHQN7piYIh99LuN7Po56W/R6P/uscqZqwS5xm1U1cTYGIzk8fmsuW7TvWVg0W85hKY/MQ==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-2.4.0.tgz", + "integrity": "sha512-0k8UlVEH9gUVwTbwcanS1JT2vCROkr1WESgdXW7d2maWYTuwbVEx87YvXPjsemAJfdu+RYqxGhO2oGTigprepA==" }, "@slack/web-api": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.6.0.tgz", - "integrity": "sha512-/HxTI9/4fMk3su1UAa7oN0n8fGSZLHXGUne3WJ+vjxGek2rvvzazqL6yTRWWWcpttPtsNyjk4KI9FkPq+6yLNg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-6.6.0.tgz", + "integrity": "sha512-4z8tBBIQFojH9uSrsmnI0pGDpOZmJ3UO+Ewwtj3SfkokAUJz3d2dSH5sPk9jKcGfx39e34LoJ+l1YSavvHQeeg==", "requires": { - "@slack/logger": ">=1.0.0 <3.0.0", - "@slack/types": "^1.2.1", + "@slack/logger": "^3.0.0", + "@slack/types": "^2.0.0", "@types/is-stream": "^1.1.0", - "@types/node": ">=8.9.0", - "@types/p-queue": "^2.3.2", - "axios": "^0.18.0", + "@types/node": ">=12.0.0", + "axios": "^0.25.0", "eventemitter3": "^3.1.0", "form-data": "^2.5.0", + "is-electron": "2.2.0", "is-stream": "^1.1.0", - "p-queue": "^2.4.2", + "p-queue": "^6.6.1", "p-retry": "^4.0.0" }, "dependencies": { - "p-retry": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.2.0.tgz", - "integrity": "sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA==", + "@slack/logger": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-3.0.0.tgz", + "integrity": "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA==", + "requires": { + "@types/node": ">=12.0.0" + } + }, + "p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", "requires": { - "@types/retry": "^0.12.0", - "retry": "^0.12.0" + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "dependencies": { + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + } } } } }, - "@types/chai": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.7.tgz", - "integrity": "sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g==", + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, + "@types/babel__core": { + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", + "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, "@types/dotenv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-4.0.3.tgz", - "integrity": "sha512-mmhpINC/HcLGQK5ikFJlLXINVvcxhlrV+ZOUJSN7/ottYl+8X4oSXzS9lBtDkmWAl96EGyGyLrNvk9zqdSH8Fw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz", + "integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==", "dev": true, "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.1.tgz", - "integrity": "sha512-hx6zWtudh3Arsbl3cXay+JnkvVgCKzCWKv42C9J01N2T2np4h8w5X8u6Tpz5mj38kE3M9FM0Pazx8vKFFMnjLQ==", - "dev": true - } } }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "requires": { + "@types/node": "*" + } }, "@types/is-stream": { "version": "1.1.0", @@ -190,155 +8714,234 @@ "integrity": "sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==", "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.1.tgz", - "integrity": "sha512-hx6zWtudh3Arsbl3cXay+JnkvVgCKzCWKv42C9J01N2T2np4h8w5X8u6Tpz5mj38kE3M9FM0Pazx8vKFFMnjLQ==" - } + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz", + "integrity": "sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==", + "dev": true, + "requires": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" } }, "@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/loglevel": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@types/loglevel/-/loglevel-1.6.3.tgz", + "integrity": "sha512-v2YWQQgqtNXAzybOT9qV3CIJqSeoaMUwmBfIMTQdvhsWUybYic/zNGccKH494naWKJ7zUm+VTgFepJfTrbCCJQ==", + "dev": true, + "requires": { + "loglevel": "*" + } + }, "@types/node": { - "version": "10.17.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==" + "version": "17.0.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz", + "integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==" }, "@types/p-queue": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz", "integrity": "sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ==" }, + "@types/prettier": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.3.tgz", + "integrity": "sha512-QzSuZMBuG5u8HqYz01qtMdg/Jfctlnvj1z/lYnIDXs/golxw0fxtRAHd9KrzjR7Yxz1qVeI00o0kiO3PmVdJ9w==", + "dev": true + }, "@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", + "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==" + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==", + "dev": true + }, + "@types/webidl-conversions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz", + "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==" + }, + "@types/whatwg-url": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz", + "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==", + "requires": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } }, "@types/ws": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-5.1.2.tgz", - "integrity": "sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg==", + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "requires": { - "@types/events": "*", "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.1.tgz", - "integrity": "sha512-hx6zWtudh3Arsbl3cXay+JnkvVgCKzCWKv42C9J01N2T2np4h8w5X8u6Tpz5mj38kE3M9FM0Pazx8vKFFMnjLQ==" - } } }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, "@typescript-eslint/eslint-plugin": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.14.0.tgz", - "integrity": "sha512-sneOJ3Hu0m5whJiVIxGBZZZMxMJ7c0LhAJzeMJgHo+n5wFs+/6rSR/gl7crkdR2kNwfOOSdzdc0gMvatG4dX2Q==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.1.tgz", + "integrity": "sha512-xN3CYqFlyE/qOcy978/L0xLR2HlcAGIyIK5sMOasxaaAPfQRj/MmMV6OC3I7NZO84oEUdWCOju34Z9W8E0pFDQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.14.0", - "eslint-utils": "^1.4.3", + "@typescript-eslint/scope-manager": "5.10.1", + "@typescript-eslint/type-utils": "5.10.1", + "@typescript-eslint/utils": "5.10.1", + "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, - "@typescript-eslint/experimental-utils": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.14.0.tgz", - "integrity": "sha512-KcyKS7G6IWnIgl3ZpyxyBCxhkBPV+0a5Jjy2g5HxlrbG2ZLQNFeneIBVXdaBCYOVjvGmGGFKom1kgiAY75SDeQ==", + "@typescript-eslint/parser": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.1.tgz", + "integrity": "sha512-GReo3tjNBwR5RnRO0K2wDIDN31cM3MmDtgyQ85oAxAmC5K3j/g85IjP+cDfcqDsDDBf1HNKQAD0WqOYL8jXqUA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.14.0", - "eslint-scope": "^5.0.0" + "@typescript-eslint/scope-manager": "5.10.1", + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/typescript-estree": "5.10.1", + "debug": "^4.3.2" } }, - "@typescript-eslint/parser": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.14.0.tgz", - "integrity": "sha512-haS+8D35fUydIs+zdSf4BxpOartb/DjrZ2IxQ5sR8zyGfd77uT9ZJZYF8+I0WPhzqHmfafUBx8MYpcp8pfaoSA==", + "@typescript-eslint/scope-manager": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.1.tgz", + "integrity": "sha512-Lyvi559Gvpn94k7+ElXNMEnXu/iundV5uFmCUNnftbFrUbAJ1WBoaGgkbOBm07jVZa682oaBU37ao/NGGX4ZDg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/visitor-keys": "5.10.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.1.tgz", + "integrity": "sha512-AfVJkV8uck/UIoDqhu+ptEdBoQATON9GXnhOpPLzkQRJcSChkvD//qsz9JVffl2goxX+ybs5klvacE9vmrQyCw==", "dev": true, "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.14.0", - "@typescript-eslint/typescript-estree": "2.14.0", - "eslint-visitor-keys": "^1.1.0" + "@typescript-eslint/utils": "5.10.1", + "debug": "^4.3.2", + "tsutils": "^3.21.0" } }, + "@typescript-eslint/types": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.1.tgz", + "integrity": "sha512-ZvxQ2QMy49bIIBpTqFiOenucqUyjTQ0WNLhBM6X1fh1NNlYAC6Kxsx8bRTY3jdYsYg44a0Z/uEgQkohbR0H87Q==", + "dev": true + }, "@typescript-eslint/typescript-estree": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.14.0.tgz", - "integrity": "sha512-pnLpUcMNG7GfFFfNQbEX6f1aPa5fMnH2G9By+A1yovYI4VIOK2DzkaRuUlIkbagpAcrxQHLqovI1YWqEcXyRnA==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.1.tgz", + "integrity": "sha512-PwIGnH7jIueXv4opcwEbVGDATjGPO1dx9RkUl5LlHDSe+FXxPwFL5W/qYd5/NHr7f6lo/vvTrAzd0KlQtRusJQ==", "dev": true, "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash.unescape": "4.0.1", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/visitor-keys": "5.10.1", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.1.tgz", + "integrity": "sha512-RRmlITiUbLuTRtn/gcPRi4202niF+q7ylFLCKu4c+O/PcpRvZ/nAUwQ2G00bZgpWkhrNLNnvhZLbDn8Ml0qsQw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.10.1", + "@typescript-eslint/types": "5.10.1", + "@typescript-eslint/typescript-estree": "5.10.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.1.tgz", + "integrity": "sha512-NjQ0Xinhy9IL979tpoTRuLKxMc0zJC7QVSdeerXs2/QvOy2yRkzX5dRb10X5woNUdJgU8G3nYRDlI33sq1K4YQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.10.1", + "eslint-visitor-keys": "^3.0.0" } }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -346,270 +8949,301 @@ "dev": true }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } }, "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", - "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "debug": "4" } }, "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, "requires": { - "string-width": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "string-width": "^4.1.0" } }, "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, - "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" - } + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "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 }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "is-string": "^1.0.5" - } - }, - "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" } }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "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 }, - "async": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/async/-/async-3.1.1.tgz", - "integrity": "sha512-X5Dj8hK1pJNC2Wzo2Rcp9FBVdJMGRR/S7V+lH46s8GVFhtbo5O4Le5GECCF/8PISVdkUA6mMPvgz7qTTD1rf1g==", - "dev": true + "array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + } }, "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, + "async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "dev": true, + "requires": { + "tslib": "^2.3.1" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "axios": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "requires": { + "follow-redirects": "^1.14.7" + } + }, + "babel-jest": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz", + "integrity": "sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==", + "dev": true, + "requires": { + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.4.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", + "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", + "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "dev": true, "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" + "babel-plugin-jest-hoist": "^27.4.0", + "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "bog": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bog/-/bog-1.0.2.tgz", - "integrity": "sha1-8StAD2YOc1FX/3bJjT8Gs1vAxeY=" - }, "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } } } }, @@ -632,42 +9266,59 @@ "fill-range": "^7.0.1" } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, - "bson": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", - "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" + "browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } }, - "buffer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", - "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "fast-json-stable-stringify": "2.x" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" + "node-int64": "^0.4.0" } }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "bson": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.1.tgz", + "integrity": "sha512-I1LQ7Hz5zgwR4QquilLNZwbhPw0Apx7i7X9kGMBTsqPdml/03Q9NBtD9nt/19ahjlphktQImrnderxqpzeVDjw==", + "requires": { + "buffer": "^5.6.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } }, "buffer-crc32": { "version": "0.2.13", @@ -675,16 +9326,53 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } }, "callsites": { "version": "3.1.0", @@ -693,119 +9381,123 @@ "dev": true }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "caniuse-lite": { + "version": "1.0.30001301", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz", + "integrity": "sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA==", "dev": true }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "requires": { - "check-error": "^1.0.2" - } - }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "check-error": { + "char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, "chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "restore-cursor": "^3.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "combined-stream": { @@ -816,12 +9508,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -835,160 +9521,112 @@ "dev": true }, "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "dev": true, "requires": { - "dot-prop": "^4.1.0", + "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" } }, "confusing-browser-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", - "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", - "dev": true - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { - "capture-stack-trace": "^1.0.0" + "safe-buffer": "~5.1.1" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true }, - "decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "dev": true, "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } } }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" } }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true - } + "ms": "2.1.2" } }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - } + "decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "dev": true, "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - } + "mimic-response": "^1.0.0" } }, "dedent": { @@ -997,15 +9635,6 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -1013,9 +9642,21 @@ "dev": true }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "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 + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, "define-properties": { @@ -1032,48 +9673,76 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "denque": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", + "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, - "dirty-chai": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz", - "integrity": "sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==", + "diff-sequences": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "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", - "isarray": "^1.0.0" + "esutils": "^2.0.2" + } + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", "dev": true } } }, "dot-prop": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz", - "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { - "is-obj": "^1.0.0" + "is-obj": "^2.0.0" } }, "dotenv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", - "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-14.3.0.tgz", + "integrity": "sha512-PCTcOQSXVo9FI1dB7AichJXMEvmiGCq0gnCpjfDUc8505uR+2MeLXWe+Ue4PN5UXa2isHSa78sr7L59fk+2mnQ==" }, "duplexer3": { "version": "0.1.4", @@ -1081,6 +9750,18 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "electron-to-chromium": { + "version": "1.4.52", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.52.tgz", + "integrity": "sha512-JGkh8HEh5PnVrhU4HbpyyO0O791dVY6k7AdqfDeqbcRMeoGxtNHWT77deR2nhvbLe4dKpxjlDEvdEwrvRLGu2Q==", + "dev": true + }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1096,32 +9777,32 @@ "once": "^1.4.0" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, "es-abstract": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz", - "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -1135,203 +9816,235 @@ "is-symbol": "^1.0.2" } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "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 }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "requires": { - "es6-promise": "^4.0.3" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "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 + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", + "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.2.0", + "espree": "^9.3.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", "dev": true, "requires": { - "esutils": "^2.0.2" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } }, - "eslint-config-airbnb": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.0.1.tgz", - "integrity": "sha512-hLb/ccvW4grVhvd6CT83bECacc+s4Z3/AEyWQdIT2KeTsG9dR7nx1gs7Iw4tDmGKozCNHFn4yZmRm3Tgy+XxyQ==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^14.0.0", - "object.assign": "^4.1.0", - "object.entries": "^1.1.0" - } - }, "eslint-config-airbnb-base": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", - "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", "dev": true, "requires": { - "confusing-browser-globals": "^1.0.7", - "object.assign": "^4.1.0", - "object.entries": "^1.1.0" + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "eslint-config-airbnb-typescript": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-6.3.1.tgz", - "integrity": "sha512-+tkkVysaN63zXz+oiPfkfYSRMIY5QfHI4qFeyb1ZhRGF2jR6JslqDv5GkrW/eciySNTVTigFvf9hkqHT9vklJw==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-16.1.0.tgz", + "integrity": "sha512-W5Cq20KpEx5ZLC54bnVrC37zq2+WD956Kp/Ma3nYFRjT1v9KM63v+DPkrrmmrVqrlDKaD0ivm/qeYmyHV6qKlw==", "dev": true, "requires": { - "@typescript-eslint/parser": "^2.3.0", - "eslint-config-airbnb": "^18.0.1", - "eslint-config-airbnb-base": "^14.0.0" + "eslint-config-airbnb-base": "^15.0.0" } }, "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" + "debug": "^3.2.7", + "resolve": "^1.20.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } } } }, "eslint-module-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz", - "integrity": "sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", "dev": true, "requires": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" + "debug": "^3.2.7", + "find-up": "^2.1.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } } } }, "eslint-plugin-import": { - "version": "2.19.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz", - "integrity": "sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", "dev": true, "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.2", "has": "^1.0.3", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.12.0" }, "dependencies": { "debug": { @@ -1342,43 +10055,66 @@ "requires": { "ms": "2.0.0" } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "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.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "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": "^1.1.0" + "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": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", "dev": true }, "espree": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", - "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", "dev": true, "requires": { - "acorn": "^7.1.0", - "acorn-jsx": "^5.1.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" } }, "esprima": { @@ -1388,21 +10124,37 @@ "dev": true }, "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "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.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "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": "^4.1.0" + "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": { @@ -1423,50 +10175,78 @@ "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" }, "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true } } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expect": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz", + "integrity": "sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==", "dev": true, "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "@jest/types": "^27.4.2", + "jest-get-type": "^27.4.0", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6" } }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "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" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "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", @@ -1479,6 +10259,24 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "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" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -1488,30 +10286,15 @@ "pend": "~1.2.0" } }, - "figures": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", - "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "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": "^2.0.1" + "flat-cache": "^3.0.4" } }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true - }, "fill-keys": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", @@ -1532,97 +10315,16 @@ } }, "find-cache-dir": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz", - "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^3.0.0", + "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, - "find-package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", - "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==", - "dev": true - }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -1638,29 +10340,25 @@ "integrity": "sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA==" }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "=3.1.0" - } + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" }, "form-data": { "version": "2.5.1", @@ -1685,9 +10383,9 @@ "dev": true }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -1703,10 +10401,33 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, "get-port": { @@ -1716,24 +10437,25 @@ "dev": true }, "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "getos": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.4.tgz", - "integrity": "sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw==", + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "requires": { - "async": "^3.1.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -1745,67 +10467,80 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "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.1" + "is-glob": "^4.0.3" } }, "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", "dev": true, "requires": { - "ini": "^1.3.4" + "ini": "2.0.0" } }, "globals": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", - "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "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" } }, "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", "dev": true, "requires": { - "create-error-class": "^3.0.0", + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } } }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "has": { @@ -1817,40 +10552,87 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "agent-base": "6", + "debug": "4" } }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1861,15 +10643,14 @@ } }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "ignore-by-default": { @@ -1879,21 +10660,13 @@ "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "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" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } } }, "import-lazy": { @@ -1902,6 +10675,16 @@ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -1925,37 +10708,35 @@ "dev": true }, "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, - "inquirer": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.1.tgz", - "integrity": "sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw==", + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.2.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } }, "is-binary-path": { "version": "2.1.0", @@ -1966,31 +10747,61 @@ "binary-extensions": "^2.0.0" } }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + } + } + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "dev": true, "requires": { - "ci-info": "^1.5.0" + "has": "^1.0.3" } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-electron": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.0.tgz", + "integrity": "sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q==" }, "is-extglob": { "version": "2.1.1", @@ -2004,35 +10815,41 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dev": true, "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" } }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", "dev": true }, "is-number": { @@ -2041,52 +10858,53 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", "dev": true }, "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { - "has": "^1.0.3" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", "dev": true }, "is-stream": { @@ -2095,31 +10913,586 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz", + "integrity": "sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==", + "dev": true, + "requires": { + "@jest/core": "^27.4.7", + "import-local": "^3.0.2", + "jest-cli": "^27.4.7" + } + }, + "jest-changed-files": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz", + "integrity": "sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz", + "integrity": "sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.4.6", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + } + }, + "jest-cli": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz", + "integrity": "sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==", + "dev": true, + "requires": { + "@jest/core": "^27.4.7", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.4.7", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + } + }, + "jest-config": { + "version": "27.4.7", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz", + "integrity": "sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==", + "dev": true, + "requires": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.4.6", + "@jest/types": "^27.4.2", + "babel-jest": "^27.4.6", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.4.6", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-jasmine2": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-runner": "^27.4.6", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", + "slash": "^3.0.0" + } + }, + "jest-diff": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", + "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.4.0", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" + } + }, + "jest-docblock": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz", + "integrity": "sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz", + "integrity": "sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "jest-get-type": "^27.4.0", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6" + } + }, + "jest-environment-jsdom": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz", + "integrity": "sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2", + "jsdom": "^16.6.0" + } + }, + "jest-environment-node": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz", + "integrity": "sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "jest-mock": "^27.4.6", + "jest-util": "^27.4.2" + } + }, + "jest-get-type": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", + "dev": true + }, + "jest-haste-map": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz", + "integrity": "sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.4.0", + "jest-serializer": "^27.4.0", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz", + "integrity": "sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.4.6", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "pretty-format": "^27.4.6", + "throat": "^6.0.1" + } + }, + "jest-leak-detector": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", + "integrity": "sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==", + "dev": true, + "requires": { + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" + } + }, + "jest-matcher-utils": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", + "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "pretty-format": "^27.4.6" + } + }, + "jest-message-util": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz", + "integrity": "sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.4.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.4.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz", + "integrity": "sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", + "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "dev": true + }, + "jest-resolve": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz", + "integrity": "sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.4.2", + "jest-validate": "^27.4.6", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz", + "integrity": "sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "jest-regex-util": "^27.4.0", + "jest-snapshot": "^27.4.6" + } + }, + "jest-runner": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz", + "integrity": "sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==", + "dev": true, + "requires": { + "@jest/console": "^27.4.6", + "@jest/environment": "^27.4.6", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.4.0", + "jest-environment-jsdom": "^27.4.6", + "jest-environment-node": "^27.4.6", + "jest-haste-map": "^27.4.6", + "jest-leak-detector": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-resolve": "^27.4.6", + "jest-runtime": "^27.4.6", + "jest-util": "^27.4.2", + "jest-worker": "^27.4.6", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + } + }, + "jest-runtime": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz", + "integrity": "sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.4.6", + "@jest/fake-timers": "^27.4.6", + "@jest/globals": "^27.4.6", + "@jest/source-map": "^27.4.0", + "@jest/test-result": "^27.4.6", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-mock": "^27.4.6", + "jest-regex-util": "^27.4.0", + "jest-resolve": "^27.4.6", + "jest-snapshot": "^27.4.6", + "jest-util": "^27.4.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-serializer": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", + "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz", + "integrity": "sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.4.6", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.4.6", + "jest-get-type": "^27.4.0", + "jest-haste-map": "^27.4.6", + "jest-matcher-utils": "^27.4.6", + "jest-message-util": "^27.4.6", + "jest-util": "^27.4.2", + "natural-compare": "^1.4.0", + "pretty-format": "^27.4.6", + "semver": "^7.3.2" + } + }, + "jest-util": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", + "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.4", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz", + "integrity": "sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.4.0", + "leven": "^3.1.0", + "pretty-format": "^27.4.6" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz", + "integrity": "sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "@jest/test-result": "^27.4.6", + "@jest/types": "^27.4.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.4.2", + "string-length": "^4.0.1" } }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "jest-worker": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } }, "js-tokens": { "version": "4.0.0", @@ -2128,15 +11501,81 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "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" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "ws": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "dev": true, + "requires": {} + } } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -2149,41 +11588,53 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", - "dev": true + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } }, - "latest-version": { + "keyv": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "dev": true, "requires": { - "package-json": "^4.0.0" + "json-buffer": "3.0.0" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "package-json": "^6.3.0" } }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "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": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "locate-path": { @@ -2196,38 +11647,28 @@ "path-exists": "^3.0.0" } }, - "lockfile": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", - "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", - "dev": true, - "requires": { - "signal-exit": "^3.0.2" - } - }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "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 }, - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true + "loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==" }, "lowercase-keys": { "version": "1.0.1", @@ -2236,41 +11677,49 @@ "dev": true }, "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "yallist": "^4.0.0" } }, "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "pify": "^3.0.0" + "semver": "^6.0.0" }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } }, "md5-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-4.0.0.tgz", - "integrity": "sha512-UC0qFwyAjn4YdPpKaDNw6gNxRf7Mcx7jC1UGCY4boCzgvU2Aoc1mOGzTtrjjLKhM5ivsnhoKpQVxKPp+1j1qwg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", + "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==", "dev": true }, "memory-pager": { @@ -2285,17 +11734,39 @@ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "requires": { - "mime-db": "1.42.0" + "mime-db": "1.51.0" } }, "mimic-fn": { @@ -2304,6 +11775,12 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2314,43 +11791,10 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - } + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "module-not-found-error": { "version": "1.0.1", @@ -2359,90 +11803,96 @@ "dev": true }, "mongodb": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.4.1.tgz", - "integrity": "sha512-juqt5/Z42J4DcE7tG7UdVaTKmUC6zinF4yioPfpeOSNBieWSK6qCY+0tfGQcHLKrauWPDdMZVROHJOa8q2pWsA==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.3.1.tgz", + "integrity": "sha512-sNa8APSIk+r4x31ZwctKjuPSaeKuvUeNb/fu/3B6dRM02HpEgig7hTHM8A/PJQTlxuC/KFWlDlQjhsk/S43tBg==", + "requires": { + "bson": "^4.6.1", + "denque": "^2.0.1", + "mongodb-connection-string-url": "^2.4.1", + "saslprep": "^1.0.3", + "socks": "^2.6.1" + } + }, + "mongodb-connection-string-url": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.4.1.tgz", + "integrity": "sha512-d5Kd2bVsKcSA7YI/yo57fSTtMwRQdFkvc5IZwod1RRxJtECeWPPSo7zqcUGJELifRA//Igs4spVtYAmvFCatug==", "requires": { - "bson": "^1.1.1", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + }, + "dependencies": { + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + } } }, "mongodb-memory-server": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-5.2.7.tgz", - "integrity": "sha512-ChAU/2/STOb9I2AZl+a1NRXHIk8CqeWQPPXTzZJwOMqiXTwo5fQQzWUhIDtZvQsCYyVpP1FW9lagSzJopIE0Tg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.2.0.tgz", + "integrity": "sha512-ahp93rbJzvqVInJ6EOH4pkdfcm3+5gGQ0WjTQvyB8X3n61jn7yITKGCE0wwvg5JME32XemiQUNAp44XdlD+fpg==", "dev": true, "requires": { - "mongodb-memory-server-core": "5.2.7" + "mongodb-memory-server-core": "8.2.0", + "tslib": "^2.3.1" } }, "mongodb-memory-server-core": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-5.2.7.tgz", - "integrity": "sha512-jU9Zb69DkhExF2hNjUB3TkSfHz3z06OdO1uYSrvYrD3sPxo4emuSR2zuXgQR34PegUrNnkrPXNMLIv2CgxWrpw==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "cross-spawn": "^6.0.5", - "debug": "^4.1.1", - "decompress": "^4.2.0", - "dedent": "^0.7.0", - "find-cache-dir": "^3.0.0", - "find-package-json": "^1.2.0", - "get-port": "^5.0.0", - "getos": "^3.1.1", - "https-proxy-agent": "^2.2.1", - "lockfile": "^1.0.4", - "md5-file": "^4.0.0", - "mkdirp": "^0.5.1", - "mongodb": ">=3.2.7", - "tmp": "^0.1.0", - "uuid": "^3.2.1" + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.2.0.tgz", + "integrity": "sha512-7NO+PJQ74wpo/e/fJYIvjjkbhMRn27yFTQzZZKf94y1Cqw/2pJZ+RSI8QJclT53/lyVyx0BLgA/ik6viKy4hDg==", + "dev": true, + "requires": { + "@types/tmp": "^0.2.3", + "async-mutex": "^0.3.2", + "camelcase": "^6.2.1", + "debug": "^4.3.3", + "find-cache-dir": "^3.3.2", + "get-port": "^5.1.1", + "https-proxy-agent": "^5.0.0", + "md5-file": "^5.0.0", + "mongodb": "^4.2.2", + "new-find-package-json": "^1.1.0", + "semver": "^7.3.5", + "tar-stream": "^2.1.4", + "tmp": "^0.2.1", + "tslib": "^2.3.1", + "uuid": "^8.3.1", + "yauzl": "^2.10.0" }, "dependencies": { "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true - }, - "tmp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", - "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", - "dev": true, - "requires": { - "rimraf": "^2.6.3" - } } } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "natural-compare": { @@ -2451,67 +11901,65 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "nise": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", - "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", + "new-find-package-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-1.1.0.tgz", + "integrity": "sha512-KOH3BNZcTKPzEkaJgG2iSUaurxKmefqRKmCOYH+8xqJytNIgjqU4J88BHfK+gy/UlEzlhccLyuJDJAcCgexSwA==", "dev": true, "requires": { - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^5.0.1", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - } + "debug": "^4.3.2", + "tslib": "^2.3.0" } }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, "nodemon": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.2.tgz", - "integrity": "sha512-GWhYPMfde2+M0FsHnggIHXTqPDHXia32HRhh6H0d75Mt9FKUoCBvumNHr7LdrpPBTKxsWmIEOjoN+P4IU6Hcaw==", + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.15.tgz", + "integrity": "sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA==", "dev": true, "requires": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", + "chokidar": "^3.5.2", + "debug": "^3.2.7", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", + "pstree.remy": "^1.1.8", "semver": "^5.7.1", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^2.5.0" + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "supports-color": { @@ -2534,43 +11982,37 @@ "abbrev": "1" } }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "path-key": "^2.0.0" + "path-key": "^3.0.0" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true }, "object-keys": { @@ -2580,39 +12022,37 @@ "dev": true }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, "object.entries": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", - "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "once": { @@ -2625,39 +12065,37 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "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.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "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", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { "version": "1.3.0", @@ -2682,6 +12120,23 @@ "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz", "integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==" }, + "p-retry": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", + "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", + "requires": { + "@types/retry": "^0.12.0", + "retry": "^0.13.1" + } + }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "requires": { + "p-finally": "^1.0.0" + } + }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", @@ -2689,15 +12144,23 @@ "dev": true }, "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "dev": true, "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "parent-module": { @@ -2709,14 +12172,11 @@ "callsites": "^3.0.0" } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true }, "path-exists": { "version": "3.0.0", @@ -2730,46 +12190,22 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, "pend": { @@ -2778,65 +12214,124 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true }, "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "find-up": "^2.1.0" + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } } }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "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-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "pretty-format": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", + "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } }, "proxyquire": { "version": "2.1.3", @@ -2849,22 +12344,46 @@ "resolve": "^1.11.1" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "pstree.remy": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", - "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "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 }, "rc": { @@ -2879,6 +12398,12 @@ "strip-json-comments": "~2.0.1" }, "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -2887,175 +12412,145 @@ } } }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "readdirp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", - "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { - "picomatch": "^2.0.7" + "picomatch": "^2.2.1" } }, "regexpp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", - "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" + "rc": "^1.2.8" } }, "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "dev": true, "requires": { - "rc": "^1.0.1" + "rc": "^1.2.8" } }, - "require_optional": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, "requires": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, - "resolve": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz", - "integrity": "sha512-fn5Wobh4cxbLzuHaE+nphztHy43/b++4M6SsGFC2gB8uYwf0C8LcarfCz1un7UTW8OFQg9iNjZ4xpcFVGebDPg==", + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "resolve-from": "^5.0.0" + }, + "dependencies": { + "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 + } } }, "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + "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 }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", "dev": true, "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "lowercase-keys": "^1.0.0" } }, "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + "version": "0.13.1", + "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": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" } }, - "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "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": { - "tslib": "^1.9.0" + "queue-microtask": "^1.2.2" } }, "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -3072,123 +12567,110 @@ "sparse-bitfield": "^3.0.3" } }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "dev": true, "requires": { - "commander": "~2.8.1" - }, - "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - } + "xmlchars": "^2.2.0" } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", "dev": true, "requires": { - "semver": "^5.0.3" + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "sinon": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-6.3.5.tgz", - "integrity": "sha512-xgoZ2gKjyVRcF08RrIQc+srnSyY1JDJtxu3Nsz07j1ffjgXoY6uPLf/qja6nDBZgzYYEovVkFryw2+KiZz11xQ==", + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "requires": { - "@sinonjs/commons": "^1.0.2", - "@sinonjs/formatio": "^3.0.0", - "@sinonjs/samsam": "^2.1.2", - "diff": "^3.5.0", - "lodash.get": "^4.4.2", - "lolex": "^2.7.5", - "nise": "^1.4.5", - "supports-color": "^5.5.0", - "type-detect": "^4.0.8" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" } }, - "sinon-chai": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.4.0.tgz", - "integrity": "sha512-BpVxsjEkGi6XPbDXrgWUe7Cb1ZzIfxKUbu/MmH5RoUnS7AXpKo3aIYIyQUg0FMvlUL05aPt7VZuAdaeQhEnWxg==", + "signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", "dev": true }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" } }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -3203,215 +12685,177 @@ "memory-pager": "^1.0.2" } }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } } }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "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==", + "dev": true + } } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", + "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } + "ansi-regex": "^5.0.1" } }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "dev": true, - "requires": { - "is-natural-number": "^4.0.1" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" } }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "requires": { - "execa": "^0.7.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } }, "text-table": { @@ -3420,31 +12864,37 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "rimraf": "^3.0.0" } }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "dev": true }, "to-regex-range": { @@ -3465,43 +12915,127 @@ "nopt": "~1.0.10" } }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", + "punycode": "^2.1.1" + } + }, + "ts-jest": { + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + } + }, + "ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "dependencies": { + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + } + } + }, + "tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true }, "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "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" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "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.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -3511,95 +13045,96 @@ "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "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 }, - "typescript": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz", - "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==" - }, - "unbzip2-stream": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", - "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" + "is-typedarray": "^1.0.0" } }, - "undefsafe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", - "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==" + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", "dev": true, "requires": { - "debug": "^2.2.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" } }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dev": true, "requires": { - "crypto-random-string": "^1.0.0" + "crypto-random-string": "^2.0.0" } }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, "update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", "dev": true, "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", "dev": true, "requires": { - "prepend-http": "^1.0.1" + "prepend-http": "^2.0.0" } }, "util-deprecate": { @@ -3609,76 +13144,124 @@ "dev": true }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "requires": { - "string-width": "^2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "string-width": "^4.0.0" } }, "word-wrap": { @@ -3687,56 +13270,90 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "requires": { - "async-limiter": "~1.0.0" - } + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", + "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", + "requires": {} }, "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "xml-name-validator": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true }, "yauzl": { @@ -3750,9 +13367,9 @@ } }, "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" } } } diff --git a/package.json b/package.json index ce82f22..db94e25 100644 --- a/package.json +++ b/package.json @@ -6,40 +6,36 @@ "start": "NODE_ENV=production ts-node ./src/server.ts", "dev": "NODE_ENV=development nodemon --ignore '/test/*.ts' --watch '*.ts' --exec 'ts-node' ./src/server.ts", "mockDB": "ts-node ./test/lib/mockDatabase.ts", - "test": "NODE_ENV=testing mocha -r ts-node/register test/*-test.ts --exit", + "test": "NODE_ENV=testing jest", "lint": "eslint --ext .ts ./src/ || exit 0", "docker-build": "docker build -t chralp/heyburrito . && docker tag chralp/heyburrito chralp/heyburrito", "docker-push": "docker push chralp/heyburrito" }, "license": "MIT", "dependencies": { - "@slack/rtm-api": "^5.0.3", - "@slack/web-api": "^5.6.0", - "bog": "^1.0.2", - "dotenv": "^6.0.0", - "mongodb": "^3.4.0", - "ts-node": "^7.0.1", - "typescript": "^3.7.4", - "ws": "^6.2.1" + "@slack/rtm-api": "^6.0.0", + "@slack/web-api": "^6.6.0", + "dotenv": "^14.3.0", + "loglevel": "^1.8.0", + "mongodb": "^4.3.1", + "ts-node": "^10.4.0", + "typescript": "^4.5.5", + "ws": "^8.4.2" }, "devDependencies": { - "@types/chai": "^4.2.7", - "@types/dotenv": "^4.0.3", - "@types/mocha": "^5.2.7", - "@types/node": "^10.17.9", - "@typescript-eslint/eslint-plugin": "^2.14.0", - "@typescript-eslint/parser": "^2.14.0", - "chai": "^4.2.0", - "chai-as-promised": "^7.1.1", - "dirty-chai": "^2.0.1", - "eslint": "^6.8.0", - "eslint-config-airbnb-typescript": "^6.3.1", - "eslint-plugin-import": "^2.19.1", - "mocha": "^5.2.0", - "mongodb-memory-server": "5.2.7", - "nodemon": "^2.0.2", + "@types/dotenv": "^6.1.1", + "@types/jest": "^27.4.0", + "@types/loglevel": "^1.6.3", + "@types/node": "^17.0.10", + "@typescript-eslint/eslint-plugin": "^5.10.1", + "@typescript-eslint/parser": "^5.10.1", + "eslint": "^8.7.0", + "eslint-config-airbnb-typescript": "^16.1.0", + "eslint-plugin-import": "^2.25.4", + "jest": "^27.4.7", + "mongodb-memory-server": "8.2.0", + "nodemon": "^2.0.15", "proxyquire": "^2.1.3", - "sinon": "^6.3.5", - "sinon-chai": "^3.2.0" + "ts-jest": "^27.1.3" } } diff --git a/src/api/Route.ts b/src/api/Route.ts index 5024524..c7d5f53 100644 --- a/src/api/Route.ts +++ b/src/api/Route.ts @@ -1,5 +1,4 @@ -import log from 'bog'; - +import log from 'loglevel'; // Defaults const ALLOWED_VERBS: string[] = ['post', 'get']; @@ -8,96 +7,96 @@ const ALLOWED_VERBS: string[] = ['post', 'get']; * "Clean up path", split by / and remove args */ const cleanUp = (path: string) => { - const arr = path.split('/'); - const result = arr.map((x) => { - if (x.length && !x.match(/{/)) return x; - return undefined; - }).filter((y: any) => y); - return result; + const arr = path.split('/'); + const result = arr.map((x) => { + if (x.length && !x.match(/{/)) return x; + return undefined; + }).filter((y: any) => y); + return result; }; /** * Api route handler */ class Route { - /** - * Save All routes in array - */ - apiRoutes = []; - - /** - * Add / register endpoints - * check if endpoint is allowed and if it already exists - */ - add({ method, path, handler }): void { - const methodLow = method.toLowerCase(); - if (ALLOWED_VERBS.includes(methodLow)) { - if (!this.apiRoutes.length) { - this.apiRoutes.push({ method: methodLow, path, handler }); - } else { - this.apiRoutes.map((x) => { - if (x.path === path && x.method === methodLow) { - throw new Error(`API endpoint already registerd, method: ${methodLow}, path: ${path}`); - } else { - this.apiRoutes.push({ method: methodLow, path, handler }); - } - return undefined; - }); - } - } else { - throw new Error(`Method not allowed, method: ${method}, path: ${path}`); - } + /** + * Save All routes in array + */ + apiRoutes = []; + + /** + * Add / register endpoints + * check if endpoint is allowed and if it already exists + */ + add({ method, path, handler }): void { + const methodLow = method.toLowerCase(); + if (ALLOWED_VERBS.includes(methodLow)) { + if (!this.apiRoutes.length) { + this.apiRoutes.push({ method: methodLow, path, handler }); + } else { + this.apiRoutes.map((x) => { + if (x.path === path && x.method === methodLow) { + throw new Error(`API endpoint already registerd, method: ${methodLow}, path: ${path}`); + } else { + this.apiRoutes.push({ method: methodLow, path, handler }); + } + return undefined; + }); + } + } else { + throw new Error(`Method not allowed, method: ${method}, path: ${path}`); } - + } + + /** + * Check request if path is registerd + * Also get all params posted and assign to request object + */ + check({ method, path, req }) { + log.debug('Route :: check :: ', method, path); /** - * Check request if path is registerd - * Also get all params posted and assign to request object + * Get registerd endpoint, match method and path. */ - check({ method, path, req }) { - log.debug('Route :: check :: ', method, path); - /** - * Get registerd endpoint, match method and path. - */ - const [route] = this.apiRoutes.filter((x) => { - // Clean up paths - const routeSplitted: string[] = cleanUp(x.path); - const reqSplitted: string[] = cleanUp(path); - - const routeUrl = routeSplitted.map((s) => `${s}/`).join(''); - const reqUrl = reqSplitted.map((r) => `${r}/`).join(''); - if (method === x.method && reqUrl.startsWith(routeUrl)) return x; - return undefined; - }).filter((y: any) => y); + const [route] = this.apiRoutes.filter((x) => { + // Clean up paths + const routeSplitted: string[] = cleanUp(x.path); + const reqSplitted: string[] = cleanUp(path); + + const routeUrl = routeSplitted.map((s) => `${s}/`).join(''); + const reqUrl = reqSplitted.map((r) => `${r}/`).join(''); + if (method === x.method && reqUrl.startsWith(routeUrl)) return x; + return undefined; + }).filter((y: any) => y); - // Unless route not found, return error - if (!route) return { error: true }; + // Unless route not found, return error + if (!route) return { error: true }; - // Args that we want - const routeArgs = route.path.match(/{(.*?)}/gmi); + // Args that we want + const routeArgs = route.path.match(/{(.*?)}/gmi); - // Get args from request - const routePath = route.path.split('/'); - const reqPath = path.split('/'); + // Get args from request + const routePath = route.path.split('/'); + const reqPath = path.split('/'); - const reqArgs = reqPath.filter((x) => !routePath.includes(x)); + const reqArgs = reqPath.filter((x) => !routePath.includes(x)); - const args = reqArgs.map((x) => { - const key = routeArgs.shift(); - const keyClean = key ? key.replace(/\{|\}/gi, '') : undefined; - if (keyClean) return { [keyClean]: x }; - return undefined; - }).filter((y: any) => y); + const args = reqArgs.map((x) => { + const key = routeArgs.shift(); + const keyClean = key ? key.replace(/\{|\}/gi, '') : undefined; + if (keyClean) return { [keyClean]: x }; + return undefined; + }).filter((y: any) => y); - // Merge objects to one object - const argsObject = args.reduce((r, c) => ({ ...r, ...c }), {}); + // Merge objects to one object + const argsObject = args.reduce((r, c) => ({ ...r, ...c }), {}); - // Add args to req object - req.params = argsObject; + // Add args to req object + req.params = argsObject; - // Plocka ut params from url - const request = req; - return { route, request }; - } + // Plocka ut params from url + const request = req; + return { route, request }; + } } export default new Route(); diff --git a/src/api/index.ts b/src/api/index.ts index 1a4f5be..a91cab9 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,4 +1,4 @@ -import log from 'bog'; +import log from 'loglevel'; import Route from './Route'; import { getScoreBoard, getUserStats, givenBurritosToday, getUserScore } from '../middleware'; import config from '../config'; @@ -10,13 +10,13 @@ import Http from '../types/Http'; const apiPath: string = config.http.api_path; const ALLOWED_LISTTYPES: string[] = [ - 'to', - 'from', + 'to', + 'from', ]; const ALLOWED_SCORETYPES: string[] = [ - 'inc', - 'dec', + 'inc', + 'dec', ]; /** @@ -26,144 +26,144 @@ const ALLOWED_SCORETYPES: string[] = [ * @params { number } statuscode */ const response = (content: Http.Response, res: any, statusCode: number = 200): void => { - res.writeHead(statusCode, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify(content), 'utf-8'); + res.writeHead(statusCode, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(content), 'utf-8'); }; Route.add({ - method: 'GET', - path: `${apiPath}userstats/today/{user}`, - handler: async (request: any, res: any) => { - try { - const { user } = request.params; - if (!user) { - throw ({ - message: 'You must provide slack userid', - code: 500, - }); - } - - const score = await givenBurritosToday(user); - - const data = { - error: false, - code: 200, - message: 'ok', - data: score, - }; - - return response(data, res); - } catch (err) { - log.warn(err); - return response({ - error: true, - code: err.code || 500, - message: err.message, - data: null, - }, res, err.code || 500); - } - }, + method: 'GET', + path: `${apiPath}userstats/today/{user}`, + handler: async (request: any, res: any) => { + try { + const { user } = request.params; + if (!user) { + throw ({ + message: 'You must provide slack userid', + code: 500, + }); + } + + const score = await givenBurritosToday(user); + + const data = { + error: false, + code: 200, + message: 'ok', + data: score, + }; + + return response(data, res); + } catch (err) { + log.warn(err); + return response({ + error: true, + code: err.code || 500, + message: err.message, + data: null, + }, res, err.code || 500); + } + }, }); Route.add({ - method: 'GET', - path: `${apiPath}scoreboard/{listType}/{scoreTypeInput}`, - handler: async (request: any, res: any) => { - try { - const { listType, scoreTypeInput } = request.params; - - const scoreType = scoreTypeInput || 'inc'; - - if (!ALLOWED_LISTTYPES.includes(listType)) { - throw ({ - message: 'Allowed listType is to or from', - code: 400, - }); - } - - if (!ALLOWED_SCORETYPES.includes(scoreType)) { - throw ({ - message: 'Allowed scoreType is inc or dec', - code: 400, - }); - } - - const score = await getScoreBoard(listType, scoreType); - - const data = { - error: false, - code: 200, - message: 'ok', - data: score, - }; - - return response(data, res); - } catch (err) { - log.warn(err); - return response({ - error: true, - code: err.code || 500, - message: err.message, - data: null, - }, res, err.code || 500); - } - }, + method: 'GET', + path: `${apiPath}scoreboard/{listType}/{scoreTypeInput}`, + handler: async (request: any, res: any) => { + try { + const { listType, scoreTypeInput } = request.params; + + const scoreType = scoreTypeInput || 'inc'; + + if (!ALLOWED_LISTTYPES.includes(listType)) { + throw ({ + message: 'Allowed listType is to or from', + code: 400, + }); + } + + if (!ALLOWED_SCORETYPES.includes(scoreType)) { + throw ({ + message: 'Allowed scoreType is inc or dec', + code: 400, + }); + } + + const score = await getScoreBoard(listType, scoreType); + + const data = { + error: false, + code: 200, + message: 'ok', + data: score, + }; + + return response(data, res); + } catch (err) { + log.warn(err); + return response({ + error: true, + code: err.code || 500, + message: err.message, + data: null, + }, res, err.code || 500); + } + }, }); /** * Add route for userScore */ Route.add({ - method: 'GET', - path: `${apiPath}userscore/{user}/{listType}/{scoreType}`, - handler: async (request: any, res: any) => { - try { - const { user: userId, listType, scoreType } = request.params; - - if (!userId) { - throw ({ - message: 'You must provide slack userid', - code: 500, - }); - } - - if (!ALLOWED_LISTTYPES.includes(listType)) { - throw ({ - message: 'Allowed listType is to or from', - code: 400, - }); - } - - if (!ALLOWED_SCORETYPES.includes(scoreType)) { - throw ({ - message: 'Allowed scoreType is inc or dec', - code: 400, - }); - } - - const { ...result } = await getUserScore(userId, listType, scoreType); - - const data = { - error: false, - code: 200, - message: 'ok', - data: { - ...result, - }, - }; - return response(data, res); - } catch (err) { - log.warn(err); - return response({ - error: true, - code: err.code || 500, - message: err.message, - data: null, - }, res, err.code || 500); - } - }, + method: 'GET', + path: `${apiPath}userscore/{user}/{listType}/{scoreType}`, + handler: async (request: any, res: any) => { + try { + const { user: userId, listType, scoreType } = request.params; + + if (!userId) { + throw ({ + message: 'You must provide slack userid', + code: 500, + }); + } + + if (!ALLOWED_LISTTYPES.includes(listType)) { + throw ({ + message: 'Allowed listType is to or from', + code: 400, + }); + } + + if (!ALLOWED_SCORETYPES.includes(scoreType)) { + throw ({ + message: 'Allowed scoreType is inc or dec', + code: 400, + }); + } + + const { ...result } = await getUserScore(userId, listType, scoreType); + + const data = { + error: false, + code: 200, + message: 'ok', + data: { + ...result, + }, + }; + return response(data, res); + } catch (err) { + log.warn(err); + return response({ + error: true, + code: err.code || 500, + message: err.message, + data: null, + }, res, err.code || 500); + } + }, }); @@ -171,77 +171,77 @@ Route.add({ * Add route for userstats */ Route.add({ - method: 'GET', - path: `${apiPath}userstats/{user}`, - handler: async (request: any, res: any) => { - try { - const { user: userId } = request.params; - - if (!userId) { - throw ({ - message: 'You must provide slack userid', - code: 500, - }); - } - - const { ...result } = await getUserStats(userId); - - const data = { - error: false, - code: 200, - message: 'ok', - data: { - ...result, - }, - }; - return response(data, res); - } catch (err) { - log.warn(err); - return response({ - error: true, - code: err.code || 500, - message: err.message, - data: null, - }, res, err.code || 500); - } - }, + method: 'GET', + path: `${apiPath}userstats/{user}`, + handler: async (request: any, res: any) => { + try { + const { user: userId } = request.params; + + if (!userId) { + throw ({ + message: 'You must provide slack userid', + code: 500, + }); + } + + const { ...result } = await getUserStats(userId); + + const data = { + error: false, + code: 200, + message: 'ok', + data: { + ...result, + }, + }; + return response(data, res); + } catch (err) { + log.warn(err); + return response({ + error: true, + code: err.code || 500, + message: err.message, + data: null, + }, res, err.code || 500); + } + }, }); Route.add({ - method: 'POST', - path: `${apiPath}/histogram`, - handler: async (request: any, res: any) => { - try { - /* Should be able to take folling params - * userID | null - * startDate | null - * endDate | null - * type ( given / gived ) | return both ? - * - */ - const data = { - error: false, - code: 200, - message: null, - data: null, - }; - return response(data, res); - } catch (err) { - log.warn(err); - return response({ - error: true, - code: err.code || 500, - message: err.message, - data: null, - }, res, err.code || 500); - } - }, + method: 'POST', + path: `${apiPath}/histogram`, + handler: async (request: any, res: any) => { + try { + /* Should be able to take folling params + * userID | null + * startDate | null + * endDate | null + * type ( given / gived ) | return both ? + * + */ + const data = { + error: false, + code: 200, + message: null, + data: null, + }; + return response(data, res); + } catch (err) { + log.warn(err); + return response({ + error: true, + code: err.code || 500, + message: err.message, + data: null, + }, res, err.code || 500); + } + }, }); export default (req: any, res: any) => { - const method: string = req.method.toLowerCase(); - const path: string = req.url; - const { route, request, error } = Route.check({ method, path, req }); - if (error) return response({ error: true }, res, 500); - return route.handler(request, res); + const method: string = req.method.toLowerCase(); + const path: string = req.url; + const { route, request, error } = Route.check({ method, path, req }); + if (error) return response({ error: true }, res, 500); + return route.handler(request, res); }; diff --git a/src/bot.ts b/src/bot.ts index 11d9d2b..1409df7 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -1,110 +1,26 @@ -import config from './config'; -import BurritoStore from './store/BurritoStore'; import LocalStore from './store/LocalStore'; import { parseMessage } from './lib/parseMessage'; +import { handleBurritos } from './handleBurritos'; import { validBotMention, validMessage } from './lib/validator'; +import { emojis } from './lib/emojis'; import Rtm from './slack/Rtm'; import Wbc from './slack/Wbc'; -const { - enableDecrement, - dailyCap, - dailyDecCap, - emojiInc, - emojiDec, - disableEmojiDec, -} = config.slack; +export const notifyUser = (user: string, message: string) => Wbc.sendDM(user, message); -interface Emojis { - type: string; - emoji: string; -} +export const incomingMessage = async (message) => { -interface Updates { - username: string; - type: string; -} -const emojis: Array = []; + // If message not valid then dont process it + if (!validMessage(message, emojis, LocalStore.getAllBots())) return false; -const incEmojis = emojiInc.split(',').map((emoji => emoji.trim())); -incEmojis.forEach((emoji: string) => emojis.push({ type: 'inc', emoji })); + // If botMention handle message seperate later on. No support today + if (validBotMention(message, LocalStore.botUserID())) return false; -if (!disableEmojiDec) { - const decEmojis = emojiDec.split(',').map((emoji => emoji.trim())); - decEmojis.forEach((emoji: string) => emojis.push({ type: 'dec', emoji })); -} - -const giveBurritos = async (giver: string, updates: Updates[]) => { - return updates.reduce(async (prev: any, burrito) => { - return prev.then(async () => { - if (burrito.type === 'inc') { - await BurritoStore.giveBurrito(burrito.username, giver); - } else if (burrito.type === 'dec') { - await BurritoStore.takeAwayBurrito(burrito.username, giver); - } - }); - }, Promise.resolve()); -}; - -const notifyUser = (user: string, message: string) => Wbc.sendDM(user, message); - -const handleBurritos = async (giver: string, updates: Updates[]) => { - if (enableDecrement) { - const burritos = await BurritoStore.givenBurritosToday(giver, 'from'); - const diff = dailyCap - burritos; - if (updates.length > diff) { - notifyUser(giver, `You are trying to give away ${updates.length} burritos, but you only have ${diff} burritos left today!`); - return false; - } - if (burritos >= dailyCap) { - return false; - } - await giveBurritos(giver, updates); - } else { - const givenBurritos = await BurritoStore.givenToday(giver, 'from', 'inc'); - const givenRottenBurritos = await BurritoStore.givenToday(giver, 'from', 'dec'); - const incUpdates = updates.filter((x) => x.type === 'inc'); - const decUpdates = updates.filter((x) => x.type === 'dec'); - const diffInc = dailyCap - givenBurritos; - const diffDec = dailyDecCap - givenRottenBurritos; - if (incUpdates.length) { - if (incUpdates.length > diffInc) { - notifyUser(giver, `You are trying to give away ${updates.length} burritos, but you only have ${diffInc} burritos left today!`); - } else { - await giveBurritos(giver, incUpdates); - } - } - if (decUpdates.length) { - if (decUpdates.length > diffDec) { - notifyUser(giver, `You are trying to give away ${updates.length} rottenburritos, but you only have ${diffDec} rottenburritos left today!`); - } else { - await giveBurritos(giver, decUpdates); - } - } - } - return true; + const result = parseMessage(message, emojis); + if (result?.updates) { + const { giver, updates } = result; + await handleBurritos(giver, updates); + } }; -const start = () => { - Rtm.on('slackMessage', async (event: any) => { - if (validMessage(event, emojis, LocalStore.getAllBots())) { - if (validBotMention(event, LocalStore.botUserID())) { - // Geather data and send back to user - } else { - const result = parseMessage(event, emojis); - if (result) { - const { giver, updates } = result; - if (updates.length) { - await handleBurritos(giver, updates); - } - } - } - } - }); -}; - -export { - handleBurritos, - notifyUser, - start, -}; +export const start = () => Rtm.on('slackMessage', (event: any) => incomingMessage(event)); diff --git a/src/config/index.ts b/src/config/index.ts index 1ad23b7..4078804 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,13 +1,13 @@ -import * as log from 'bog'; +import log from 'loglevel'; import { - env, - fixPath, - mustHave, - themeRootPath, - defaultTheme, - root, - getThemePath, - getThemeName + env, + fixPath, + mustHave, + themeRootPath, + defaultTheme, + root, + getThemePath, + getThemeName } from '../lib/utils'; @@ -15,152 +15,154 @@ const isFalse = (input: string) => (input === 'false' || input === 'no' || input const isTrue = (input: string) => (input === 'true' || input === 'yes' || input === '1'); export function fixEmoji(input) { - let inputFix = input - if (!input.startsWith(':')) inputFix = `:${inputFix}`; - if (!input.endsWith(':')) inputFix = `${inputFix}:`; - return inputFix; + let inputFix = input + if (!input.startsWith(':')) inputFix = `:${inputFix}`; + if (!input.endsWith(':')) inputFix = `${inputFix}:`; + return inputFix; } export function getBool(inputKey: string, defaultValue: boolean) { - if (!inputKey) return defaultValue; - const key = inputKey.toLowerCase(); + if (!inputKey) return defaultValue; + const key = inputKey.toLowerCase(); - if (isFalse(key)) return false; - if (isTrue(key)) return true; - return defaultValue; + if (isFalse(key)) return false; + if (isTrue(key)) return true; + return defaultValue; }; export function getNum(inputKey: string, defaultValue: number): number { - if (!inputKey) return defaultValue; - const integer = Number(inputKey); - return !!integer ? integer : defaultValue; + if (!inputKey) return defaultValue; + const integer = Number(inputKey); + return !!integer ? integer : defaultValue; }; const config = { - production: { - db: { - db_driver: process.env.DATABASE_DRIVER || 'file', - db_fileName: 'burrito-prod.db', - db_path: process.env.DATABASE_PATH || `${root}data/`, - db_url: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_URL') : '', - db_name: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_DATABASE') : '', - db_uri: process.env.DATABASE_URI || `${process.env.MONGODB_URL}/${process.env.MONGODB_DATABASE}`, - }, - slack: { - bot_name: process.env.BOT_NAME || 'heyburrito', - api_token: mustHave('SLACK_API_TOKEN'), - emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), - emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), - disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), - dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), - dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), - enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), - }, - http: { - http_port: process.env.PORT || process.env.HTTP_PORT || 3333, - wss_port: process.env.WSS_PORT || 3334, - web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', - api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', - }, - theme: { - root: themeRootPath, - url: process.env.THEME_URL || defaultTheme, - path: process.env.THEME_PATH, - latest: getBool(process.env.THEME_LATEST, false), - themeName: getThemeName(), - themePath: getThemePath(), - }, - level: { - enableLevel: getBool(process.env.ENABLE_LEVEL, false), - scoreRotation: getNum(process.env.SCORE_ROTATION, 500) - }, - misc: { - slackMock: false, - log_level: process.env.LOG_LEVEL || 'info' - }, - }, - development: { - db: { - db_driver: process.env.DATABASE_DRIVER || 'file', - db_fileName: 'burrito-dev.db', - db_path: process.env.DATABASE_PATH || `${root}data/`, - db_url: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_URL') : '', - db_name: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_DATABASE') : '', - db_uri: process.env.DATABASE_URI || `${process.env.MONGODB_URL}/${process.env.MONGODB_DATABASE}`, - }, - slack: { - bot_name: process.env.BOT_NAME || 'heyburrito', - api_token: mustHave('SLACK_API_TOKEN'), - emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), - emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), - disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), - dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5000), - dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5000), - enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), - }, - http: { - http_port: getNum(process.env.HTTP_PORT, 3333), - wss_port: getNum(process.env.WSS_PORT, 3334), - web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', - api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', - }, - theme: { - root: themeRootPath, - url: process.env.THEME_URL || defaultTheme, - path: process.env.THEME_PATH, - latest: getBool(process.env.THEME_LATEST, false), - themeName: getThemeName(), - themePath: getThemePath(), - }, - level: { - enableLevel: getBool(process.env.ENABLE_LEVEL, true), - scoreRotation: getNum(process.env.SCORE_ROTATION, 500) - }, - misc: { - slackMock: true, - log_level: process.env.LOG_LEVEL || 'debug' - }, - }, - testing: { - db: { - db_driver: process.env.DATABASE_DRIVER || 'file', - db_fileName: 'burrito-test.db', - db_path: process.env.DATABASE_PATH || `${root}data/`, - db_url: '', - db_name: '', - }, - slack: { - bot_name: process.env.BOT_NAME || 'heyburrito', - api_token: process.env.SLACK_API_TOKEN || '', - emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), - emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), - disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), - dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5000), - dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5000), - enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), - }, - http: { - http_port: process.env.HTTP_PORT || 3333, - wss_port: process.env.WSS_PORT || 3334, - web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', - api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', - }, - theme: { - root: themeRootPath, - url: process.env.THEME_URL || defaultTheme, - path: process.env.THEME_PATH, - latest: getBool(process.env.THEME_LATEST, true), - themeName: getThemeName(), - themePath: getThemePath(), - }, - level: { - enableLevel: getBool(process.env.ENABLE_LEVEL, false), - scoreRotation: getNum(process.env.SCORE_ROTATION, 500) - }, - misc: { - slackMock: true, - }, + production: { + db: { + db_driver: process.env.DATABASE_DRIVER || 'file', + db_fileName: 'burrito-prod.db', + db_path: process.env.DATABASE_PATH || `${root}data/`, + db_url: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_URL') : '', + db_name: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_DATABASE') : '', + db_uri: process.env.DATABASE_URI || `${process.env.MONGODB_URL}/${process.env.MONGODB_DATABASE}`, }, + slack: { + bot_name: process.env.BOT_NAME || 'heyburrito', + api_token: mustHave('SLACK_API_TOKEN'), + emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), + emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), + disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), + dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), + dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), + enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), + }, + http: { + http_port: process.env.PORT || process.env.HTTP_PORT || 3333, + wss_port: process.env.WSS_PORT || 3334, + web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', + api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', + }, + theme: { + root: themeRootPath, + url: process.env.THEME_URL || defaultTheme, + path: process.env.THEME_PATH, + latest: getBool(process.env.THEME_LATEST, false), + themeName: getThemeName(), + themePath: getThemePath(), + }, + level: { + enableLevel: getBool(process.env.ENABLE_LEVEL, false), + scoreRotation: getNum(process.env.SCORE_ROTATION, 500) + }, + misc: { + slackMock: false, + log_level: process.env.LOG_LEVEL || 'info' + }, + }, + development: { + db: { + db_driver: process.env.DATABASE_DRIVER || 'file', + db_fileName: 'burrito-dev.db', + db_path: process.env.DATABASE_PATH || `${root}data/`, + db_url: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_URL') : '', + db_name: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_DATABASE') : '', + db_uri: process.env.DATABASE_URI || `${process.env.MONGODB_URL}/${process.env.MONGODB_DATABASE}`, + }, + slack: { + bot_name: process.env.BOT_NAME || 'heyburrito', + api_token: mustHave('SLACK_API_TOKEN'), + emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), + emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), + disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), + dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), + dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), + overdrawCap: getBool(process.env.ENABLE_OVERDRAW, true) ? getNum(process.env.SLACK_OVERDRAW_CAP, 5) : 0, + enableOverDraw: getBool(process.env.ENABLE_OVERDRAW, true), + enableDecrement: getBool(process.env.ENABLE_DECREMENT, false), + }, + http: { + http_port: getNum(process.env.HTTP_PORT, 3333), + wss_port: getNum(process.env.WSS_PORT, 3334), + web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', + api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', + }, + theme: { + root: themeRootPath, + url: process.env.THEME_URL || defaultTheme, + path: process.env.THEME_PATH, + latest: getBool(process.env.THEME_LATEST, false), + themeName: getThemeName(), + themePath: getThemePath(), + }, + level: { + enableLevel: getBool(process.env.ENABLE_LEVEL, true), + scoreRotation: getNum(process.env.SCORE_ROTATION, 500) + }, + misc: { + slackMock: false, + log_level: process.env.LOG_LEVEL || 'debug' + }, + }, + testing: { + db: { + db_driver: process.env.DATABASE_DRIVER || 'file', + db_fileName: 'burrito-test.db', + db_path: process.env.DATABASE_PATH || `${root}data/`, + db_url: '', + db_name: '', + }, + slack: { + bot_name: process.env.BOT_NAME || 'heyburrito', + api_token: process.env.SLACK_API_TOKEN || '', + emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), + emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), + disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), + dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5000), + dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5000), + enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), + }, + http: { + http_port: process.env.HTTP_PORT || 3333, + wss_port: process.env.WSS_PORT || 3334, + web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', + api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', + }, + theme: { + root: themeRootPath, + url: process.env.THEME_URL || defaultTheme, + path: process.env.THEME_PATH, + latest: getBool(process.env.THEME_LATEST, true), + themeName: getThemeName(), + themePath: getThemePath(), + }, + level: { + enableLevel: getBool(process.env.ENABLE_LEVEL, false), + scoreRotation: getNum(process.env.SCORE_ROTATION, 500) + }, + misc: { + slackMock: true, + }, + }, }; export default config[env] ? config[env] : config.development; diff --git a/src/database/drivers/Driver.ts b/src/database/drivers/Driver.ts index 33f5be2..4e9883a 100644 --- a/src/database/drivers/Driver.ts +++ b/src/database/drivers/Driver.ts @@ -1,25 +1,43 @@ -import Score from '../../types/Score.interface'; - -interface Find { - _id: string; - to: string; - from: string; - value: number; - given_at: Date; -} +export interface Find { + _id: string; + to: string; + from: string; + value: number; + given_at: Date; + overdrawn?: boolean; +}; +export interface DatabasePost { + _id: string, + to: string, + from: string, + value: number, + given_at: Date; + overdrawn: boolean; +}; -interface Sum { - _id?: string; // Username - score?: number; -} +export interface GetScoreBoard { + user?: string; + listType?: string; + today?: boolean; +}; + +export interface GivePost { + _id?: string; + to: string; + from: string; + value: number; + given_at: Date; + overdrawn: boolean; +}; export default abstract class Driver { - abstract async give(to: string, from: string, date): Promise; - abstract async takeAway(to: string, from: string, date): Promise; + abstract give(score: GivePost); + + abstract getScore(user: string, listType: string): Promise; - abstract async getScore(user: string, listType: string): Promise; + abstract findFromToday(user: string, listType: string): Promise; - abstract async findFromToday(user: string, listType: string): Promise>; + abstract getScoreBoard({ }: GetScoreBoard): Promise; } diff --git a/src/database/drivers/GenericDriver.ts b/src/database/drivers/GenericDriver.ts index 5757a58..e17f192 100644 --- a/src/database/drivers/GenericDriver.ts +++ b/src/database/drivers/GenericDriver.ts @@ -1,6 +1,6 @@ import Store from './Store'; -import Driver from './Driver'; -import Score from '../../types/Score.interface'; +import Driver, { GivePost } from './Driver'; + import { time } from '../../lib/utils'; function id() { @@ -9,102 +9,75 @@ function id() { return `_${str}`; } -interface Find { - _id: string; - to: string; - from: string; - value: number; - given_at: Date; -} - -interface Sum { - _id?: string; // Username - score?: number; -} - class GenericDriver extends Store implements Driver { - constructor(public driver: string) { - super(driver); - } + constructor(public driver: string) { + super(driver); + }; - async give(to: string, from: string, date: any): Promise { - const score: Score = { - _id: id(), - to, - from, - value: 1, - given_at: date, - }; - await this.storeData(score); - return Promise.resolve(true); - } + async give({ ...score }: GivePost) { + //score._id = id(); + const hej = { + _id: id(), + ...score + }; + await this.storeData(hej); + return Promise.resolve(true); + } - async takeAway(to: string, from: string, date: any): Promise { - const score: Score = { - _id: id(), - to, - from, - value: -1, - given_at: date, - }; - await this.storeData(score); - return Promise.resolve(true); - } + async getScore(user: string, listType: string) { + this.syncData(); + const data: any = await this.getData(); + const filteredData = data.filter((item: any) => item[listType] === user); + // if (asNumber) { + // const score: number = filteredData.reduce((a: number, item: any) => a + item.value, 0); + // return Promise.resolve(score); + // } + return Promise.resolve(filteredData); + }; - async getScore(user: string, listType: string, num = false): Promise { - this.syncData(); - const data: any = await this.getData(); - const filteredData = data.filter((item: any) => item[listType] === user); - if (num) { - const score: number = filteredData.reduce((a: number, item: any) => a + item.value, 0); - return Promise.resolve(score); - } - return Promise.resolve(filteredData); - } + async findFromToday(user: string, listType: string) { + this.syncData(); + const data: any = await this.getData(); + const filteredData = data.filter((item) => { + if (item[listType] === user + && item.given_at.getTime() < time().end.getTime() + && item.given_at.getTime() > time().start.getTime()) { + return item; + } + return undefined; + }).filter((y) => y); + return filteredData; + }; - async findFromToday(user: string, listType: string): Promise { - this.syncData(); - const data: any = await this.getData(); - const filteredData = data.filter((item) => { - if (item[listType] === user - && item.given_at.getTime() < time().end.getTime() - && item.given_at.getTime() > time().start.getTime()) { - return item; - } - return undefined; - }).filter((y) => y); - return filteredData; + async getScoreBoard({ user, listType, today }) { + this.syncData(); + const data: any = await this.getData(); + let listTypeSwitch: string; + if (user) { + listTypeSwitch = (listType === 'from') ? 'to' : 'from'; + } else { + listTypeSwitch = listType; } - - async getScoreBoard({ user, listType, today }): Promise { - this.syncData(); - const data: any = await this.getData(); - - let listTypeSwitch: string; - if (user) { - listTypeSwitch = (listType === 'from') ? 'to' : 'from'; - } else { - listTypeSwitch = listType; + const selected = data.filter((item: any) => { + if (today) { + if (item.given_at.getTime() < time().end.getTime() + && item.given_at.getTime() > time().start.getTime()) { + if (user) { + if (item[listTypeSwitch] === user) return item; + } else { + return item; + } } - const selected = data.filter((item: any) => { - if (today) { - if (item.given_at.getTime() < time().end.getTime() - && item.given_at.getTime() > time().start.getTime()) { - if (user) { - if (item[listTypeSwitch] === user) return item; - } else { - return item; - } - } - } else if (user) { - if (item[listTypeSwitch] === user) return item; - } else { - return item; - } - return undefined; - }).filter((y: any) => y); - return selected; - } -} + } else if (user) { + if (item[listTypeSwitch] === user) return item; + } else { + return item; + } + + return undefined; + }).filter((y: any) => y); + return selected; + }; +}; export default GenericDriver; diff --git a/src/handleBurritos.ts b/src/handleBurritos.ts new file mode 100644 index 0000000..95d92c9 --- /dev/null +++ b/src/handleBurritos.ts @@ -0,0 +1,121 @@ +import log from 'loglevel'; +import config from './config'; +import BurritoStore from './store/BurritoStore'; +import { notifyUser } from './bot'; + +const { + enableDecrement, + enableOverDraw, + dailyCap, + dailyDecCap, + overdrawCap, +} = config.slack; + +interface Updates { + username: string; + burritoType: string; + type?: string; + overdrawn?: boolean; +} + + +const giveBurritos = async (giver: string, updates: Updates[]) => { + return updates.reduce(async (prev: any, burrito) => { + return prev.then(async () => { + if (burrito.burritoType === 'inc') { + await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); + } else if (burrito.burritoType === 'dec') { + if (enableDecrement) { + const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'dec'); + } else { + await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); + } + } + }); + }, Promise.resolve()); +}; + +const handleUpdates = async (giver: string, updates: Updates[], scoreType: string) => { + log.debug("handleUpdates => scoreType => ", scoreType); + log.debug("handleUpdates => enableOverDraw => ", enableOverDraw); + log.debug("handleUpdates => enableDecrement => ", enableDecrement); + log.debug("handleUpdates => dailyCap => ", dailyCap); + log.debug("handleUpdates => dailyDecCap => ", dailyDecCap); + log.debug("handleUpdates => overdrawCap => ", overdrawCap); + log.debug("handleUpdates => args => giver => ", giver); + log.debug("handleUpdates => args => updates => ", updates); + log.debug("handleUpdates => args => scoreType: => ", scoreType); + + + const burritoType = (scoreType === 'inc') ? 'burrito' : 'rottenburrito'; + const cap = (scoreType === 'inc') ? dailyCap : dailyDecCap; + + // GivenToday + const GT = await BurritoStore.givenToday(giver, 'from', scoreType); + + // GivenToday Overdrawn + const GTO = await BurritoStore.givenToday(giver, 'from', scoreType, true); + + // Total Given today + const TGT = GT + GTO; + + const dailyDiff = cap - GT; + const dailyDiffTotal = cap + overdrawCap - TGT; + + // Send right total in message, so we dont send - if overdrawn was disabled the same day. + const messTotal = enableOverDraw ? dailyDiffTotal : dailyDiff; + + // Check if user can send all updates. + if(!(dailyDiffTotal >= updates.length)) return notifyUser(giver, `You are trying to give away ${updates.length} ${burritoType}, but you only have ${messTotal} ${burritoType} left today!`); + + // Check if update.length exceeds dailyDiff + if(!(dailyDiff >= updates.length)) { + + /** + * When overdraw we want to do a credit check of giver first. + * Giver needs to be able to pay the bill. + * ( Lowest userScore can be 0 ) */ + const giverScore = await BurritoStore.getUserScore(giver, 'to', scoreType); + if (!(giverScore >= updates.length)) return notifyUser(giver, `Trying to give more ${burritoType}s then u have`); + } + + /** + * We want to first handle the all the updates that we can as daily given ( from dailyCap ). + * So we need to slice out the entries that we want to count as daily. */ + const countAsDaily = updates.slice(0, dailyDiff); + if (countAsDaily.length) await giveBurritos(giver, countAsDaily); + + // Get the rest entries and count them as overDrawn + const overDrawnUpdates = updates.slice(dailyDiff); + + // When overdraw we want to add type overdrawn + const updatesOverDrawn = overDrawnUpdates.map(({ ...all }) => ({ ...all, overdrawn: true })); + return await giveBurritos(giver, updatesOverDrawn); +}; + +export const handleBurritos = async (giver: string, updates: Updates[]) => { + + /** + * We want to handle burritos differently depending on ENVs. + * If enableDecrement is true we want to handle all types of updates ( inc / dec ) against dailyCap. + * Else we want to handle them separately. + * Type inc => dailyCap + * Type dec => dailyDecCap */ + if (enableDecrement) { + const givenToday = await BurritoStore.givenToday(giver, 'from'); + const diff = dailyCap - givenToday; + + if (updates.length > diff) return notifyUser(giver, `You are trying to give away ${updates.length} burritos, but you only have ${diff} burritos left today!`); + if (givenToday >= dailyCap) return false; + await giveBurritos(giver, updates); + } else { + + const incUpdates = updates.filter((x) => x.burritoType === 'inc'); + const decUpdates = updates.filter((x) => x.burritoType === 'dec'); + + if (incUpdates.length) await handleUpdates(giver, incUpdates, 'inc'); + if (decUpdates.length) await handleUpdates(giver, decUpdates, 'dec'); + + }; + return true; +}; diff --git a/src/lib/boot.ts b/src/lib/boot.ts index 2ab874c..c80e60c 100644 --- a/src/lib/boot.ts +++ b/src/lib/boot.ts @@ -1,38 +1,38 @@ -import * as log from 'bog'; +import log from 'loglevel'; import config from '../config'; import { pathExists, createPath } from './utils'; import themeHandler from './themeHandler'; export default async () => { - log.level(config.misc.log_level); - log.debug('Loaded ENVs for boot:'); - log.debug('====================='); - log.debug('db_driver:', config.db.db_driver); - log.debug('themeName', config.theme.themeName); + log.setLevel(config.misc.log_level); + log.debug('Loaded ENVs for boot:'); + log.debug('====================='); + log.debug('db_driver:', config.db.db_driver); + log.debug('themeName', config.theme.themeName); - if (config.theme.path) { - log.debug('themePath:', config.theme.themePath); - } else { - log.debug('themeUrl:', config.theme.url); - } - log.debug('====================='); - await themeHandler(); - // check if database is file - if (config.db.db_driver === 'file') { - log.info('Database driver is file'); + if (config.theme.path) { + log.debug('themePath:', config.theme.themePath); + } else { + log.debug('themeUrl:', config.theme.url); + } + log.debug('====================='); + await themeHandler(); + // check if database is file + if (config.db.db_driver === 'file') { + log.info('Database driver is file'); - // Check if path exists - if (!pathExists(config.db.db_path)) { - log.debug('Database path does not exists'); + // Check if path exists + if (!pathExists(config.db.db_path)) { + log.debug('Database path does not exists'); - // Create path - if (createPath(config.db.db_path)) { - log.debug('Database path created', config.db.db_path); - } else { - // Better error handle here, try to recreate to some default folder ? - throw new Error('Could not create database path'); - } - } + // Create path + if (createPath(config.db.db_path)) { + log.debug('Database path created', config.db.db_path); + } else { + // Better error handle here, try to recreate to some default folder ? + throw new Error('Could not create database path'); + } } - return true; + } + return true; }; diff --git a/src/lib/emojis.ts b/src/lib/emojis.ts new file mode 100644 index 0000000..3534b6f --- /dev/null +++ b/src/lib/emojis.ts @@ -0,0 +1,21 @@ +import config from '../config'; +const { + emojiInc, + emojiDec, + disableEmojiDec, +} = config.slack; + +export interface Emojis { + type: string; + emoji: string; +} + +export const emojis: Emojis[] = []; + +const incEmojis = emojiInc.split(',').map((emoji: string) => emoji.trim()); +incEmojis.forEach((emoji: string) => emojis.push({ type: 'inc', emoji })); + +if (!disableEmojiDec) { + const decEmojis = emojiDec.split(',').map((emoji: string) => emoji.trim()); + decEmojis.forEach((emoji: string) => emojis.push({ type: 'dec', emoji })); +} diff --git a/src/lib/mapper.ts b/src/lib/mapper.ts index 945e1be..331e82d 100644 --- a/src/lib/mapper.ts +++ b/src/lib/mapper.ts @@ -2,22 +2,22 @@ import LocalStore from '../store/LocalStore'; import User from '../types/User.interface'; export default (data: User[]): User[] => { - const slackUsers = LocalStore.getSlackUsers(); - if (!data) return []; - if (!slackUsers) return []; + const slackUsers = LocalStore.getSlackUsers(); + if (!data) return []; + if (!slackUsers) return []; - return slackUsers.map((x: any) => { - const match = data.find(({ _id }) => _id === x.id && x.name); - if (match) { - const { _id, ...meta } = match; - return { - username: _id, - name: x.name, - avatar: x.avatar, - memberType: x.memberType, - ...meta, - }; - } - return undefined; - }).filter((y: any) => y); + return slackUsers.map((x: any) => { + const match = data.find(({ _id }) => _id === x.id && x.name); + if (match) { + const { _id, ...meta } = match; + return { + username: _id, + name: x.name, + avatar: x.avatar, + memberType: x.memberType, + ...meta, + }; + } + return undefined; + }).filter((y: any) => y); }; diff --git a/src/lib/parseMessage.ts b/src/lib/parseMessage.ts index 187e220..1c8b670 100644 --- a/src/lib/parseMessage.ts +++ b/src/lib/parseMessage.ts @@ -1,64 +1,75 @@ +import { Emojis } from './emojis'; + const usernameRegex: RegExp = /(<@[A-Z0-9]{2,}>)/g; +interface Update { + username: string; + burritoType: string; +} + +interface Updates { + giver?: string; + updates?: Update[] +} + /** * @param { string } text from slack message * @returns array, only unique values */ -function parseUsernames(text: string): string[] { - // Regex to get all users from message - const usersRaw = text.match(new RegExp(usernameRegex)); - if (!usersRaw) return []; - // replace unwanted chars - const users = usersRaw.map((x) => x.replace('<@', '').replace('>', '')); - // Remove duplicated values - const unique: string[] = users.filter((v, i, a) => a.indexOf(v) === i); - return unique.length ? unique : []; +const parseUsernames = (text: string): string[] => { + // Regex to get all users from message + const usersRaw = text.match(new RegExp(usernameRegex)); + if (!usersRaw) return []; + // replace unwanted chars + const users = usersRaw.map((x) => x.replace('<@', '').replace('>', '')); + // Remove duplicated values + const unique: string[] = users.filter((v, i, a) => a.indexOf(v) === i); + return unique.length ? unique : []; } /** * @param { Obejct } msg slackmessage * @param { array } emojis emojis that we want to use. Comes from env - * @return { object } { giver: string, updates:array } + * @returns { object } { giver: string, updates:array } * - giver: sent from , ex => giver: USER1 * - updates: array containing, username, and type. ex: * - [ { username: 'USER2', type: 'inc' }, * { username: 'USER2', type: 'dec' } ] } */ -function parseMessage(msg, emojis) { - // Array containg data of whom to give / remove points from - const updates = []; - - // Array with "allowed" emojis mentioned in slackmessage - const emojiHits = []; +const parseMessage = (msg: any, emojis: Emojis[]): Updates => { + // Array containg data of whom to give / remove points from + const updates = []; - // Get usernames from slack message - const users: string[] = parseUsernames(msg.text); - if (!users.length) return false; + // Array with "allowed" emojis mentioned in slackmessage + const emojiHits = []; - // Match and push allowed emojis to emojiHits - emojis.map((x: any) => { - const hitsRaw = msg.text.match(new RegExp(x.emoji, 'g')); - if (hitsRaw) hitsRaw.forEach((e: any) => emojiHits.push(e)); - return undefined; - }); + // Get usernames from slack message + const users: string[] = parseUsernames(msg.text); + if (!users.length) return {}; - // Rebuild emoji object with emojiHits - const hits = emojiHits.map((x: any) => ( - { - emoji: x, - type: emojis.filter((t: any) => t.emoji === x)[0].type, - } - )); + // Match and push allowed emojis to emojiHits + emojis.map((x: any) => { + const hitsRaw = msg.text.match(new RegExp(x.emoji, 'g')); + if (hitsRaw) hitsRaw.forEach((e: any) => emojiHits.push(e)); + return undefined; + }); - if (hits.length === 0) return false; + // Rebuild emoji object with emojiHits + const hits = emojiHits.map((x: any) => ( + { + emoji: x, + type: emojis.filter((t: any) => t.emoji === x)[0].type, + } + )); - // For each emojiHits give each user a update - hits.map((x) => users.forEach((u) => updates.push({ username: u, type: x.type }))); + if (!hits.length) return {}; - return { - updates, - giver: msg.user, - }; + // For each emojiHits give each user a update + hits.map((x) => users.forEach((u) => updates.push({ username: u, burritoType: x.type }))); + return { + updates, + giver: msg.user, + }; } export { parseMessage, parseUsernames }; diff --git a/src/lib/themeHandler.ts b/src/lib/themeHandler.ts index f2ff5ab..342cbbf 100644 --- a/src/lib/themeHandler.ts +++ b/src/lib/themeHandler.ts @@ -1,5 +1,5 @@ import * as fs from 'fs'; -import * as log from 'bog'; +import log from 'loglevel'; import { spawn } from 'child_process'; import config from '../config'; @@ -7,102 +7,102 @@ const THEMES_AVAILABLE: any = []; let times = 0; async function gitFunc(args, cwd: string) { - const [option, url] = args; + const [option, url] = args; - if (option === 'clone') log.info('Cloning theme:', url); - if (option === 'pull') log.info('Pulling latest theme:', url); + if (option === 'clone') log.info('Cloning theme:', url); + if (option === 'pull') log.info('Pulling latest theme:', url); - return new Promise((resolve, reject) => { - const process = spawn('git', args, { cwd }); - process.on('close', (status: any) => { - if (status === 0) { - resolve(true); - } else { - reject(status); - } - }); + return new Promise((resolve, reject) => { + const process = spawn('git', args, { cwd }); + process.on('close', (status: any) => { + if (status === 0) { + resolve(true); + } else { + reject(status); + } }); + }); } async function sleep() { - return new Promise((resolve) => { - setTimeout(() => { - resolve(true); - }, 1000); - }); + return new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }, 1000); + }); } const recursive = async (args, cwd) => { - times += 1; - try { - await gitFunc(args, cwd); - return true; - } catch (error) { - if (times < 5) { - await sleep(); - await recursive(args, cwd); - } else { - throw error; - } - } + times += 1; + try { + await gitFunc(args, cwd); return true; + } catch (error) { + if (times < 5) { + await sleep(); + await recursive(args, cwd); + } else { + throw error; + } + } + return true; }; async function git(args, cwd: string = config.theme.root) { - return recursive(args, cwd); + return recursive(args, cwd); } async function checkThemePath() { - fs.readdirSync(config.theme.root).forEach((file: string) => { - const isDir = fs.lstatSync(`${config.theme.root}${file}`).isDirectory(); - if (isDir) { - THEMES_AVAILABLE.push({ - name: file, - path: `${config.theme.root}${file}`, - }); - } - }); + fs.readdirSync(config.theme.root).forEach((file: string) => { + const isDir = fs.lstatSync(`${config.theme.root}${file}`).isDirectory(); + if (isDir) { + THEMES_AVAILABLE.push({ + name: file, + path: `${config.theme.root}${file}`, + }); + } + }); } export default async () => { - checkThemePath(); + checkThemePath(); - const theme = config.theme.url; - const [themeName] = theme.split('/').slice(-1); - const [themeExists] = THEMES_AVAILABLE.filter((x) => x.name === themeName); + const theme = config.theme.url; + const [themeName] = theme.split('/').slice(-1); + const [themeExists] = THEMES_AVAILABLE.filter((x) => x.name === themeName); - if (config.theme.path) { - log.info('Loading theme from disk'); - log.info('Theme:', config.theme.path); - } + if (config.theme.path) { + log.info('Loading theme from disk'); + log.info('Theme:', config.theme.path); + } - if (!config.theme.path) { - if (themeExists) { - log.info('Theme exist on disk'); - log.info('Theme:', theme); - if (config.theme.latest) { - log.info('Get latest = true'); - try { - await git(['pull'], themeExists.path); - log.info('Latest theme pulled'); - return true; - } catch (err) { - log.warn('Could not pull latest, error code:', err); - } - } - } else { - log.info('Theme does not exist on disk'); - log.info('Theme:', theme); - try { - await git(['clone', theme]); - log.info('Theme cloned'); - return true; - } catch (err) { - log.warn('Could not clone theme, error code:', err); - log.warn('Theme:', theme); - return true; - } + if (!config.theme.path) { + if (themeExists) { + log.info('Theme exist on disk'); + log.info('Theme:', theme); + if (config.theme.latest) { + log.info('Get latest = true'); + try { + await git(['pull'], themeExists.path); + log.info('Latest theme pulled'); + return true; + } catch (err) { + log.warn('Could not pull latest, error code:', err); } + } + } else { + log.info('Theme does not exist on disk'); + log.info('Theme:', theme); + try { + await git(['clone', theme]); + log.info('Theme cloned'); + return true; + } catch (err) { + log.warn('Could not clone theme, error code:', err); + log.warn('Theme:', theme); + return true; + } } - return true; + } + return true; }; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 46ff1cd..62022ac 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,4 +1,4 @@ -import * as log from 'bog'; +import log from 'loglevel'; import fs from 'fs'; import path from 'path'; import UserInterface from '../types/User.interface'; @@ -9,98 +9,98 @@ const defaultTheme: string = 'https://github.com/chralp/heyburrito-theme'; const time = () => { - const start = new Date(); - const end = new Date(); - start.setHours(0, 0, 0, 0); - end.setHours(23, 59, 59, 999); - return { - start, - end, - }; + const start = new Date(); + const end = new Date(); + start.setHours(0, 0, 0, 0); + end.setHours(23, 59, 59, 999); + return { + start, + end, + }; }; const sort = (input: UserInterface[], sortType: string = 'desc'): UserInterface[] => { - const sorted = input.sort((a, b) => { - if (a.score) { - if (sortType === 'desc') return b.score - a.score; - return a.score - b.score; - } else { - if (sortType === 'desc') return b.scoreinc - a.scoreinc; - return a.scoreinc - b.scoreinc; - } - }); - return sorted; + const sorted = input.sort((a, b) => { + if (a.score) { + if (sortType === 'desc') return b.score - a.score; + return a.score - b.score; + } else { + if (sortType === 'desc') return b.scoreinc - a.scoreinc; + return a.scoreinc - b.scoreinc; + } + }); + return sorted; }; const env: string = process.env.NODE_ENV || 'development'; const fixPath = (p: string): string => { - if (!p.startsWith('/')) return `/${p}`; - if (!p.endsWith('/')) return `${p}/`; - return p; + if (!p.startsWith('/')) return `/${p}`; + if (!p.endsWith('/')) return `${p}/`; + return p; }; const pathExists = (inPath: string) => { - try { - log.debug('Checking if path exists', inPath); - return fs.lstatSync(inPath).isDirectory(); - } catch (e) { - return false; - } + try { + log.debug('Checking if path exists', inPath); + return fs.lstatSync(inPath).isDirectory(); + } catch (e) { + return false; + } }; const createPath = (inPath: string) => { - try { - log.debug(`Trying to create path ${inPath}`); - fs.mkdirSync(inPath); - const exists = pathExists(inPath); - if (exists) return true; - throw new Error('Neit'); - } catch (e) { - log.debug(`Could not create path ${inPath}`); - return false; - } + try { + log.debug(`Trying to create path ${inPath}`); + fs.mkdirSync(inPath); + const exists = pathExists(inPath); + if (exists) return true; + throw new Error('Neit'); + } catch (e) { + log.debug(`Could not create path ${inPath}`); + return false; + } }; const mustHave = (key: string) => { - if (env === 'development' || env === 'testing') return process.env[key]; - if (!process.env[key]) throw new Error(`Missing ENV ${key}`); - return process.env[key]; + if (env === 'development' || env === 'testing') return process.env[key]; + if (!process.env[key]) throw new Error(`Missing ENV ${key}`); + return process.env[key]; }; const getThemeName = () => { - if (process.env.THEME_PATH) { - const themePath = process.env.THEME_PATH; - const [themeName] = themePath.split('/').slice(-1); - return themeName; - } - const theme = process.env.THEME_URL || defaultTheme; - const [themeName] = theme.split('/').slice(-1); + if (process.env.THEME_PATH) { + const themePath = process.env.THEME_PATH; + const [themeName] = themePath.split('/').slice(-1); return themeName; + } + const theme = process.env.THEME_URL || defaultTheme; + const [themeName] = theme.split('/').slice(-1); + return themeName; }; const getThemePath = () => { - if (process.env.THEME_PATH) { - const themePath = process.env.THEME_PATH; - if (themePath.endsWith('/')) return themePath; - return `${themePath}/`; - } + if (process.env.THEME_PATH) { + const themePath = process.env.THEME_PATH; + if (themePath.endsWith('/')) return themePath; + return `${themePath}/`; + } - const themeName = getThemeName(); - return `${themeRootPath}${themeName}/`; + const themeName = getThemeName(); + return `${themeRootPath}${themeName}/`; }; export { - time, - sort, - mustHave, - fixPath, - env, - pathExists, - createPath, - themeRootPath, - defaultTheme, - root, - getThemePath, - getThemeName, + time, + sort, + mustHave, + fixPath, + env, + pathExists, + createPath, + themeRootPath, + defaultTheme, + root, + getThemePath, + getThemeName, }; diff --git a/src/lib/validator.ts b/src/lib/validator.ts index 9892f1c..3f7285d 100644 --- a/src/lib/validator.ts +++ b/src/lib/validator.ts @@ -1,79 +1,81 @@ -import * as log from 'bog'; +import log from 'loglevel'; import { parseUsernames } from './parseMessage'; function selfMention(message: any) { - const selfmention = message.text.match(`<@${message.user}>`); - if (selfmention) log.warn('Not valid, sender mentioned in message'); - return !!selfmention; + const selfmention = message.text.match(`<@${message.user}>`); + if (selfmention) { + log.warn('Not valid, sender mentioned in message'); + } + return !!selfmention; } function sentFromBot(message: any, allBots: any) { - const fromBot = allBots.filter((x: any) => message.user.match(x.id)); - return !!fromBot.length; + const fromBot = allBots.filter((x: any) => message.user.match(x.id)); + return !!fromBot.length; } function sentToBot(message: any, allBots: any) { - // Get all users from message.text - const usersArr = parseUsernames(message.text); + // Get all users from message.text + const usersArr = parseUsernames(message.text); - if (!usersArr) return false; + if (!usersArr) return false; - const toBot = allBots.filter((v: any) => { - if (usersArr.includes(v.id)) return v; - return undefined; - }); + const toBot = allBots.filter((v: any) => { + if (usersArr.includes(v.id)) return v; + return undefined; + }); - return !!toBot.length; + return !!toBot.length; } function burritoToBot(message: any, emojis: any) { - const burritoSentToBot = emojis.filter((x: any) => message.text.match(`${x.id}`)); - return !!burritoSentToBot.length; + const burritoSentToBot = emojis.filter((x: any) => message.text.match(`${x.id}`)); + return !!burritoSentToBot.length; } function validMessage(message: any, emojis: any, allBots: any): boolean { - // We dont want messages with subtypes - if (message.subtype) return false; + // We dont want messages with subtypes + if (message.subtype) return false; - // Check if sender is mentioned in message - if (selfMention(message)) return false; + // Check if sender is mentioned in message + if (selfMention(message)) return false; - // Check if message.user is registerd Bot - const usrIsBot = allBots.filter((m: any) => { - if (message.user.match(`${m.id}`)) return m; - return undefined; - }); - if (usrIsBot.length) return false; + // Check if message.user is registerd Bot + const usrIsBot = allBots.filter((m: any) => { + if (message.user.match(`${m.id}`)) return m; + return undefined; + }); + if (usrIsBot.length) return false; - // Check if message.text contains registerd Bot - const txtContainsBot = allBots.filter((m: any) => { - if (message.text.match(`${m.id}`)) return m; - return undefined; - }); + // Check if message.text contains registerd Bot + const txtContainsBot = allBots.filter((m: any) => { + if (message.text.match(`${m.id}`)) return m; + return undefined; + }); - if (txtContainsBot.length) { - // Check if message.text contains registerd emoji to bot - const txtContainsEmoji = emojis.filter((e) => { - if (message.text.match(`${e.emoji}`)) return e; - return undefined; - }); - if (txtContainsEmoji.length) return false; - } - return true; + if (txtContainsBot.length) { + // Check if message.text contains registerd emoji to bot + const txtContainsEmoji = emojis.filter((e) => { + if (message.text.match(`${e.emoji}`)) return e; + return undefined; + }); + if (txtContainsEmoji.length) return false; + } + return true; } function validBotMention(message: any, botUserID: any) { - if ((message.text.match(`<@${botUserID}>`)) && (message.text.match('stats'))) { - return true; - } - return false; + if ((message.text.match(`<@${botUserID}>`)) && (message.text.match('stats'))) { + return true; + } + return false; } export { - validBotMention, - validMessage, - selfMention, - sentFromBot, - sentToBot, - burritoToBot, + validBotMention, + validMessage, + selfMention, + sentFromBot, + sentToBot, + burritoToBot, }; diff --git a/src/middleware.ts b/src/middleware.ts index 3fd986e..d3086f5 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -3,11 +3,33 @@ import mapper from './lib/mapper'; import { sort } from './lib/utils'; import BurritoStore from './store/BurritoStore'; - const { + level: { enableLevel, scoreRotation, -} = config.level; + }, + slack: { + enableOverDraw, + enableDecrement, + } +} = config; + + + +export const listTypeSwitch = (listType: string) => listType === 'to' ? 'from' : 'to'; + + +const levelScoreList = (scoreList) => scoreList.map((x: any) => { + let score = x.score; + const roundedScore = Math.floor(score / scoreRotation) * scoreRotation; + const level = Math.floor((score - 1) / scoreRotation); + const newScore = ((score - roundedScore) === 0 ? roundedScore - (score - scoreRotation) : score - roundedScore); + return { + _id: x._id, + score: newScore, + level, + } +}); /** * Middleware for API and Websocket @@ -18,150 +40,129 @@ const { * @param {string} listType - to / from */ const getScoreBoard = async (listType: string, scoreType: string) => { - const data = await BurritoStore.getScoreBoard({ listType, scoreType }); - const score = []; - const uniqueUsername = [...new Set(data.map((x) => x[listType]))]; - - const scoreTypeFilter = (scoreType === 'inc') ? 1 : -1; - uniqueUsername.forEach((u) => { - const dataByUser = data.filter((e: any) => (e[listType] === u)); - let filteredData: any; - let countSwitch: any; - - if (listType === 'to' && config.slack.enableDecrement && (scoreType === 'inc')) { - filteredData = dataByUser; - } else { - filteredData = dataByUser.filter((e: any) => (e.value === scoreTypeFilter)); - countSwitch = 1; - } - const red = filteredData.reduce((a: number, item) => a + (countSwitch || item.value), 0); - score.push({ _id: u, score: red }); - }); - const scoreList = score.map((x) => { - if (x.score !== 0) return x; - return undefined; - }).filter((y) => y); - - if(enableLevel) { - const levelScoreList = scoreList.map(x => { - let score = x.score; - const roundedScore = Math.floor( score / scoreRotation ) * scoreRotation; - const level = Math.floor((score -1) / scoreRotation); - const newScore = ((score - roundedScore) === 0 ? roundedScore - (score - scoreRotation) : score - roundedScore); - return { - _id: x._id, - score: newScore, - level, - } - }); - return sort(mapper(levelScoreList)); - }; - - return sort(mapper(scoreList)); + + const _data = await BurritoStore.getScoreBoard({ listType }); + + // We want to filter out data that we want first + const data = BurritoStore.filterScoreData(_data, scoreType); + + // Get unique Usernames + const uniqueUsername: string[] = [...new Set(data.map((x) => x[listType]))]; + + const scoreList = uniqueUsername + .map((user) => ({ _id: user, score: BurritoStore._calucateScore(data, user, { listType, scoreType }) })) + .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); + + return enableLevel ? sort(mapper(levelScoreList(scoreList))) : sort(mapper(scoreList)); }; const _getUserScoreBoard = async ({ ...args }) => { - const { listType } = args; - const data: any = await BurritoStore.getScoreBoard({ ...args }); - const score = []; - const uniqueUsername = [...new Set(data.map((x) => x[listType]))]; - uniqueUsername.forEach((u) => { - const dataByUser = data.filter((e: any) => e[listType] === u); - const scoreinc = dataByUser.filter((x: any) => x.value === 1); - const scoredec = dataByUser.filter((x: any) => x.value === -1); - score.push({ - _id: u, - scoreinc: scoreinc.length, - scoredec: scoredec.length, - }); + const { listType, user, today } = args; + const data = await BurritoStore.getScoreBoard({ listType, user, today }); + const score = []; + const uniqueUsername: string[] = [...new Set(data.map((x) => x[listType]))]; + uniqueUsername.forEach((u) => { + const dataByUser = data.filter((e: any) => e[listType] === u); + const scoreinc = dataByUser.filter((x: any) => ((x.value === 1) && (x.overdrawn !== true))); + const scoredec = dataByUser.filter((x: any) => ((x.value === -1) && (x.overdrawn !== true))); + const scoreincOverdrawn = dataByUser.filter((x) => ((x.value === 1) && (x.overdrawn == true))); + const scoredecOverdrawn = dataByUser.filter((x) => ((x.value === -1) && (x.overdrawn == true))); + score.push({ + _id: u, + scoreinc: scoreinc.length, + scoredec: scoredec.length, + scoreincOverdrawn: scoreincOverdrawn.length, + scoredecOverdrawn: scoredecOverdrawn.length, }); - return score; + }); + return score; }; + /** * @param {string} user - Slack userId */ const getUserStats = async (user: string) => { - const [ - userStats, - givenList, - receivedList, - givenListToday, - receivedListToday, - ] = await Promise.all([ - BurritoStore.getUserStats(user), - _getUserScoreBoard({ user, listType: 'to' }), - _getUserScoreBoard({ user, listType: 'from' }), - _getUserScoreBoard({ user, listType: 'to', today: true }), - _getUserScoreBoard({ user, listType: 'from', today: true }), - ]); - - return { - user: mapper([userStats])[0], - given: sort(mapper(givenList)), - received: sort(mapper(receivedList)), - givenToday: sort(mapper(givenListToday)), - receivedToday: sort(mapper(receivedListToday)), - }; + const [ + userStats, + givenList, + receivedList, + givenListToday, + receivedListToday, + ] = await Promise.all([ + BurritoStore.getUserStats(user), + _getUserScoreBoard({ user, listType: 'to' }), + _getUserScoreBoard({ user, listType: 'from' }), + _getUserScoreBoard({ user, listType: 'to', today: true }), + _getUserScoreBoard({ user, listType: 'from', today: true }), + ]); + return { + user: mapper([userStats])[0], + given: sort(mapper(givenList)), + received: sort(mapper(receivedList)), + givenToday: sort(mapper(givenListToday)), + receivedToday: sort(mapper(receivedListToday)), + }; }; /** * @param {string} user - Slack userId */ const givenBurritosToday = async (user: string) => { - const [ - receivedToday, - givenToday, - ] = await Promise.all([ - BurritoStore.givenBurritosToday(user, 'to'), - BurritoStore.givenBurritosToday(user, 'from'), - ]); - - return { - givenToday, - receivedToday, - }; + const [ + receivedToday, + givenToday, + ] = await Promise.all([ + BurritoStore.givenToday(user, 'to'), + BurritoStore.givenToday(user, 'from'), + ]); + + return { + givenToday, + receivedToday, + }; }; /** * @param {string} user - Slack userId */ const getUserScore = async (user: string, listType: string, scoreType: string) => { - const scoreList = await BurritoStore.getScoreBoard({ listType, scoreType }); - const userScore = scoreList.filter((x) => x[listType] === user); - - const scoreTypeFilter = (scoreType === 'inc') ? 1 : -1; - let countSwitch: any; - let filteredData: any; - - if (listType === 'to' && scoreType === 'inc') { - if (config.slack.enableDecrement) { - filteredData = userScore; - } else { - filteredData = userScore.filter((e: any) => (e.value === scoreTypeFilter)); - countSwitch = 1; - } + console.log("HAALÃ…Ã…Ã…") + const scoreList = await BurritoStore.getScoreBoard({ listType }); + const userScore = scoreList.filter((x) => x[listType] === user); + + const scoreTypeFilter = (scoreType === 'inc') ? 1 : -1; + let countSwitch: any; + let filteredData: any; + + if (listType === 'to' && scoreType === 'inc') { + if (config.slack.enableDecrement) { + filteredData = userScore; } else { - filteredData = userScore.filter((e: any) => (e.value === scoreTypeFilter)); - if (scoreType === 'dec') { - countSwitch = 1; - } + filteredData = userScore.filter((e: any) => (e.value === scoreTypeFilter)); + countSwitch = 1; + } + } else { + filteredData = userScore.filter((e: any) => (e.value === scoreTypeFilter)); + if (scoreType === 'dec') { + countSwitch = 1; } - const userScoreCounted = filteredData.reduce((acc, item) => acc + (countSwitch || item.value), 0); - const [res] = mapper([{ - _id: user, - score: userScoreCounted, - }]); - return { - ...res, - scoreType, - listType, - }; + } + const userScoreCounted = filteredData.reduce((acc, item) => acc + (countSwitch || item.value), 0); + const [res] = mapper([{ + _id: user, + score: userScoreCounted, + }]); + return { + ...res, + scoreType, + listType, + }; }; export { - getScoreBoard, - getUserStats, - givenBurritosToday, - getUserScore, + getScoreBoard, + getUserStats, + givenBurritosToday, + getUserScore, }; diff --git a/src/server.ts b/src/server.ts index ffadfab..8655819 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,7 +1,7 @@ import dotenv from 'dotenv'; /* eslint-disable import/first */ dotenv.config(); -import log from 'bog'; +import log from 'loglevel'; import http from 'http'; import BurritoStore from './store/BurritoStore'; import LocalStore from './store/LocalStore'; @@ -17,58 +17,63 @@ import WSSHandler from './wss'; import boot from './lib/boot'; const init = async () => { - await boot(); + await boot(); }; init().then(() => { - log.info('Staring heyburrito'); - // Configure BurritoStore - BurritoStore.setDatabase(database); + log.setLevel(config.misc.log_level); + log.info('Staring heyburrito'); - // Set and start slack services - const { rtm, wbc } = slack; + // Configure BurritoStore + BurritoStore.setDatabase(database); - rtm.start(); - RTMHandler.register(rtm); - WBCHandler.register(wbc); + // Set and start slack services + const { rtm, wbc } = slack; - // Start bot instance - start(); + //BurritoStore.getUserScore("UEKN9GNAJ", 'to', 'dec'); + //BurritoStore.getUserScore("UEHUXHG0G", 'to', 'inc'); - // Start localstore instance - LocalStore.start(); + rtm.start(); + RTMHandler.register(rtm); + WBCHandler.register(wbc); + // Start bot instance + start(); + + // Start localstore instance + LocalStore.start(); + + /** + * Httpserver request handler + */ + const requestHandler = (request: http.IncomingMessage, response: http.ServerResponse) => { /** - * Httpserver request handler + * Check if request url contains api path, then let APIHandler take care of it */ - const requestHandler = (request: http.IncomingMessage, response: http.ServerResponse) => { - /** - * Check if request url contains api path, then let APIHandler take care of it - */ - if (request.url.includes(config.http.api_path)) return APIHandler(request, response); - /** - * Check if request url contains webpath, then let WEBHandler take care of it - */ - if (request.url.includes(config.http.web_path)) return WEBHandler(request, response); - /** - * redirect all other requests to webPath - */ - response.writeHead(301, { - location: config.http.web_path, - }); - return response.end(); - }; - + if (request.url.includes(config.http.api_path)) return APIHandler(request, response); /** - * Start HTTP / WSS server + * Check if request url contains webpath, then let WEBHandler take care of it */ - const httpserver = http.createServer(requestHandler); - - httpserver.listen(config.http.http_port, (err) => { - if (err) throw new Error(`Could not start HTTP server, error => ${err}`); - // Start WSS instance - WSSHandler(); - log.info(`HttpServer started on ${config.http.http_port}`); + if (request.url.includes(config.http.web_path)) return WEBHandler(request, response); + /** + * redirect all other requests to webPath + */ + response.writeHead(301, { + location: config.http.web_path, }); + return response.end(); + }; + + /** + * Start HTTP / WSS server + */ + const httpserver = http.createServer(requestHandler); + + httpserver.listen(config.http.http_port, () => { + //if (err) throw new Error(`Could not start HTTP server, error => ${err}`); + // Start WSS instance + WSSHandler(); + log.info(`HttpServer started on ${config.http.http_port}`); + }); }); diff --git a/src/slack/Rtm.ts b/src/slack/Rtm.ts index b3894dd..a14b202 100644 --- a/src/slack/Rtm.ts +++ b/src/slack/Rtm.ts @@ -1,4 +1,4 @@ -import * as log from 'bog'; +import log from 'loglevel'; import { EventEmitter } from 'events'; interface SlackEvent { diff --git a/src/slack/Wbc.ts b/src/slack/Wbc.ts index 65c2705..a1fc83c 100644 --- a/src/slack/Wbc.ts +++ b/src/slack/Wbc.ts @@ -1,50 +1,50 @@ -import * as log from 'bog'; +import log from 'loglevel'; import config from '../config'; interface WbcParsed { - id: string; - name: string; - avatar: string; - memberType: string; + id: string; + name: string; + avatar: string; + memberType: string; } class Wbc { - wbc: any; + wbc: any; - register(wbc: any) { - this.wbc = wbc; - } + register(wbc: any) { + this.wbc = wbc; + } - async fetchSlackUsers() { - const users: WbcParsed[] = []; - const bots: WbcParsed[] = []; + async fetchSlackUsers() { + const users: WbcParsed[] = []; + const bots: WbcParsed[] = []; - log.info('Fetching slack users via wbc'); - const result = await this.wbc.users.list(); - result.members.forEach((x: any) => { - // reassign correct array to arr - const arr = x.is_bot ? bots : users; - arr.push({ - id: x.id, - name: x.is_bot ? x.name : x.real_name, - memberType: x.is_restricted ? 'guest' : 'member', - avatar: x.profile.image_48, - }); - }); - return { users, bots }; - } + log.info('Fetching slack users via wbc'); + const result = await this.wbc.users.list(); + result.members.forEach((x: any) => { + // reassign correct array to arr + const arr = x.is_bot ? bots : users; + arr.push({ + id: x.id, + name: x.is_bot ? x.name : x.real_name, + memberType: x.is_restricted ? 'guest' : 'member', + avatar: x.profile.image_48, + }); + }); + return { users, bots }; + } - async sendDM(username: string, text: string) { - const res = await this.wbc.chat.postMessage({ - text, - channel: username, - username: config.slack.bot_name, - icon_emoji: ':burrito:', - }); - if (res.ok) { - log.info(`Notified user ${username}`); - } + async sendDM(username: string, text: string) { + const res = await this.wbc.chat.postMessage({ + text, + channel: username, + username: config.slack.bot_name, + icon_emoji: ':burrito:', + }); + if (res.ok) { + log.info(`Notified user ${username}`); } + } } export default new Wbc(); diff --git a/src/slack/index.ts b/src/slack/index.ts index 44928e4..fe2342f 100644 --- a/src/slack/index.ts +++ b/src/slack/index.ts @@ -1,4 +1,4 @@ -import * as log from 'bog'; +import log from 'loglevel'; import { WebClient } from '@slack/web-api'; import { RTMClient } from '@slack/rtm-api'; import { RTMMock, WebMock } from '../../test/lib/slackMock'; @@ -6,9 +6,9 @@ import config from '../config'; const { slackMock } = config.misc; -log.debug('Slack mockApi loaded', slackMock); +log.info('Slack mockApi loaded', slackMock); export default { - rtm: slackMock ? new RTMMock() : new RTMClient(config.slack.api_token), - wbc: slackMock ? new WebMock() : new WebClient(config.slack.api_token), + rtm: slackMock ? new RTMMock() : new RTMClient(config.slack.api_token), + wbc: slackMock ? new WebMock() : new WebClient(config.slack.api_token), }; diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 7e073b9..6f08ecc 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -1,115 +1,236 @@ -import * as log from 'bog'; +import log from 'loglevel'; import { EventEmitter } from 'events'; +import config from '../config'; +import { listTypeSwitch } from '../middleware'; -interface Find { - _id: string; - to: string; - from: string; - value: number; - given_at: Date; -} +import Driver, { + GetScoreBoard, + DatabasePost, +} from '../database/drivers/Driver'; + +const { + slack: { + enableOverDraw, + enableDecrement, + } +} = config; -interface Sum { - _id?: string; // Username - score?: number; +interface CalucateUserScore { + listType?: string; + scoreType?: string; + user?: string; } interface GetUserStats { - _id: string; - received: number; - given: number; - receivedToday: number; - givenToday: number; + _id: string; + received: number; + given: number; + receivedToday: number; + givenToday: number; } -interface DatabasePost { - _id: string, - to: string, - from: string, - value: number, - given_at: Date +interface BurritoUpdate { + to: string; + from: string; + type: string; + overdrawn?: boolean; } class BurritoStore extends EventEmitter { - database: any = null; - // Set and Store database object - setDatabase(database: any) { - this.database = database; - } + database: Driver; - async giveBurrito(to: string, from: string, date = new Date()): Promise { - log.info(`Burrito given to ${to} from ${from}`); - await this.database.give(to, from, date); - this.emit('GIVE', to, from); - return to; - } + // Set and Store database object + public setDatabase(database: Driver) { + this.database = database; + }; - async takeAwayBurrito(to: string, from: string, date = new Date()): Promise { - log.info(`Burrito taken away from ${to} by ${from}`); - const score: number = await this.database.getScore(to, 'to', true); - if (!score) return []; - await this.database.takeAway(to, from, date); - this.emit('TAKE_AWAY', to, from); - return to; - } + public async give({ to, from, type, overdrawn }: BurritoUpdate): Promise { + const score = { + to, + from, + value: (type === 'inc') ? 1 : -1, + given_at: new Date(), + overdrawn, + }; + + await this.database.give(score); + + if (type === 'inc') { + log.info(`Burrito given to ${to} from ${from}`); + this.emit('GIVE', to, from); + }; + + if (type === 'dec') { + log.info(`Burrito taken away from ${to} by ${from}`); + this.emit('TAKE_AWAY', to, from); + }; + + if (overdrawn) this.emit('TAKE_AWAY', to, from); + return to; + }; + + public async getUserStats(user: string): Promise { + const [ + received, + given, + receivedToday, + givenToday, + ] = await Promise.all([ + this.database.getScore(user, 'to'), + this.database.getScore(user, 'from'), + this.givenToday(user, 'to'), + this.givenToday(user, 'from'), + ]); + return { + receivedToday, + givenToday, + _id: user, + received: this.calucateScore(received, {}), + given: this.calucateScore(given, {}) + }; + }; + + public getScoreBoard(args: GetScoreBoard) { + return this.database.getScoreBoard(args); + }; - async getUserStats(user: string): Promise { - const [ - received, - given, - receivedToday, - givenToday, - ]: [Sum[], Sum[], number, number] = await Promise.all([ - this.database.getScore(user, 'to'), - this.database.getScore(user, 'from'), - this.givenBurritosToday(user, 'to'), - this.givenBurritosToday(user, 'from'), - ]); - return { - receivedToday, - givenToday, - _id: user, - received: received.length, - given: given.length, + public async givenToday(user: string, listType: string, scoreType?: string, overdrawn: boolean = false): Promise { + + const givenToday = await this.database.findFromToday(user, listType); + if (scoreType && ['inc', 'dec'].includes(scoreType)) { + const scoreTypeFilter = (scoreType === 'inc') ? 1 : -1; + + const givenFilter = givenToday.filter((x) => { + if (x.value === scoreTypeFilter) { + if(overdrawn) return !!x.overdrawn + return !x.overdrawn }; - } + }); + return this.calucateScore(givenFilter, {}); + }; + return this.calucateScore(givenToday, {}); + }; + + - async getScoreBoard({ ...args }): Promise { - return this.database.getScoreBoard({ ...args }); - } - /** - * @param {string} user - userId - * @param {string} listType - to / from defaults from - */ - async givenBurritosToday(user: string, listType: string): Promise { - const givenToday: Find[] = await this.database.findFromToday(user, listType); - return givenToday.length; + /** + * Get UserScore depending on listType and scoreType. + */ + public async getUserScore(user: string, listType: string, scoreType: string): Promise { + + // Get users score from DB, ( Only all inc not calculated with dec or overdrwan) + const _data = await this.database.getScore(user, listType); + if (enableOverDraw) { + const _dataSwitched = await this.database.getScore(user, listTypeSwitch(listType)); + const data = _dataSwitched.filter((entry) => (!!entry.overdrawn)); + return _data.length - data.length; } + return _data.length; + + }; + + + + // countScore + public calucateScore(data: DatabasePost[], args: CalucateUserScore) { + const { listType, scoreType, user } = args; + const valueSwitch = (scoreType === 'dec') ? 1 : 0; - /** - * @param {string} user - userId - * @param {string} listType - to / from defaults from - */ - async givenToday(user: string, listType: string, type: any = false): Promise { - const givenToday: Find[] = await this.database.findFromToday(user, listType); - if (type) { - if (['inc', 'dec'].includes(type)) { - const valueFilter = (type === 'inc') ? 1 : -1; - const givenFilter = givenToday.filter((x) => x.value === valueFilter); - return givenFilter.length; - } + const gg = data.reduce((total: number, current: any): number => { + if (listType) { + if (current[listType] === user) { + return total + (valueSwitch || current.value); } - return givenToday.length; - } + return total; + } else { + return total + 1; + } + }, 0); + return gg; + }; + + + public _filterScoreData(data: DatabasePost[], scoreType: string) { + console.log("_filterScoreData => scoreType:", scoreType); + const scoreSwitch = (scoreType === 'inc') ? 1 : -1; + const valueSwitch = (scoreType === 'dec') ? 1 : 0; + + return data.filter((entry) => { + + /* if enableDecrement return 1 AND -1 + * check first if enableOverDraw, if so return only if enableOverDraw = true + */ + if (enableDecrement) { + + if (enableOverDraw) { + return valueSwitch + ? (entry.overdrawn !== true && entry.value === scoreSwitch) + : entry.overdrawn !== true; + } else { + return valueSwitch ? entry.value === scoreSwitch : entry; + } + + + } else { + if (entry.value == scoreSwitch) { + if (enableOverDraw) return entry; + return entry.overdrawn !== true; + } + return null; + } + }); + }; + + public filterScoreData(data: DatabasePost[], scoreType: string) { - /** - * @param {string} user - userId - */ - async getUserScore(user: string, listType: string, num): Promise { - return this.database.getScore(user, listType, num); + const scoreSwitch = (scoreType === 'inc') ? 1 : -1; + const valueSwitch = (scoreType === 'dec') ? 1 : 0; + + return data.filter((entry) => { + if (enableDecrement) { + if (!enableOverDraw) { + return valueSwitch + ? (entry.overdrawn !== true && entry.value === scoreSwitch) + : entry.overdrawn !== true; + } else { + return valueSwitch ? entry.value === scoreSwitch : entry; + } + } else { + if (entry.value == scoreSwitch) { + if (enableOverDraw) return entry; + return entry.overdrawn !== true; + } + } + }); + }; + + + public _getOverDrawn (user: string) { + + } + + public _calucateScore(data, user: string, { listType, scoreType }): number { + const valueSwitch = (scoreType === 'dec') ? 1 : 0; + + if (enableOverDraw) { + const scoreOverDrawn = data.reduce((total: number, entry) => { + if (!!entry.overdrawn && entry[listTypeSwitch(listType)] == user) { + return total + (valueSwitch || entry.value); + } + return total; + }, 0); + console.log("DJAHA", user, scoreOverDrawn) + const _score = this.calucateScore(data, { user, listType, scoreType }); + + console.log("_score", _score) + return scoreOverDrawn ? _score - scoreOverDrawn : _score; + } else { + return this.calucateScore(data, { user, listType, scoreType }); } + + }; } export default new BurritoStore(); diff --git a/src/store/LocalStore.ts b/src/store/LocalStore.ts index 245adf8..17ec8a0 100644 --- a/src/store/LocalStore.ts +++ b/src/store/LocalStore.ts @@ -1,14 +1,11 @@ -import * as log from 'bog'; +import log from 'loglevel'; import config from '../config'; import WBCHandler from '../slack/Wbc'; class LocalStore { botId: string = null; - storedBots: any; - storedUsers: any; - botName: string = config.slack.bot_name; async start() { @@ -24,6 +21,12 @@ class LocalStore { this.storedUsers = []; this.storedBots = []; this.storedUsers = users; + this.storedUsers.push({ + id: 'BurritoFee', + name: 'BurritoFee bank', + avatar: 'https://secure.gravatar.com/avatar/c8facda114a361db902d0cbf6481e819.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0006-48.png', + memberType: 'member', + }) this.storedBots = bots; this.getBotUsername(); diff --git a/src/store/_BurritoStore.old.ts b/src/store/_BurritoStore.old.ts new file mode 100644 index 0000000..7e073b9 --- /dev/null +++ b/src/store/_BurritoStore.old.ts @@ -0,0 +1,115 @@ +import * as log from 'bog'; +import { EventEmitter } from 'events'; + +interface Find { + _id: string; + to: string; + from: string; + value: number; + given_at: Date; +} + +interface Sum { + _id?: string; // Username + score?: number; +} + +interface GetUserStats { + _id: string; + received: number; + given: number; + receivedToday: number; + givenToday: number; +} + +interface DatabasePost { + _id: string, + to: string, + from: string, + value: number, + given_at: Date +} + +class BurritoStore extends EventEmitter { + database: any = null; + + // Set and Store database object + setDatabase(database: any) { + this.database = database; + } + + async giveBurrito(to: string, from: string, date = new Date()): Promise { + log.info(`Burrito given to ${to} from ${from}`); + await this.database.give(to, from, date); + this.emit('GIVE', to, from); + return to; + } + + async takeAwayBurrito(to: string, from: string, date = new Date()): Promise { + log.info(`Burrito taken away from ${to} by ${from}`); + const score: number = await this.database.getScore(to, 'to', true); + if (!score) return []; + await this.database.takeAway(to, from, date); + this.emit('TAKE_AWAY', to, from); + return to; + } + + async getUserStats(user: string): Promise { + const [ + received, + given, + receivedToday, + givenToday, + ]: [Sum[], Sum[], number, number] = await Promise.all([ + this.database.getScore(user, 'to'), + this.database.getScore(user, 'from'), + this.givenBurritosToday(user, 'to'), + this.givenBurritosToday(user, 'from'), + ]); + return { + receivedToday, + givenToday, + _id: user, + received: received.length, + given: given.length, + }; + } + + async getScoreBoard({ ...args }): Promise { + return this.database.getScoreBoard({ ...args }); + } + + /** + * @param {string} user - userId + * @param {string} listType - to / from defaults from + */ + async givenBurritosToday(user: string, listType: string): Promise { + const givenToday: Find[] = await this.database.findFromToday(user, listType); + return givenToday.length; + } + + /** + * @param {string} user - userId + * @param {string} listType - to / from defaults from + */ + async givenToday(user: string, listType: string, type: any = false): Promise { + const givenToday: Find[] = await this.database.findFromToday(user, listType); + if (type) { + if (['inc', 'dec'].includes(type)) { + const valueFilter = (type === 'inc') ? 1 : -1; + const givenFilter = givenToday.filter((x) => x.value === valueFilter); + return givenFilter.length; + } + } + return givenToday.length; + } + + /** + * @param {string} user - userId + */ + async getUserScore(user: string, listType: string, num): Promise { + return this.database.getScore(user, listType, num); + } +} + +export default new BurritoStore(); diff --git a/src/types/Score.interface.ts b/src/types/Score.interface.ts index f2e772f..fc49cd9 100644 --- a/src/types/Score.interface.ts +++ b/src/types/Score.interface.ts @@ -1,7 +1,8 @@ export default interface Score { - _id:string; + _id?:string; to:string; from:string; value:number; given_at:Date; + type?: string; } diff --git a/src/web/index.ts b/src/web/index.ts index 6f8e5c5..60faaac 100644 --- a/src/web/index.ts +++ b/src/web/index.ts @@ -1,4 +1,4 @@ -import * as log from 'bog'; +import log from 'loglevel'; import fs from 'fs'; import http from 'http'; import path from 'path'; diff --git a/src/wss/index.ts b/src/wss/index.ts index 934a5dd..fb0e038 100644 --- a/src/wss/index.ts +++ b/src/wss/index.ts @@ -1,25 +1,24 @@ -import * as log from 'bog'; +import log from 'loglevel'; import ws from 'ws'; import BurritoStore from '../store/BurritoStore'; import config from '../config'; export default () => { - const wss = new ws.Server({ port: config.http.wss_port }); - log.info(`WebSocketServer started on port ${config.http.wss_port}`); - - wss.broadcast = (data: any) => { - wss.clients.forEach((client: any) => { - if (client.readyState === ws.OPEN) { - client.send(data); - } - }); - }; - - BurritoStore.on('GIVE', async (to: string, from: string) => { - wss.broadcast(JSON.stringify({ event: 'GIVE', data: { to, from } })); + const wss = new ws.Server({ port: config.http.wss_port }); + log.info(`WebSocketServer started on port ${config.http.wss_port}`); + const broadcast = (data: any) => { + wss.clients.forEach((client: any) => { + if (client.readyState === ws.OPEN) { + client.send(data); + } }); + }; - BurritoStore.on('TAKE_AWAY', async (to: string, from: string) => { - wss.broadcast(JSON.stringify({ event: 'TAKE_AWAY', data: { to, from } })); - }); + BurritoStore.on('GIVE', async (to: string, from: string) => { + broadcast(JSON.stringify({ event: 'GIVE', data: { to, from } })); + }); + + BurritoStore.on('TAKE_AWAY', async (to: string, from: string) => { + broadcast(JSON.stringify({ event: 'TAKE_AWAY', data: { to, from } })); + }); }; diff --git a/test/Wbc-test.ts b/test/Wbc-test.ts deleted file mode 100644 index fbfbefe..0000000 --- a/test/Wbc-test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { expect } from 'chai'; -import { WebMock } from './lib/slackMock' -import WBCHandler from '../src/slack/Wbc'; -import { wbcListParsed } from './data/slackUsers'; -let wbc: any - -beforeEach(() => { - wbc = new WebMock(); - WBCHandler.register(wbc); -}) - -describe('Wbc-test', async () => { - it('fetchSlackUsers, should return object of users and bots', async () => { - const result = await WBCHandler.fetchSlackUsers(); - // expect(result).to.deep.equal(wbcListParsed); - }); -}); diff --git a/test/burritostore-test.ts b/test/burritostore-test.ts deleted file mode 100644 index d1bf016..0000000 --- a/test/burritostore-test.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { expect } from 'chai'; -import BurritoStore from '../src/store/BurritoStore'; -import { init } from './lib/seedDatabase'; - -let mongod: any, mongoDriver: any; - -describe('Burritostore-test', async () => { - [ - { - describe: 'file Driver', - driver: 'file' - }, - { - describe: 'Array Driver', - driver: 'array' - }, - { - describe: 'Mongodb Driver', - driver: 'mongodb' - }, - ].forEach((test) => { - - - describe(test.describe, async () => { - - async function connectDB(seedDB = false) { - const dbinit: any = await init({ driver: test.driver, random: false, seedDB }); - if (dbinit.mongod && dbinit.mongoDriver) { - mongod = dbinit.mongod - mongoDriver = dbinit.mongoDriver - } - } - - async function closeDB() { - if (test.driver === 'mongodb') { - if (mongoDriver.client) await mongoDriver.client.close(); - if (mongod) await mongod.stop(); - } - } - - before(async () => { - await connectDB() - - }); - - after(async () => { - await closeDB() - }); - - - describe('giveBurrito', async () => { - it('Should give burrito and return event', async () => { - const res1 = await BurritoStore.giveBurrito('USER1', 'USER2'); - const res2 = await BurritoStore.giveBurrito('USER1', 'USER2'); - const res3 = await BurritoStore.giveBurrito('USER2', 'USER1'); - const res4 = await BurritoStore.giveBurrito('USER2', 'USER1'); - expect(res1).to.equal('USER1'); - expect(res2).to.equal('USER1'); - expect(res3).to.equal('USER2'); - expect(res4).to.equal('USER2'); - }); - }); - - describe('takeAwayBurrito', () => { - - it('Should not takeaway burrito, lowset score is 0', async () => { - const res = await BurritoStore.takeAwayBurrito('USER3', 'USER1'); - expect(res).to.deep.equal([]); - }); - - it('Should take away burrito', async () => { - const res1 = await BurritoStore.takeAwayBurrito('USER1', 'USER2'); - const res2 = await BurritoStore.takeAwayBurrito('USER1', 'USER2'); - const res3 = await BurritoStore.takeAwayBurrito('USER2', 'USER1'); - const res4 = await BurritoStore.takeAwayBurrito('USER2', 'USER1'); - expect(res1).to.equal('USER1'); - expect(res2).to.equal('USER1'); - expect(res3).to.equal('USER2'); - expect(res4).to.equal('USER2'); - }); - }); - - describe('getUserStats', () => { - - it('Should return userstats for USER1', async () => { - const res = await BurritoStore.getUserStats('USER1'); - expect(res).to.deep.equal({ - receivedToday: 4, - givenToday: 4, - _id: 'USER1', - received: 4, - given: 4 - }); - }); - - it('Should return userstats for USER2', async () => { - const res = await BurritoStore.getUserStats('USER2'); - expect(res).to.deep.equal({ - receivedToday: 4, - givenToday: 4, - _id: 'USER2', - received: 4, - given: 4 - }); - }); - - - describe('givenBurritosToday', () => { - it('Should return givenBurritosToday stats for USER1 lisyType: to', async () => { - const res = await BurritoStore.givenBurritosToday('USER1', 'to'); - expect(res).to.equal(4) - }); - it('Should return givenBurritosToday stats for USER1 lisyType: from', async () => { - const res = await BurritoStore.givenBurritosToday('USER1', 'from'); - expect(res).to.equal(4) - }); - - it('Should return givenBurritosToday stats for USER2 lisyType: to', async () => { - const res = await BurritoStore.givenBurritosToday('USER2', 'to'); - expect(res).to.equal(4) - }); - it('Should return givenBurritosToday stats for USER2 lisyType: from', async () => { - const res = await BurritoStore.givenBurritosToday('USER2', 'from'); - expect(res).to.equal(4) - }); - - - }); - }) - - }); - - - }); -}); diff --git a/test/burritostore.test.ts b/test/burritostore.test.ts new file mode 100644 index 0000000..dacaa00 --- /dev/null +++ b/test/burritostore.test.ts @@ -0,0 +1,121 @@ +import BurritoStore from '../src/store/BurritoStore'; +import { init } from './lib/seedDatabase'; + +let mongod: any, mongoDriver: any; + +describe('Burritostore-test', () => { + [ + // { + // describe: 'file Driver', + // driver: 'file' + // }, + { + describe: 'Array Driver', + driver: 'array' + }, + // { + // describe: 'Mongodb Driver', + // driver: 'mongodb' + // }, + ].forEach((test) => { + + + describe(test.describe, () => { + + async function connectDB(seedDB = false) { + const dbinit: any = await init({ driver: test.driver, random: false, seedDB }); + if (dbinit.mongod && dbinit.mongoDriver) { + mongod = dbinit.mongod + mongoDriver = dbinit.mongoDriver + } + } + + async function closeDB() { + if (test.driver === 'mongodb') { + if (mongoDriver.client) await mongoDriver.client.close(); + if (mongod) await mongod.stop(); + } + } + + beforeAll(async () => { + await connectDB() + + }); + + afterAll(async () => { + await closeDB() + }); + + + describe('giveBurrito', () => { + it('Should give burrito and return event', async () => { + const res1 = await BurritoStore.give({ to: 'USER1', from: 'USER2', type: 'inc', overdrawn: false }); + const res2 = await BurritoStore.give({ to: 'USER1', from: 'USER2', type: 'inc', overdrawn: false }); + const res3 = await BurritoStore.give({ to: 'USER2', from: 'USER1', type: 'inc', overdrawn: false }); + const res4 = await BurritoStore.give({ to: 'USER2', from: 'USER1', type: 'inc', overdrawn: false }); + expect(res1).toEqual('USER1'); + expect(res2).toEqual('USER1'); + expect(res3).toEqual('USER2'); + expect(res4).toEqual('USER2'); + }); + }); + + describe('takeAwayBurrito', () => { + + it('Should take away burrito', async () => { + const res1 = await BurritoStore.give({ to: 'USER1', from: 'USER2', type: 'dec', overdrawn: false }); + const res2 = await BurritoStore.give({ to: 'USER1', from: 'USER2', type: 'dec', overdrawn: false }); + const res3 = await BurritoStore.give({ to: 'USER2', from: 'USER1', type: 'dec', overdrawn: false }); + const res4 = await BurritoStore.give({ to: 'USER2', from: 'USER1', type: 'dec', overdrawn: false }); + expect(res1).toEqual('USER1'); + expect(res2).toEqual('USER1'); + expect(res3).toEqual('USER2'); + expect(res4).toEqual('USER2'); + }); + }); + + describe('getUserStats', () => { + it('Should return userstats for USER1', async () => { + const res = await BurritoStore.getUserStats('USER1'); + expect(res).toEqual({ + receivedToday: 4, + givenToday: 4, + _id: 'USER1', + received: 4, + given: 4 + }); + }); + + it('Should return userstats for USER2', async () => { + const res = await BurritoStore.getUserStats('USER2'); + expect(res).toEqual({ + receivedToday: 4, + givenToday: 4, + _id: 'USER2', + received: 4, + given: 4 + }); + }); + }); + + describe('givenBurritosToday', () => { + it('Should return givenBurritosToday stats for USER1 lisyType: to', async () => { + const res = await BurritoStore.givenToday('USER1', 'to'); + expect(res).toEqual(4) + }); + it('Should return givenBurritosToday stats for USER1 lisyType: from', async () => { + const res = await BurritoStore.givenToday('USER1', 'from'); + expect(res).toEqual(4) + }); + it('Should return givenBurritosToday stats for USER2 lisyType: to', async () => { + const res = await BurritoStore.givenToday('USER2', 'to'); + expect(res).toEqual(4) + }); + it('Should return givenBurritosToday stats for USER2 lisyType: from', async () => { + const res = await BurritoStore.givenToday('USER2', 'from'); + expect(res).toEqual(4) + }); + }); + }) + }); +}); diff --git a/test/globals.ts b/test/globals.ts deleted file mode 100644 index 27800ee..0000000 --- a/test/globals.ts +++ /dev/null @@ -1,7 +0,0 @@ - -import chai from 'chai'; -import { default as log } from 'bog'; - -chai.use(require('sinon-chai')); -chai.use(require('dirty-chai')); -log.level(0); diff --git a/test/lib/seedDatabase.ts b/test/lib/seedDatabase.ts index 3b98b49..8a7a3ce 100644 --- a/test/lib/seedDatabase.ts +++ b/test/lib/seedDatabase.ts @@ -28,11 +28,11 @@ function pickRandomDate(start, end) { return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); } -async function give(to, from, date) { - await BurritoStore.giveBurrito(to, from, date) +async function give(to, from, date, overdrawn = false) { + await BurritoStore.give({ to, from, type: 'inc', overdrawn }) } -async function takeaway(to, from, date) { - await BurritoStore.takeAwayBurrito(to, from, date) +async function takeaway(to, from, date, overdrawn = false) { + await BurritoStore.give({ to, from, type: 'dec', overdrawn }) } @@ -79,7 +79,7 @@ async function init({ driver = config.db.db_driver, random, seedDB = true }) { mongoDriver = databaseDrivers[driver]({ db_uri: uri, db_name: database }); BurritoStore.setDatabase(mongoDriver); } else { - BurritoStore.setDatabase(databaseDrivers[driver]()) + BurritoStore.setDatabase(databaseDrivers[driver]()) } diff --git a/test/mapper-test.ts b/test/mapper-test.ts deleted file mode 100644 index 50b92a1..0000000 --- a/test/mapper-test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import dotenv from 'dotenv'; -dotenv.config(); -import log from 'bog'; -import { expect } from 'chai'; -import { init } from './lib/seedDatabase'; -import mapper from '../src/lib/mapper'; -log.level("0") - -before(async () => { - const dbinit: any = await init({ random: false, seedDB: false }); -}); - -describe('mapper-test', async () => { - it('Should map USER2 with data from LocalStore', async () => { - const result = mapper([{ _id: 'USER2', score: 10 }]) - expect(result).to.deep.equal([ - { - username: 'USER2', - name: 'User2', - memberType: 'member', - avatar: 'https://link.to.avatar.48.burrito', - score: 10 - } - ]); - }); - - it('Should map USER1 and USER3 with data from LocalStore', async () => { - const result = mapper([{ _id: 'USER1', score: 10 }, { _id: 'USER3', score: 12 }]) - expect(result).to.deep.equal([ - { - username: 'USER1', - name: 'User1', - avatar: 'https://link.to.avatar.48.burrito', - memberType: 'member', - score: 10 - }, - { - username: 'USER3', - name: 'User3', - memberType: 'member', - avatar: 'https://link.to.avatar.48.burrito', - score: 12 - } - ]); - }); - - it('Should return empty array, due to no user found in LocalStore', async () => { - const result = mapper([{ _id: 'USER1111', score: 10 }, { _id: 'USER111111', score: 12 }]) - expect(result).to.deep.equal([]); - }); -}); diff --git a/test/mapper.test.ts b/test/mapper.test.ts new file mode 100644 index 0000000..ee17853 --- /dev/null +++ b/test/mapper.test.ts @@ -0,0 +1,49 @@ +import dotenv from 'dotenv'; +dotenv.config(); +import { init } from './lib/seedDatabase'; +import mapper from '../src/lib/mapper'; + +beforeEach(async () => { + await init({ random: false, seedDB: false }); +}); + +describe('/src/lib/mapper', () => { + + it('Should map USER2 with data from LocalStore', async () => { + const result = mapper([{ _id: 'USER2', score: 10 }]) + expect(result).toEqual([ + { + username: 'USER2', + name: 'User2', + memberType: 'member', + avatar: 'https://link.to.avatar.48.burrito', + score: 10 + } + ]); + }); + + it('Should map USER1 and USER3 with data from LocalStore', async () => { + const result = mapper([{ _id: 'USER1', score: 10 }, { _id: 'USER3', score: 12 }]) + expect(result).toEqual([ + { + username: 'USER1', + name: 'User1', + avatar: 'https://link.to.avatar.48.burrito', + memberType: 'member', + score: 10 + }, + { + username: 'USER3', + name: 'User3', + memberType: 'member', + avatar: 'https://link.to.avatar.48.burrito', + score: 12 + } + ]); + }); + + it('Should return empty array, due to no user found in LocalStore', async () => { + const result = mapper([{ _id: 'USER1111', score: 10 }, { _id: 'USER1111111', score: 12 }]) + expect(result).toEqual([]); + }); +}); diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index e69de29..0000000 diff --git a/test/parseMessage-test.ts b/test/parseMessage-test.ts deleted file mode 100644 index 234a8b4..0000000 --- a/test/parseMessage-test.ts +++ /dev/null @@ -1,242 +0,0 @@ -import { expect } from 'chai'; -import { parseMessage, parseUsernames } from '../src/lib/parseMessage' - -let msg, resultShouldBe, res, joinedChannel, pingUser, dmToBot, kicked, userJoinedChannel, emojis - -before(() => { - - emojis = [{ type: 'inc', emoji: ':burrito:' }, { type: 'dec', emoji: ':rottenburrito:' }] - - - //Hey burrito joinade en kanal - joinedChannel = { - user: 'UF34A58AC', - inviter: 'UEKN9GNAJ', - user_profile: - { - avatar_hash: 'a940dfda2378', - image_72: - 'https://avatars.slack-edge.com/2018-12-30/513714034820_a940dfda23784468d1f2_72.png', - first_name: '', - real_name: 'heyburrito', - display_name: '', - team: 'TEKBZBLVD', - name: 'heyburrito', - is_restricted: false, - is_ultra_restricted: false - }, - type: 'message', - subtype: 'channel_join', - team: 'TEKBZBLVD', - text: '<@UF34A58AC> has joined the channel', - channel: 'CF4458XJ9', - event_ts: '1546225820.000600', - ts: '1546225820.000600' - } - - pingUser = { - type: 'message', - user: 'UEKN9GNAJ', - text: '<@UF34A58AC> hejsn', - client_msg_id: 'cff7385d-56d2-4cec-a8d7-23ea85e96e22', - team: 'TEKBZBLVD', - channel: 'CF4458XJ9', - event_ts: '1546225857.000800', - ts: '1546225857.000800' - } - - //direkt meddelande till heyburrito privat - dmToBot = { - type: 'message', - user: 'UEKN9GNAJ', - text: 'jahej', - client_msg_id: 'e7f90cb1-da81-4075-828f-6f2e6ab2f12e', - team: 'TEKBZBLVD', - channel: 'DF386PMNV', - event_ts: '1546225921.000100', - ts: '1546225921.000100' - } - - // jag joinade en kanal - userJoinedChannel = { - user: 'UEKN9GNAJ', - user_profile: - { - avatar_hash: 'gc8facda114a', - image_72: - 'https://secure.gravatar.com/avatar/c8facda114a361db902d0cbf6481e819.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-72.png', - first_name: 'chralp', - real_name: 'chralp', - display_name: '', - team: 'TEKBZBLVD', - name: 'christian', - is_restricted: false, - is_ultra_restricted: false - }, - type: 'message', - subtype: 'channel_join', - team: 'TEKBZBLVD', - text: '<@UEKN9GNAJ> has joined the channel', - channel: 'CF4458XJ9', - event_ts: '1546225958.001100', - ts: '1546225958.001100' - } - - //Kickad - kicked = { - type: 'message', - user: 'USLACKBOT', - text: 'You have been removed from #test by <@UEKN9GNAJ>', - team: 'TEKBZBLVD', - channel: 'DF3M00X3N', - event_ts: '1546226014.000100', - ts: '1546226014.000100' - } - -}) - -describe('parseMessage-test', () => { - - describe('parseUsername', () => { - it('should return 2 unique usernames', () => { - msg = { - text: '<@USER2><@USER2><@USER3>:burrito: :burrito: :rottenburrito: user2', - } - resultShouldBe = ['USER2', 'USER3'] - res = parseUsernames(msg.text) - expect(res).to.deep.equal(resultShouldBe) - }); - - it('should not return any usernames', () => { - msg = { - text: '<@USER2 @USER2> :burrito: :burrito: :rottenburrito: user2', - } - res = parseUsernames(msg.text) - expect(res).to.deep.equal([]) - }); - - }) - - - describe('parseMessage', () => { - - it('should return 2 INC updates, one user', () => { - msg = { - user: 'USER1', - text: '<@USER2>:burrito: :burrito:', - } - - resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', type: 'inc' }, - { username: 'USER2', type: 'inc' }] - } - res = parseMessage(msg, emojis) - expect(res).to.deep.equal(resultShouldBe) - }); - - - it('should return 4 INC updates, two users', () => { - - msg = { - user: 'USER1', - text: '<@USER2> <@USER3> :burrito: :burrito:', - } - - resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', type: 'inc' }, - { username: 'USER3', type: 'inc' }, - { username: 'USER2', type: 'inc' }, - { username: 'USER3', type: 'inc' }] - } - res = parseMessage(msg, emojis) - expect(res).to.deep.equal(resultShouldBe) - - }); - - it('should return 4 INC updates, two users, burrito before user', () => { - - msg = { - user: 'USER1', - text: ':burrito: :burrito: <@USER2> <@USER3>', - } - - resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', type: 'inc' }, - { username: 'USER3', type: 'inc' }, - { username: 'USER2', type: 'inc' }, - { username: 'USER3', type: 'inc' }] - } - res = parseMessage(msg, emojis) - expect(res).to.deep.equal(resultShouldBe) - - }); - - - it('should return 2 DEC updates, one user', () => { - msg = { - user: 'USER1', - text: '<@USER2>:rottenburrito: :rottenburrito:', - } - - resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', type: 'dec' }, - { username: 'USER2', type: 'dec' }] - } - res = parseMessage(msg, emojis) - expect(res).to.deep.equal(resultShouldBe) - }); - - - it('should return 4 DEC updates, two users', () => { - - msg = { - user: 'USER1', - text: '<@USER2> <@USER3> :rottenburrito: :rottenburrito:', - } - - resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', type: 'dec' }, - { username: 'USER3', type: 'dec' }, - { username: 'USER2', type: 'dec' }, - { username: 'USER3', type: 'dec' }] - } - res = parseMessage(msg, emojis) - expect(res).to.deep.equal(resultShouldBe) - - }); - - it('should return 2 INC and 1 DEC updates, two users', () => { - - msg = { - user: 'USER1', - text: '<@USER2> <@USER3> :burrito::burrito: :rottenburrito:', - } - - resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', type: 'inc' }, - { username: 'USER3', type: 'inc' }, - { username: 'USER2', type: 'inc' }, - { username: 'USER3', type: 'inc' }, - { username: 'USER2', type: 'dec' }, - { username: 'USER3', type: 'dec' }] - } - res = parseMessage(msg, emojis) - expect(res).to.deep.equal(resultShouldBe) - - }); - - }); - -}); diff --git a/test/parseMessage.test.ts b/test/parseMessage.test.ts new file mode 100644 index 0000000..4a70771 --- /dev/null +++ b/test/parseMessage.test.ts @@ -0,0 +1,239 @@ +import { parseMessage, parseUsernames } from '../src/lib/parseMessage' + +let msg, resultShouldBe, res, joinedChannel, pingUser, dmToBot, kicked, userJoinedChannel, emojis + +beforeEach(() => { + + emojis = [{ type: 'inc', emoji: ':burrito:' }, { type: 'dec', emoji: ':rottenburrito:' }] + + + //Hey burrito joinade en kanal + joinedChannel = { + user: 'UF34A58AC', + inviter: 'UEKN9GNAJ', + user_profile: + { + avatar_hash: 'a940dfda2378', + image_72: + 'https://avatars.slack-edge.com/2018-12-30/513714034820_a940dfda23784468d1f2_72.png', + first_name: '', + real_name: 'heyburrito', + display_name: '', + team: 'TEKBZBLVD', + name: 'heyburrito', + is_restricted: false, + is_ultra_restricted: false + }, + type: 'message', + subtype: 'channel_join', + team: 'TEKBZBLVD', + text: '<@UF34A58AC> has joined the channel', + channel: 'CF4458XJ9', + event_ts: '1546225820.000600', + ts: '1546225820.000600' + } + + pingUser = { + type: 'message', + user: 'UEKN9GNAJ', + text: '<@UF34A58AC> hejsn', + client_msg_id: 'cff7385d-56d2-4cec-a8d7-23ea85e96e22', + team: 'TEKBZBLVD', + channel: 'CF4458XJ9', + event_ts: '1546225857.000800', + ts: '1546225857.000800' + } + + //direkt meddelande till heyburrito privat + dmToBot = { + type: 'message', + user: 'UEKN9GNAJ', + text: 'jahej', + client_msg_id: 'e7f90cb1-da81-4075-828f-6f2e6ab2f12e', + team: 'TEKBZBLVD', + channel: 'DF386PMNV', + event_ts: '1546225921.000100', + ts: '1546225921.000100' + } + + // jag joinade en kanal + userJoinedChannel = { + user: 'UEKN9GNAJ', + user_profile: + { + avatar_hash: 'gc8facda114a', + image_72: + 'https://secure.gravatar.com/avatar/c8facda114a361db902d0cbf6481e819.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F66f9%2Fimg%2Favatars%2Fava_0006-72.png', + first_name: 'chralp', + real_name: 'chralp', + display_name: '', + team: 'TEKBZBLVD', + name: 'christian', + is_restricted: false, + is_ultra_restricted: false + }, + type: 'message', + subtype: 'channel_join', + team: 'TEKBZBLVD', + text: '<@UEKN9GNAJ> has joined the channel', + channel: 'CF4458XJ9', + event_ts: '1546225958.001100', + ts: '1546225958.001100' + } + + //Kickad + kicked = { + type: 'message', + user: 'USLACKBOT', + text: 'You have been removed from #test by <@UEKN9GNAJ>', + team: 'TEKBZBLVD', + channel: 'DF3M00X3N', + event_ts: '1546226014.000100', + ts: '1546226014.000100' + } + +}) + +describe('/src/lib/parseMessage', () => { + + describe('parseUsername', () => { + it('should return 2 unique usernames', () => { + msg = { + text: '<@USER2><@USER2><@USER3>:burrito: :burrito: :rottenburrito: user2', + } + resultShouldBe = ['USER2', 'USER3'] + res = parseUsernames(msg.text) + expect(res).toEqual(resultShouldBe) + }); + + it('should not return any usernames', () => { + msg = { + text: '<@USER2 @USER2> :burrito: :burrito: :rottenburrito: user2', + } + res = parseUsernames(msg.text) + expect(res).toEqual([]) + }); + + }) + + + describe('parseMessage', () => { + + it('should return 2 INC updates, one user', () => { + msg = { + user: 'USER1', + text: '<@USER2>:burrito: :burrito:', + } + + resultShouldBe = { + giver: 'USER1', + updates: + [{ username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }] + } + res = parseMessage(msg, emojis) + expect(res).toEqual(resultShouldBe) + }); + + + it('should return 4 INC updates, two users', () => { + + msg = { + user: 'USER1', + text: '<@USER2> <@USER3> :burrito: :burrito:', + } + + resultShouldBe = { + giver: 'USER1', + updates: + [{ username: 'USER2', burritoType: 'inc' }, + { username: 'USER3', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER3', burritoType: 'inc' }] + } + res = parseMessage(msg, emojis) + expect(res).toEqual(resultShouldBe) + + }); + + it('should return 4 INC updates, two users, burrito before user', () => { + + msg = { + user: 'USER1', + text: ':burrito: :burrito: <@USER2> <@USER3>', + } + + resultShouldBe = { + giver: 'USER1', + updates: + [{ username: 'USER2', burritoType: 'inc' }, + { username: 'USER3', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER3', burritoType: 'inc' }] + } + res = parseMessage(msg, emojis) + expect(res).toEqual(resultShouldBe) + + }); + + + it('should return 2 DEC updates, one user', () => { + msg = { + user: 'USER1', + text: '<@USER2>:rottenburrito: :rottenburrito:', + } + + resultShouldBe = { + giver: 'USER1', + updates: + [{ username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }] + } + res = parseMessage(msg, emojis) + expect(res).toEqual(resultShouldBe) + }); + + + it('should return 4 DEC updates, two users', () => { + + msg = { + user: 'USER1', + text: '<@USER2> <@USER3> :rottenburrito: :rottenburrito:', + } + + resultShouldBe = { + giver: 'USER1', + updates: + [{ username: 'USER2', burritoType: 'dec' }, + { username: 'USER3', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER3', burritoType: 'dec' }] + } + res = parseMessage(msg, emojis) + expect(res).toEqual(resultShouldBe) + + }); + + it('should return 2 INC and 1 DEC updates, two users', () => { + + msg = { + user: 'USER1', + text: '<@USER2> <@USER3> :burrito::burrito: :rottenburrito:', + } + + resultShouldBe = { + giver: 'USER1', + updates: + [{ username: 'USER2', burritoType: 'inc' }, + { username: 'USER3', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER3', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER3', burritoType: 'dec' }] + } + res = parseMessage(msg, emojis) + expect(res).toEqual(resultShouldBe) + + }); + }); +}); diff --git a/test/setup.ts b/test/setup.ts new file mode 100644 index 0000000..2439a10 --- /dev/null +++ b/test/setup.ts @@ -0,0 +1,3 @@ + +global.console.warn = jest.fn(); +global.console.debug = jest.fn(); diff --git a/test/utils-test.ts b/test/utils-test.ts deleted file mode 100644 index 4ea57a0..0000000 --- a/test/utils-test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { WebMock } from './lib/slackMock' -import { stub } from 'sinon'; -import { expect } from 'chai'; -import { sort } from '../src/lib/utils'; -let data; -beforeEach(() => { - data = [ - { - username: 'USER2', - name: 'User2', - avatar: 'https://link.to.avatar.48.burrito', - score: 3 - }, - { - username: 'USER1', - name: 'User1', - avatar: 'https://link.to.avatar.48.burrito', - score: 15 - }, - { - username: 'USER3', - name: 'User3', - avatar: 'https://link.to.avatar.48.burrito', - score: 20 - } - ] -}) - -describe('Utils-test', async () => { - it('should return shorted list descending', async () => { - expect(sort(data)).to.deep.equal([ - { - username: 'USER3', - name: 'User3', - avatar: 'https://link.to.avatar.48.burrito', - score: 20 - }, - { - username: 'USER1', - name: 'User1', - avatar: 'https://link.to.avatar.48.burrito', - score: 15 - }, - { - username: 'USER2', - name: 'User2', - avatar: 'https://link.to.avatar.48.burrito', - score: 3 - } - ]); - }); - - it('should return shorted list ascending', async () => { - expect(sort(data, 'asc')).to.deep.equal([ - { - username: 'USER2', - name: 'User2', - avatar: 'https://link.to.avatar.48.burrito', - score: 3 - }, - { - username: 'USER1', - name: 'User1', - avatar: 'https://link.to.avatar.48.burrito', - score: 15 - }, - { - username: 'USER3', - name: 'User3', - avatar: 'https://link.to.avatar.48.burrito', - score: 20 - }, - - ]); - }); -}); diff --git a/test/utils.test.ts b/test/utils.test.ts new file mode 100644 index 0000000..45977f0 --- /dev/null +++ b/test/utils.test.ts @@ -0,0 +1,73 @@ +import { sort } from '../src/lib/utils'; +let data; +beforeEach(() => { + data = [ + { + username: 'USER2', + name: 'User2', + avatar: 'https://link.to.avatar.48.burrito', + score: 3 + }, + { + username: 'USER1', + name: 'User1', + avatar: 'https://link.to.avatar.48.burrito', + score: 15 + }, + { + username: 'USER3', + name: 'User3', + avatar: 'https://link.to.avatar.48.burrito', + score: 20 + } + ] +}) + +describe('Utils-test', () => { + it('should return shorted list descending', () => { + expect(sort(data)).toEqual([ + { + username: 'USER3', + name: 'User3', + avatar: 'https://link.to.avatar.48.burrito', + score: 20 + }, + { + username: 'USER1', + name: 'User1', + avatar: 'https://link.to.avatar.48.burrito', + score: 15 + }, + { + username: 'USER2', + name: 'User2', + avatar: 'https://link.to.avatar.48.burrito', + score: 3 + } + ]); + }); + + it('should return shorted list ascending', () => { + expect(sort(data, 'asc')).toEqual([ + { + username: 'USER2', + name: 'User2', + avatar: 'https://link.to.avatar.48.burrito', + score: 3 + }, + { + username: 'USER1', + name: 'User1', + avatar: 'https://link.to.avatar.48.burrito', + score: 15 + }, + { + username: 'USER3', + name: 'User3', + avatar: 'https://link.to.avatar.48.burrito', + score: 20 + }, + + ]); + }); +}); diff --git a/test/validator-test.ts b/test/validator-test.ts deleted file mode 100644 index e7b1903..0000000 --- a/test/validator-test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { expect } from 'chai'; -import { validBotMention, validMessage, selfMention, sentFromBot, sentToBot } from '../src/lib/validator' -let msg, resultShouldBe, res, storedBots, joinedChannel, pingUser, dmToBot, kicked, userJoinedChannel, emojis; - -describe('/app/lib/validator', () => { - - beforeEach(() => { - res = null - emojis = [{ type: 'inc', emoji: ':burrito:' }, { type: 'dec', emoji: ':rottenburrito:' }] - - storedBots = [{ - id: 'HEYBURRITO', - name: 'heyburrito', - avatar: 'https://burrito.web.png' - }, - { - id: 'slackbot', - name: 'slackbot', - avatar: 'https://slack.bot.png' - }] - - }) - - - describe('sentFromBot', () => { - - it('should return true', () => { - msg = { - user: 'HEYBURRITO', - text: 'hejsan' - } - - res = sentFromBot(msg, storedBots) - expect(res).to.equal(true) - }); - - it('should return false', () => { - msg = { - user: 'notBot', - text: 'hejsan' - } - - res = sentFromBot(msg, storedBots) - expect(res).to.equal(false) - }); - }); - - - describe('sentToBot', () => { - - it('should return true', () => { - msg = { - user: 'USER1', - text: 'hello <@HEYBURRITO>' - } - - res = sentToBot(msg, storedBots) - expect(res).to.equal(true) - }); - - it('should return false', () => { - - msg = { - user: 'USER1', - text: 'hello HEYBURRITO' - } - - res = sentToBot(msg, storedBots) - expect(res).to.equal(false) - }); - - - }); - - - // Test if sender is mentioned in slackmessage - describe('selfMention', () => { - - it('should return true', () => { - msg = { - user: 'USER1', - text: '<@USER2> <@USER1> :burrito: :burrito:' - } - res = selfMention(msg) - expect(res).to.equal(true) - }); - - it('should return false', () => { - msg = { - user: 'USER1', - text: '<@USER2> :burrito: :burrito:' - } - res = selfMention(msg) - expect(res).to.equal(false) - }); - - }) -}); diff --git a/test/validator.test.ts b/test/validator.test.ts new file mode 100644 index 0000000..de047b8 --- /dev/null +++ b/test/validator.test.ts @@ -0,0 +1,94 @@ +import { validBotMention, validMessage, selfMention, sentFromBot, sentToBot } from '../src/lib/validator' +let msg, resultShouldBe, res, storedBots, joinedChannel, pingUser, dmToBot, kicked, userJoinedChannel, emojis; + +describe('/src/lib/validator', () => { + + beforeEach(() => { + res = null + emojis = [{ type: 'inc', emoji: ':burrito:' }, { type: 'dec', emoji: ':rottenburrito:' }] + + storedBots = [{ + id: 'HEYBURRITO', + name: 'heyburrito', + avatar: 'https://burrito.web.png' + }, + { + id: 'slackbot', + name: 'slackbot', + avatar: 'https://slack.bot.png' + }] + }) + + + describe('sentFromBot', () => { + + it('should return true', () => { + msg = { + user: 'HEYBURRITO', + text: 'hejsan' + } + + res = sentFromBot(msg, storedBots) + expect(res).toEqual(true) + }); + + it('should return false', () => { + msg = { + user: 'notBot', + text: 'hejsan' + } + + res = sentFromBot(msg, storedBots) + expect(res).toEqual(false) + }); + }); + + + describe('sentToBot', () => { + + it('should return true', () => { + msg = { + user: 'USER1', + text: 'hello <@HEYBURRITO>' + } + + res = sentToBot(msg, storedBots) + expect(res).toEqual(true) + }); + + it('should return false', () => { + + msg = { + user: 'USER1', + text: 'hello HEYBURRITO' + } + + res = sentToBot(msg, storedBots) + expect(res).toEqual(false) + }); + }); + + + // Test if sender is mentioned in slackmessage + describe('selfMention', () => { + + + it('should return true', () => { + msg = { + user: 'USER1', + text: '<@USER2> <@USER1> :burrito: :burrito:' + } + res = selfMention(msg) + expect(res).toEqual(true) + }); + + it('should return false', () => { + msg = { + user: 'USER1', + text: '<@USER2> :burrito: :burrito:' + } + res = selfMention(msg) + expect(res).toEqual(false) + }); + }) +}); diff --git a/test/wbc.test.ts b/test/wbc.test.ts new file mode 100644 index 0000000..dd0b4f7 --- /dev/null +++ b/test/wbc.test.ts @@ -0,0 +1,16 @@ +import { WebMock } from './lib/slackMock' +import WBCHandler from '../src/slack/Wbc'; +import { wbcListParsed } from './data/slackUsers'; +let wbc: any + +beforeEach(() => { + wbc = new WebMock(); + WBCHandler.register(wbc); +}) + +describe('Wbc-test', () => { + it('fetchSlackUsers, should return object of users and bots', async () => { + const result = await WBCHandler.fetchSlackUsers(); + //expect(result).toEqual(wbcListParsed); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index cb40b2f..72a0f9b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,20 @@ { - "compilerOptions": { - "baseUrl": ".", - "esModuleInterop": true, - "target": "es2017", - "lib": [ "es2017", "dom" ], - "paths": { - "*": ["./declarations"] - }, - "typeRoots": [ - "./node_modules/@types" - ], - "module": "commonjs" - } + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "outDir": "dist", + "sourceMap": true, + "lib": ["es2017"], + "esModuleInterop": true, + "resolveJsonModule": true + }, + "files": [ + "./node_modules/@types/node/index.d.ts" + ], + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } From 5ffbf25a20e102a2d90bba22a6c6724ca87bd58f Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Thu, 27 Jan 2022 22:30:14 +0100 Subject: [PATCH 02/51] test code, new way to calculate --- src/database/drivers/Driver.ts | 12 +- src/database/drivers/Store.ts | 124 +++++++++---------- src/lib/utils.ts | 4 + src/middleware.ts | 31 ++--- src/store/BurritoStore.ts | 111 +++-------------- src/store/calc.ts | 151 +++++++++++++++++++++++ test/chralp.test.ts | 204 +++++++++++++++++++++++++++++++ test/data/calculatescore-data.ts | 133 ++++++++++++++++++++ 8 files changed, 586 insertions(+), 184 deletions(-) create mode 100644 src/store/calc.ts create mode 100644 test/chralp.test.ts create mode 100644 test/data/calculatescore-data.ts diff --git a/src/database/drivers/Driver.ts b/src/database/drivers/Driver.ts index 4e9883a..678221b 100644 --- a/src/database/drivers/Driver.ts +++ b/src/database/drivers/Driver.ts @@ -8,12 +8,12 @@ export interface Find { }; export interface DatabasePost { - _id: string, - to: string, - from: string, - value: number, - given_at: Date; - overdrawn: boolean; + _id?: string, + to?: string, + from?: string, + value?: number, + given_at?: Date; + overdrawn?: boolean; }; export interface GetScoreBoard { diff --git a/src/database/drivers/Store.ts b/src/database/drivers/Store.ts index e34d78c..6c7a5ca 100644 --- a/src/database/drivers/Store.ts +++ b/src/database/drivers/Store.ts @@ -3,78 +3,78 @@ import path from 'path'; import config from '../../config'; export default class Store { - dbPath: string; + dbPath: string; - connected: boolean; + connected: boolean; - dataSynced: boolean; + dataSynced: boolean; - data: any; + data: any; - constructor(public driver: string) { - this.connected = false; - this.dbPath = path.resolve(`${config.db.db_path}${config.db.db_fileName}`); - this.dataSynced = false; - this.data = []; - } + constructor(public driver: string) { + this.connected = false; + this.dbPath = path.resolve(`${config.db.db_path}${config.db.db_fileName}`); + this.dataSynced = false; + this.data = []; + } - connect(): boolean { - if (this.driver === 'array') { - this.connected = true; - return true; - } - - if (this.driver === 'file') { - if (!this.connected && !fs.existsSync(this.dbPath)) { - fs.writeFileSync(this.dbPath, '', 'utf8'); - this.connected = true; - return true; - } - } - return false; + connect(): boolean { + if (this.driver === 'array') { + this.connected = true; + return true; } - syncData() { - this.connect(); - if (this.driver === 'array') return true; - - this.data = []; - - const fd = fs.readFileSync(this.dbPath, 'utf8'); - if (!fd.length) return false; - - const items = fd.split('\n'); - if (!items.length) return false; - - const mappedItems = items.map((item: any) => { - let parsedData: any; - try { - parsedData = JSON.parse(item); - } catch (ex) { - return null; - } - - parsedData.given_at = new Date(parsedData.given_at); - return parsedData; - }); - this.data = mappedItems.filter((item: any) => item); + if (this.driver === 'file') { + if (!this.connected && !fs.existsSync(this.dbPath)) { + fs.writeFileSync(this.dbPath, '', 'utf8'); + this.connected = true; return true; + } } - - async storeData(score) { - if (this.driver === 'array') { - this.data.push(score); - return true; - } - - if (this.driver === 'file') { - await fs.appendFileSync(this.dbPath, `\n${JSON.stringify(score)}`); - return true; - } - return false; + return false; + } + + syncData() { + this.connect(); + if (this.driver === 'array') return true; + + this.data = []; + + const fd = fs.readFileSync(this.dbPath, 'utf8'); + if (!fd.length) return false; + + const items = fd.split('\n'); + if (!items.length) return false; + + const mappedItems = items.map((item: any) => { + let parsedData: any; + try { + parsedData = JSON.parse(item); + } catch (ex) { + return null; + } + + parsedData.given_at = new Date(parsedData.given_at); + return parsedData; + }); + this.data = mappedItems.filter((item: any) => item); + return true; + } + + async storeData(score) { + if (this.driver === 'array') { + this.data.push(score); + return true; } - async getData() { - return this.data; + if (this.driver === 'file') { + fs.appendFileSync(this.dbPath, `\n${JSON.stringify(score)}`); + return true; } + return false; + } + + async getData() { + return this.data; + } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 62022ac..2205803 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -90,6 +90,9 @@ const getThemePath = () => { return `${themeRootPath}${themeName}/`; }; + +const listTypeSwitch = (listType: string) => listType === 'to' ? 'from' : 'to'; + export { time, sort, @@ -103,4 +106,5 @@ export { root, getThemePath, getThemeName, + listTypeSwitch, }; diff --git a/src/middleware.ts b/src/middleware.ts index d3086f5..2f4b440 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -2,6 +2,7 @@ import config from './config'; import mapper from './lib/mapper'; import { sort } from './lib/utils'; import BurritoStore from './store/BurritoStore'; +import { levelScoreList, calculateScore } from './store/calc'; const { level: { @@ -16,21 +17,6 @@ const { -export const listTypeSwitch = (listType: string) => listType === 'to' ? 'from' : 'to'; - - -const levelScoreList = (scoreList) => scoreList.map((x: any) => { - let score = x.score; - const roundedScore = Math.floor(score / scoreRotation) * scoreRotation; - const level = Math.floor((score - 1) / scoreRotation); - const newScore = ((score - roundedScore) === 0 ? roundedScore - (score - scoreRotation) : score - roundedScore); - return { - _id: x._id, - score: newScore, - level, - } -}); - /** * Middleware for API and Websocket */ @@ -41,19 +27,20 @@ const levelScoreList = (scoreList) => scoreList.map((x: any) => { */ const getScoreBoard = async (listType: string, scoreType: string) => { - const _data = await BurritoStore.getScoreBoard({ listType }); - - // We want to filter out data that we want first - const data = BurritoStore.filterScoreData(_data, scoreType); + const data = await BurritoStore.getScoreBoard({ listType }); // Get unique Usernames const uniqueUsername: string[] = [...new Set(data.map((x) => x[listType]))]; - + console.log(uniqueUsername) const scoreList = uniqueUsername - .map((user) => ({ _id: user, score: BurritoStore._calucateScore(data, user, { listType, scoreType }) })) + .map((user) => ({ _id: user, score: calculateScore(data, data, { listType, scoreType, user}) })) .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); - return enableLevel ? sort(mapper(levelScoreList(scoreList))) : sort(mapper(scoreList)); + console.log("scoreList", scoreList) + const handledScore = enableLevel ? sort(mapper(levelScoreList(scoreList))) : sort(mapper(scoreList)); + console.log("enableLevel", enableLevel) + console.log("handledScore", handledScore) + return handledScore }; const _getUserScoreBoard = async ({ ...args }) => { diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 6f08ecc..2082cc9 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -1,19 +1,13 @@ import log from 'loglevel'; import { EventEmitter } from 'events'; import config from '../config'; -import { listTypeSwitch } from '../middleware'; - +import { listTypeSwitch } from '../lib/utils'; +import {calculateScore} from './calc'; import Driver, { GetScoreBoard, DatabasePost, } from '../database/drivers/Driver'; -const { - slack: { - enableOverDraw, - enableDecrement, - } -} = config; interface CalucateUserScore { listType?: string; @@ -36,6 +30,10 @@ interface BurritoUpdate { overdrawn?: boolean; } + +console.log("OUTSIDE", config.slack.enableOverDraw, config.slack.enableDecrement) + + class BurritoStore extends EventEmitter { database: Driver; @@ -86,8 +84,8 @@ class BurritoStore extends EventEmitter { receivedToday, givenToday, _id: user, - received: this.calucateScore(received, {}), - given: this.calucateScore(given, {}) + received: calculateScore(received, [],{}), + given: calculateScore(given, [],{}) }; }; @@ -107,9 +105,9 @@ class BurritoStore extends EventEmitter { return !x.overdrawn }; }); - return this.calucateScore(givenFilter, {}); + return calculateScore(givenFilter, [], { listType, scoreType, user }); }; - return this.calucateScore(givenToday, {}); + return calculateScore(givenToday, [], { listType, scoreType, user }); }; @@ -120,77 +118,28 @@ class BurritoStore extends EventEmitter { */ public async getUserScore(user: string, listType: string, scoreType: string): Promise { + const { enableDecrement, enableOverDraw } = config.slack + console.log("INSIDE", enableOverDraw, enableDecrement) // Get users score from DB, ( Only all inc not calculated with dec or overdrwan) const _data = await this.database.getScore(user, listType); if (enableOverDraw) { const _dataSwitched = await this.database.getScore(user, listTypeSwitch(listType)); const data = _dataSwitched.filter((entry) => (!!entry.overdrawn)); - return _data.length - data.length; + return calculateScore(_data, [], { listType, scoreType, user }); } - return _data.length; + return calculateScore(_data, [], { listType, scoreType, user }); }; - - // countScore - public calucateScore(data: DatabasePost[], args: CalucateUserScore) { - const { listType, scoreType, user } = args; - const valueSwitch = (scoreType === 'dec') ? 1 : 0; - - const gg = data.reduce((total: number, current: any): number => { - if (listType) { - if (current[listType] === user) { - return total + (valueSwitch || current.value); - } - return total; - } else { - return total + 1; - } - }, 0); - return gg; - }; - - - public _filterScoreData(data: DatabasePost[], scoreType: string) { - console.log("_filterScoreData => scoreType:", scoreType); - const scoreSwitch = (scoreType === 'inc') ? 1 : -1; - const valueSwitch = (scoreType === 'dec') ? 1 : 0; - - return data.filter((entry) => { - - /* if enableDecrement return 1 AND -1 - * check first if enableOverDraw, if so return only if enableOverDraw = true - */ - if (enableDecrement) { - - if (enableOverDraw) { - return valueSwitch - ? (entry.overdrawn !== true && entry.value === scoreSwitch) - : entry.overdrawn !== true; - } else { - return valueSwitch ? entry.value === scoreSwitch : entry; - } - - - } else { - if (entry.value == scoreSwitch) { - if (enableOverDraw) return entry; - return entry.overdrawn !== true; - } - return null; - } - }); - }; - public filterScoreData(data: DatabasePost[], scoreType: string) { const scoreSwitch = (scoreType === 'inc') ? 1 : -1; const valueSwitch = (scoreType === 'dec') ? 1 : 0; return data.filter((entry) => { - if (enableDecrement) { - if (!enableOverDraw) { + if (config.slack.enableDecrement) { + if (!config.slack.enableOverDraw) { return valueSwitch ? (entry.overdrawn !== true && entry.value === scoreSwitch) : entry.overdrawn !== true; @@ -199,38 +148,12 @@ class BurritoStore extends EventEmitter { } } else { if (entry.value == scoreSwitch) { - if (enableOverDraw) return entry; + if (config.slack.enableOverDraw) return entry; return entry.overdrawn !== true; } } }); }; - - - public _getOverDrawn (user: string) { - - } - - public _calucateScore(data, user: string, { listType, scoreType }): number { - const valueSwitch = (scoreType === 'dec') ? 1 : 0; - - if (enableOverDraw) { - const scoreOverDrawn = data.reduce((total: number, entry) => { - if (!!entry.overdrawn && entry[listTypeSwitch(listType)] == user) { - return total + (valueSwitch || entry.value); - } - return total; - }, 0); - console.log("DJAHA", user, scoreOverDrawn) - const _score = this.calucateScore(data, { user, listType, scoreType }); - - console.log("_score", _score) - return scoreOverDrawn ? _score - scoreOverDrawn : _score; - } else { - return this.calucateScore(data, { user, listType, scoreType }); - } - - }; } export default new BurritoStore(); diff --git a/src/store/calc.ts b/src/store/calc.ts new file mode 100644 index 0000000..7c24c52 --- /dev/null +++ b/src/store/calc.ts @@ -0,0 +1,151 @@ +import config from '../config'; +import { listTypeSwitch } from '../lib/utils'; +import { DatabasePost } from '../database/drivers/Driver'; + +interface CalculateScoreArgs { + listType?: string; + scoreType?: string; + user?: string; + countOverDrawn?: boolean; +} + +/** + * Since ive added some features as levelUp and overdrawn and decrement + * adding code to calulate this everywhere makes no sense. And depening on ENVS + * makes everything harder. + * Trying to add add dumb calculations in this file + */ + + +export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePost[], args?: CalculateScoreArgs): number => { + const { listType, scoreType, user } = args; + const valueSwitch = (scoreType === 'dec') ? 1 : 0; + console.log("aaa", data) + console.log("valueSwitch", valueSwitch) + console.log(listType, scoreType, user) + + const { enableOverDraw } = config.slack; + + + const _dataOverDrawn = overDrawnData.filter((entry: DatabasePost) => { + + if (enableOverDraw) { + /** + * Just ensure that we filter out correct user data if user is present + */ + const list = listType === 'to' ? listTypeSwitch(listType) : listType; + if (listType !== 'from') { + if (user && entry[list] === user && !!entry.overdrawn) { + return entry; + } + } + } + }); + + const _scoreOverdrawn = _dataOverDrawn.reduce((total: number, current: DatabasePost): number => { + return total + current.value; + }, 0); + + console.log("_scoreOverdrawn", _scoreOverdrawn) + const _score = data.reduce((total: number, current: DatabasePost): number => { + + /** + * enableDecrement = true + * calc: + * all values beside overdrawn? + */ + + if (config.slack.enableDecrement) { + + if (listType && user && current[listType] === user) { + + if (enableOverDraw) { + if (current.overdrawn) { + return total + current.value; + } + return total; + } + + + if(listType === 'from' && scoreType === 'inc' && current.value === 1) { + return total + current.value + + }else if(listType === 'to' && scoreType === 'inc') { + return total + current.value + + }else { + return total; + } + + + // THIS SEAMS TO WORK + if (!current.overdrawn) return total + current.value; + } + return total; + } + + /** + * enableDecrement = false + * calc: + * only postive number + */ + if (!config.slack.enableDecrement) { + + if (listType && user && current[listType] === user) { + + + if(listType === 'to' && scoreType === 'dec') { + if(current.value === -1){ + return total + 1; + } else { + return total; + } + } + + + if (enableOverDraw && current.overdrawn) { + // Is this right?? + return total + current.value; + } + + + + if (current.value === 1 && !current.overdrawn) return total + current.value; + return total; + } + return total; + } + }, 0); + console.log("_score", _score) + return _score - _scoreOverdrawn; +}; + + + + + + + + + + + + + +export const levelScoreList = (scoreList: any) => { + const data = scoreList.map((x: any) => { + const { scoreRotation } = config.level; + let score = x.score; + const roundedScore = Math.floor(score / scoreRotation) * scoreRotation; + const level = Math.floor((score - 1) / scoreRotation); + const newScore = ((score - roundedScore) === 0 ? roundedScore - (score - scoreRotation) : score - roundedScore); + return { + _id: x._id, + score: newScore, + level, + } + }); + return data; + + +} diff --git a/test/chralp.test.ts b/test/chralp.test.ts new file mode 100644 index 0000000..a355650 --- /dev/null +++ b/test/chralp.test.ts @@ -0,0 +1,204 @@ +import { calculateScore } from '../src/store/calc' +import * as config from '../src/config'; +import { scoreBoard } from './data/calculatescore-data'; + + +interface args { + listType: string; + scoreType: string; + user?: string; +} + +const getScore = ({ listType, scoreType, user }:args) => { + const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + + const scoreList = uniqueUsername + .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) + .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); + return scoreList; +} + + +describe('calculateScore', () => { + + // describe('userscore', () => { + // it('User1 score should be 3 { enableOverDraw: false, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: false } + // const result = calculateScore(data, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) + // expect(result).toEqual(3) + // }); + + // it('User1 score should be 4 { enableOverDraw: true, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const result = calculateScore(data, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) + // expect(result).toEqual(4) + // }); + + // it('User1 score should be 3 with overdrawn data { enableOverDraw: true, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const overdrawn = [ + // { + // to: 'USER2', + // from: 'USER1', + // value: 1, + // overdrawn: true + // }, + // { + // to: 'USER2', + // from: 'USER3', + // value: 1, + // overdrawn: true + // }, + // ] + // const result = calculateScore(data, overdrawn, { listType: 'to', scoreType: 'inc', user: 'USER1' }) + // expect(result).toEqual(3) + // }); + + // it('User1 score should be 2 with overdrawn data { enableOverDraw: true, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const overdrawn = [ + // { + // to: 'USER2', + // from: 'USER1', + // value: 1, + // overdrawn: true + // }, + // { + // to: 'USER2', + // from: 'USER1', + // value: 1, + // overdrawn: true + // }, + // { + // to: 'USER2', + // from: 'USER3', + // value: 1, + // overdrawn: true + // }, + // ] + // const result = calculateScore(data, overdrawn, { listType: 'to', scoreType: 'inc', user: 'USER1' }) + // expect(result).toEqual(2) + // }); + + // it('User1 score should be 2 { enableOverDraw: false, enableDecrement: true }', async () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: true } + // const result = calculateScore(data, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) + // expect(result).toEqual(2) + // }); + + // }); + + describe('scoreboard', () => { + + it('Should calc scoreboard => to & inc => { enableOverDraw: false, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const listType = 'to'; + const scoreType = 'inc' + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([{ _id: 'USER1', score: 9 }, { _id: 'USER2', score: 5 }]) + }); + + + it('Should calc scoreboard => to & inc => { enableOverDraw: true, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const listType = 'to'; + const scoreType = 'inc' + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([{ _id: 'USER1', score: 4 }, { _id: 'USER2', score: 10 }]) + }); + + + it('Should calc scoreboard => to & inc => { enableOverDraw: false, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const listType = 'to'; + const scoreType = 'inc' + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([{ _id: 'USER1', score: 8 }, { _id: 'USER2', score: 8 }]) + }); + + + it('Should calc scoreboard => to & dec => { enableOverDraw: false, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const listType = 'to'; + const scoreType = 'dec' + + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([{ _id: 'USER1', score: 1 }, { _id: 'USER2', score: 2 }]) + }); + + + it('Should calc scoreboard => to & dec => { enableOverDraw: true, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const listType = 'to'; + const scoreType = 'dec' + const scoreList = getScore({ listType, scoreType }) + console.log("scoreBoard", scoreBoard) + console.log("List", scoreList) + expect(scoreList).toEqual([{ _id: 'USER1', score: 1 }, { _id: 'USER2', score: 2 }]) + }); + + + + // test listType from + // test scoreType dec + + // it('Should calc scoreboard => from & inc => { enableOverDraw: false, enableDecrement: false }', async () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: false } + // const listType = 'from'; + // const scoreType = 'inc' + // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + + // const scoreList = uniqueUsername + // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) + // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); + + // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 5 }]) + // }); + + // it('Should calc scoreboard => from & inc => { enableOverDraw: true, enableDecrement: false }', async () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const listType = 'from'; + // const scoreType = 'inc' + // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + + // const scoreList = uniqueUsername + // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) + // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); + // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 10 }]) + // }); + + + // it('Should calc scoreboard => from & inc => { enableOverDraw: false, enableDecrement: true }', async () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: true } + // const listType = 'from'; + // const scoreType = 'inc' + // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + + // const scoreList = uniqueUsername + // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) + // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); + + // console.log("scoreBoard", scoreBoard) + // console.log("scoreList", scoreList) + // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 10 }]) + // }); + + + // it('Should calc scoreboard => from & dec => { enableOverDraw: false, enableDecrement: false }', async () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const listType = 'from'; + // const scoreType = 'inc' + // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + + // const scoreList = uniqueUsername + // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) + // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); + // console.log("scoreBoard", scoreBoard) + // console.log("scoreList", scoreList) + // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 10 }]) + // }); + + + }); + +}); diff --git a/test/data/calculatescore-data.ts b/test/data/calculatescore-data.ts new file mode 100644 index 0000000..0f3c8ae --- /dev/null +++ b/test/data/calculatescore-data.ts @@ -0,0 +1,133 @@ + + +export const scoreBoard = [ + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER1', + from: 'USER2', + value: 1, + overdrawn: false + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: false + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: false + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: false + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: false + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: false + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: true + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: true + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: true + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: true + }, + { + to: 'USER2', + from: 'USER1', + value: 1, + overdrawn: true + }, + { + to: 'USER2', + from: 'USER1', + value: -1, + }, + { + to: 'USER2', + from: 'USER1', + value: -1, + }, + { + to: 'USER1', + from: 'USER2', + value: -1, + } +] From 5ef828f6e3395e77b435610571453f28035d78cc Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 28 Jan 2022 18:48:06 +0100 Subject: [PATCH 03/51] update --- src/store/calc.ts | 95 ++++------ test/chralp.test.ts | 287 ++++++++++++++-------------- test/data/calculatescore-data.ts | 309 ++++++++++++++++++------------- 3 files changed, 362 insertions(+), 329 deletions(-) diff --git a/src/store/calc.ts b/src/store/calc.ts index 7c24c52..8076f8a 100644 --- a/src/store/calc.ts +++ b/src/store/calc.ts @@ -1,5 +1,5 @@ import config from '../config'; -import { listTypeSwitch } from '../lib/utils'; +import { listTypeSwitch, sort } from '../lib/utils'; import { DatabasePost } from '../database/drivers/Driver'; interface CalculateScoreArgs { @@ -20,12 +20,9 @@ interface CalculateScoreArgs { export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePost[], args?: CalculateScoreArgs): number => { const { listType, scoreType, user } = args; const valueSwitch = (scoreType === 'dec') ? 1 : 0; - console.log("aaa", data) - console.log("valueSwitch", valueSwitch) console.log(listType, scoreType, user) - const { enableOverDraw } = config.slack; - + const { enableOverDraw, enableDecrement} = config.slack; const _dataOverDrawn = overDrawnData.filter((entry: DatabasePost) => { @@ -46,87 +43,69 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos return total + current.value; }, 0); - console.log("_scoreOverdrawn", _scoreOverdrawn) - const _score = data.reduce((total: number, current: DatabasePost): number => { - /** - * enableDecrement = true - * calc: - * all values beside overdrawn? - */ + if(user === 'USER3') console.log("_scoreOverdrawn", _scoreOverdrawn) - if (config.slack.enableDecrement) { + const _score = data.reduce((total: number, current: DatabasePost): number => { - if (listType && user && current[listType] === user) { + // We only want to handle the correct user data depending on listTypeon current[listType] === USER + if(!(current[listType] === user)) return total; - if (enableOverDraw) { - if (current.overdrawn) { - return total + current.value; - } - return total; - } + /** + * We want to calculate the score differently + * depending on listType and scoreType. + * Main scoreBoard: listType === 'to' && scoreType === 'inc' + * This scoreBoard should take into account if decrement or overdrawn is enabled or not. + */ + if (listType === 'to' && scoreType === 'inc') { - if(listType === 'from' && scoreType === 'inc' && current.value === 1) { - return total + current.value + // Just count everything + if (enableOverDraw && enableDecrement) return total + current.value; - }else if(listType === 'to' && scoreType === 'inc') { - return total + current.value - }else { - return total; - } + if (enableOverDraw) { + if (current.value !== -1) return total + current.value; + return total; + } - // THIS SEAMS TO WORK + if (enableDecrement) { if (!current.overdrawn) return total + current.value; + return total; } + + // Ensure we only return positive value and that current.overdrawn is false + if (current.value === 1 && !current.overdrawn) return total + current.value; return total; } - /** - * enableDecrement = false - * calc: - * only postive number - */ - if (!config.slack.enableDecrement) { - - if (listType && user && current[listType] === user) { - - - if(listType === 'to' && scoreType === 'dec') { - if(current.value === -1){ - return total + 1; - } else { - return total; - } - } + // We only want to return a list of received dec + if (listType === 'to' && scoreType === 'dec') { + if (current.value === -1) return total + 1; + // Add support for overdrawn? + return total; + } + if (listType === 'from' && scoreType === 'inc') { - if (enableOverDraw && current.overdrawn) { - // Is this right?? - return total + current.value; - } + } - if (current.value === 1 && !current.overdrawn) return total + current.value; - return total; - } - return total; - } - }, 0); - console.log("_score", _score) - return _score - _scoreOverdrawn; -}; + return total; + }, 0); + console.log("---------------\n", _score, _scoreOverdrawn) + return _score - _scoreOverdrawn; +}; diff --git a/test/chralp.test.ts b/test/chralp.test.ts index a355650..b6c5a1c 100644 --- a/test/chralp.test.ts +++ b/test/chralp.test.ts @@ -1,6 +1,6 @@ import { calculateScore } from '../src/store/calc' import * as config from '../src/config'; -import { scoreBoard } from './data/calculatescore-data'; +import { scoreBoard, user1ScoreData, user2ScoreData, user3ScoreData, user4ScoreData } from './data/calculatescore-data'; interface args { @@ -21,183 +21,186 @@ const getScore = ({ listType, scoreType, user }:args) => { describe('calculateScore', () => { - // describe('userscore', () => { - // it('User1 score should be 3 { enableOverDraw: false, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: false } - // const result = calculateScore(data, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) - // expect(result).toEqual(3) - // }); - - // it('User1 score should be 4 { enableOverDraw: true, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const result = calculateScore(data, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) - // expect(result).toEqual(4) - // }); - - // it('User1 score should be 3 with overdrawn data { enableOverDraw: true, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const overdrawn = [ - // { - // to: 'USER2', - // from: 'USER1', - // value: 1, - // overdrawn: true - // }, - // { - // to: 'USER2', - // from: 'USER3', - // value: 1, - // overdrawn: true - // }, - // ] - // const result = calculateScore(data, overdrawn, { listType: 'to', scoreType: 'inc', user: 'USER1' }) - // expect(result).toEqual(3) - // }); - - // it('User1 score should be 2 with overdrawn data { enableOverDraw: true, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const overdrawn = [ - // { - // to: 'USER2', - // from: 'USER1', - // value: 1, - // overdrawn: true - // }, - // { - // to: 'USER2', - // from: 'USER1', - // value: 1, - // overdrawn: true - // }, - // { - // to: 'USER2', - // from: 'USER3', - // value: 1, - // overdrawn: true - // }, - // ] - // const result = calculateScore(data, overdrawn, { listType: 'to', scoreType: 'inc', user: 'USER1' }) - // expect(result).toEqual(2) - // }); - - // it('User1 score should be 2 { enableOverDraw: false, enableDecrement: true }', async () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: true } - // const result = calculateScore(data, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) - // expect(result).toEqual(2) - // }); - - // }); + describe('userscore', () => { + - describe('scoreboard', () => { - it('Should calc scoreboard => to & inc => { enableOverDraw: false, enableDecrement: false }', async () => { + it('User1 score should be 14 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } - const listType = 'to'; - const scoreType = 'inc' - const scoreList = getScore({ listType, scoreType }) - expect(scoreList).toEqual([{ _id: 'USER1', score: 9 }, { _id: 'USER2', score: 5 }]) + const result = calculateScore(user1ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(14) }); + it('User1 score should be 11 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(user1ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(11) + }); - it('Should calc scoreboard => to & inc => { enableOverDraw: true, enableDecrement: false }', async () => { + it('User1 score should be 14 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: false } - const listType = 'to'; - const scoreType = 'inc' - const scoreList = getScore({ listType, scoreType }) - expect(scoreList).toEqual([{ _id: 'USER1', score: 4 }, { _id: 'USER2', score: 10 }]) + const result = calculateScore(user1ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(14) }); - it('Should calc scoreboard => to & inc => { enableOverDraw: false, enableDecrement: true }', async () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const listType = 'to'; - const scoreType = 'inc' - const scoreList = getScore({ listType, scoreType }) - expect(scoreList).toEqual([{ _id: 'USER1', score: 8 }, { _id: 'USER2', score: 8 }]) + it('User1 score should be 11 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(user1ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(11) }); - it('Should calc scoreboard => to & dec => { enableOverDraw: false, enableDecrement: false }', async () => { + + + + + + + + it('User2 score should be 9 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } - const listType = 'to'; - const scoreType = 'dec' + const result = calculateScore(user2ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER2' }) + expect(result).toEqual(9) + }); + + it('User2 score should be 5 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(user2ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER2' }) + expect(result).toEqual(5) + }); + + it('User2 score should be 12 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(user2ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER2' }) + expect(result).toEqual(12) + }); + - const scoreList = getScore({ listType, scoreType }) - expect(scoreList).toEqual([{ _id: 'USER1', score: 1 }, { _id: 'USER2', score: 2 }]) + it('User2 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(user2ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER2' }) + expect(result).toEqual(8) }); - it('Should calc scoreboard => to & dec => { enableOverDraw: true, enableDecrement: false }', async () => { + + + + + it('User3 score should be 13 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } - const listType = 'to'; - const scoreType = 'dec' - const scoreList = getScore({ listType, scoreType }) - console.log("scoreBoard", scoreBoard) - console.log("List", scoreList) - expect(scoreList).toEqual([{ _id: 'USER1', score: 1 }, { _id: 'USER2', score: 2 }]) + const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) + expect(result).toEqual(13) }); + it('User3 score should be 9 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) + expect(result).toEqual(9) + }); + it('User3 score should be 12 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) + expect(result).toEqual(12) + }); - // test listType from - // test scoreType dec - // it('Should calc scoreboard => from & inc => { enableOverDraw: false, enableDecrement: false }', async () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: false } - // const listType = 'from'; - // const scoreType = 'inc' - // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + it('User3 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) + expect(result).toEqual(8) + }); - // const scoreList = uniqueUsername - // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) - // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); - // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 5 }]) - // }); - // it('Should calc scoreboard => from & inc => { enableOverDraw: true, enableDecrement: false }', async () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const listType = 'from'; - // const scoreType = 'inc' - // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; - // const scoreList = uniqueUsername - // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) - // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); - // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 10 }]) - // }); + it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) + expect(result).toEqual(10) + }); + it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) + expect(result).toEqual(9) + }); - // it('Should calc scoreboard => from & inc => { enableOverDraw: false, enableDecrement: true }', async () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: true } - // const listType = 'from'; - // const scoreType = 'inc' - // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + it('User4 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) + expect(result).toEqual(8) + }); - // const scoreList = uniqueUsername - // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) - // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); - // console.log("scoreBoard", scoreBoard) - // console.log("scoreList", scoreList) - // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 10 }]) - // }); + it('User4 score should be 7 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) + expect(result).toEqual(7) + }); + - // it('Should calc scoreboard => from & dec => { enableOverDraw: false, enableDecrement: false }', async () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const listType = 'from'; - // const scoreType = 'inc' - // const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + }); - // const scoreList = uniqueUsername - // .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) - // .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); - // console.log("scoreBoard", scoreBoard) - // console.log("scoreList", scoreList) - // expect(scoreList).toEqual([{ _id: 'USER2', score: 9 }, { _id: 'USER1', score: 10 }]) - // }); + describe('scoreboard', () => { + // it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: false }', async () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: false } + // const listType = 'to'; + // const scoreType = 'inc' + // const scoreList = getScore({ listType, scoreType }) + // expect(scoreList).toEqual([ + // { _id: 'USER1', score: 14 }, + // { _id: 'USER2', score: 9 }, + // { _id: 'USER3', score: 13 }, + // { _id: 'USER4', score: 10 } + // ]); + // }); + + + // it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: true }', async () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: true } + // const listType = 'to'; + // const scoreType = 'inc' + // const scoreList = getScore({ listType, scoreType }) + // expect(scoreList).toEqual([ + // { _id: 'USER1', score: 11 }, + // { _id: 'USER2', score: 5 }, + // { _id: 'USER3', score: 9 }, + // { _id: 'USER4', score: 9 } + // ]); + // }); + + + // it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: false }', async () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const listType = 'to'; + // const scoreType = 'inc' + // const scoreList = getScore({ listType, scoreType }) + // expect(scoreList).toEqual([ + // { _id: 'USER1', score: 14 }, + // { _id: 'USER2', score: 12 }, + // { _id: 'USER3', score: 12 }, + // { _id: 'USER4', score: 8 } + // ]); + // }); + + + // it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: true }', async () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: true } + // const listType = 'to'; + // const scoreType = 'inc' + // const scoreList = getScore({ listType, scoreType }) + // expect(scoreList).toEqual([ + // { _id: 'USER1', score: 11 }, + // { _id: 'USER2', score: 8 }, + // { _id: 'USER3', score: 8 }, + // { _id: 'USER4', score: 7 } + // ]); + // }); }); diff --git a/test/data/calculatescore-data.ts b/test/data/calculatescore-data.ts index 0f3c8ae..082444e 100644 --- a/test/data/calculatescore-data.ts +++ b/test/data/calculatescore-data.ts @@ -1,133 +1,184 @@ +/** + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: false + * Res = 14 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: true + * Res = 11 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: false + * Res = 10 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: true + * Res = 7 + * -------------------------- + * listType: to, scoreType: dec, enableOverDraw: false, enableDecrement: false + * Res = 3 + * -------------------------- + */ + +// 18 ALL INC +// 14 overdrawn: false +// 3 decrement +// 4 overDrwan +// 11 = ALL ENABLED +export const user1ScoreData = [ + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER2', value: -1 }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: true }, +] + +/** + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: false + * Res = 9 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: true + * Res = 5 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: false + * Res = 9 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: true + * Res = 5 + * -------------------------- + * listType: to, scoreType: dec, enableOverDraw: false, enableDecrement: false + * Res = 4 + * -------------------------- + */ + +// 12 ALL INC +// 9 overdrawn: false +// 4 decrement +// 0 overDrwan +// 8 = ALL ENABLED +export const user2ScoreData = [ + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, +] + + +/** + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: false + * Res = 13 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: true + * Res = 9 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: false + * Res = 9 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: true + * Res = 9 + * -------------------------- + * listType: to, scoreType: dec, enableOverDraw: false, enableDecrement: false + * Res = 4 + * -------------------------- + */ + +// 16 ALL INC +// 13 overdrawn: false +// 4 decrement +// 4 overDrwan +// 8 = ALL ENABLED +export const user3ScoreData = [ + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER1', value: -1 }, + { to: 'USER3', from: 'USER2', value: -1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER4', value: -1 }, + { to: 'USER3', from: 'USER4', value: -1 }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, +] + +/** + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: false + * Res = 10 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: false, enableDecrement: true + * Res = 9 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: false + * Res = 8 + * -------------------------- + * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: true + * Res = 7 + * -------------------------- + * listType: to, scoreType: dec, enableOverDraw: false, enableDecrement: false + * Res = 1 + * -------------------------- + */ +// 10 ALL INC +// 10 overdrawn: false +// 1 decrement +// 2 overDrwan +// 7 = ALL ENABLED +export const user4ScoreData = [ + { to: 'USER4', from: 'USER2', value: 1 }, + { to: 'USER4', from: 'USER2', value: 1 }, + { to: 'USER4', from: 'USER3', value: 1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER1', value: -1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER2', value: 1, overdrawn: false }, +] + export const scoreBoard = [ - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER1', - from: 'USER2', - value: 1, - overdrawn: false - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: false - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: false - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: false - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: false - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: false - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: true - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: true - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: true - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: true - }, - { - to: 'USER2', - from: 'USER1', - value: 1, - overdrawn: true - }, - { - to: 'USER2', - from: 'USER1', - value: -1, - }, - { - to: 'USER2', - from: 'USER1', - value: -1, - }, - { - to: 'USER1', - from: 'USER2', - value: -1, - } + ...user1ScoreData, + ...user2ScoreData, + ...user3ScoreData, + ...user4ScoreData ] From e89acb3abe76ee1e754ad294e40a506fd1b95b77 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 29 Jan 2022 14:42:22 +0100 Subject: [PATCH 04/51] Update --- src/store/calc.ts | 50 +++++- test/chralp.test.ts | 283 ++++++++++++++++++++++++++----- test/data/calculatescore-data.ts | 9 +- 3 files changed, 299 insertions(+), 43 deletions(-) diff --git a/src/store/calc.ts b/src/store/calc.ts index 8076f8a..65d964e 100644 --- a/src/store/calc.ts +++ b/src/store/calc.ts @@ -59,7 +59,6 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos */ if (listType === 'to' && scoreType === 'inc') { - // Just count everything if (enableOverDraw && enableDecrement) return total + current.value; @@ -87,8 +86,57 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos return total; } + + + + + + + if (listType === 'from' && scoreType === 'inc') { + if (enableOverDraw && enableDecrement) { + if (current.value !== -1) return total + current.value; + return total; + } + + if (enableOverDraw) { + if (current.value !== -1) return total + current.value; + return total; + } + + if (enableDecrement) { + if (current.value === 1 && !current.overdrawn) return total + current.value; + return total; + } + + // Ensure we only return positive value and that current.overdrawn is false + if (current.value === 1 && !current.overdrawn) return total + current.value; + return total; + + } + + + if (listType === 'from' && scoreType === 'dec') { + if (current.value == -1) return total + 1; + return total; + if (enableOverDraw && enableDecrement) { + if (current.value !== -1) return total + current.value; + return total; + } + + if (enableOverDraw) { + if (current.value == -1) return total + current.value; + return total; + } + + if (enableDecrement) { + if (current.value == -1 && !current.overdrawn) return total + 1; + return total; + } + + if (current.value === -1 && !current.overdrawn) return total + 1; + return total; } diff --git a/test/chralp.test.ts b/test/chralp.test.ts index b6c5a1c..34c5a9f 100644 --- a/test/chralp.test.ts +++ b/test/chralp.test.ts @@ -24,60 +24,183 @@ describe('calculateScore', () => { describe('userscore', () => { - - it('User1 score should be 14 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { + /* + [ + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER2', value: -1 }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: true } + ] + */ + + + /* + [ + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER1', value: -1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER1', value: -1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER1', value: 1, overdrawn: false } + ] + */ + + + it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(user1ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) expect(result).toEqual(14) }); - it('User1 score should be 11 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: true } const result = calculateScore(user1ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) expect(result).toEqual(11) }); - it('User1 score should be 14 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: false } const result = calculateScore(user1ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER1' }) expect(result).toEqual(14) }); - - it('User1 score should be 11 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } const result = calculateScore(user1ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER1' }) expect(result).toEqual(11) }); + it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(3) + }); + + it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(3) + }); + + it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(3) + }); + + it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(3) + }); + + + it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(14) + }); + + it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(14) + }); + + it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(18) + }); + it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) + expect(result).toEqual(18) + }); + it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(6) + }); + it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(6) + }); + it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(6) + }); + it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) + expect(result).toEqual(6) + }); - it('User2 score should be 9 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { + + it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(user2ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER2' }) expect(result).toEqual(9) }); - it('User2 score should be 5 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: true } const result = calculateScore(user2ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER2' }) expect(result).toEqual(5) }); - it('User2 score should be 12 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: false } const result = calculateScore(user2ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER2' }) expect(result).toEqual(12) }); - it('User2 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } const result = calculateScore(user2ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER2' }) expect(result).toEqual(8) @@ -87,59 +210,139 @@ describe('calculateScore', () => { + /* + [ + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER2', value: -1 }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: -1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER2', value: 1 }, + { to: 'USER4', from: 'USER2', value: 1 }, + { to: 'USER4', from: 'USER2', value: 1, overdrawn: false } + ] + + + [ + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false } + ] + */ + + + + - it('User3 score should be 13 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { + it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) - expect(result).toEqual(13) + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER2' }) + expect(result).toEqual(9) }); - it('User3 score should be 9 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: false, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) - expect(result).toEqual(9) + const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER2' }) + expect(result).toEqual(5) }); - it('User3 score should be 12 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: true, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) + const result = calculateScore(scoreBoard, scoreBoard, { listType: 'from', scoreType: 'inc', user: 'USER2' }) expect(result).toEqual(12) }); - it('User3 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: true, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) + const result = calculateScore(scoreBoard, scoreBoard, { listType: 'from', scoreType: 'inc', user: 'USER2' }) + + const gg = scoreBoard.filter(data => { + if(data['to'] === "USER2") return data + }) + console.log(gg) + expect(result).toEqual(8) }); - it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) - expect(result).toEqual(10) - }); - it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) - expect(result).toEqual(9) - }); - it('User4 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) - expect(result).toEqual(8) - }); + // it('User3 score should be 13 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: false } + // const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) + // expect(result).toEqual(13) + // }); + // it('User3 score should be 9 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: true } + // const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) + // expect(result).toEqual(9) + // }); - it('User4 score should be 7 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) - expect(result).toEqual(7) - }); + // it('User3 score should be 12 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) + // expect(result).toEqual(12) + // }); + + + // it('User3 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: true } + // const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) + // expect(result).toEqual(8) + // }); + + + + + // it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: false } + // const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) + // expect(result).toEqual(10) + // }); + + // it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { + // config.default.slack = { enableOverDraw: false, enableDecrement: true } + // const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) + // expect(result).toEqual(9) + // }); + + // it('User4 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) + // expect(result).toEqual(8) + // }); + + + // it('User4 score should be 7 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: true } + // const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) + // expect(result).toEqual(7) + // }); diff --git a/test/data/calculatescore-data.ts b/test/data/calculatescore-data.ts index 082444e..a057f97 100644 --- a/test/data/calculatescore-data.ts +++ b/test/data/calculatescore-data.ts @@ -14,8 +14,11 @@ * listType: to, scoreType: inc, enableOverDraw: true, enableDecrement: true * Res = 7 * -------------------------- - * listType: to, scoreType: dec, enableOverDraw: false, enableDecrement: false - * Res = 3 + * listType: from, scoreType: inc, enableOverDraw: false, enableDecrement: false + * Res = 14 + * -------------------------- + * listType: from, scoreType: inc, enableOverDraw: false, enableDecrement: true + * Res = 14 * -------------------------- */ @@ -176,6 +179,8 @@ export const user4ScoreData = [ { to: 'USER4', from: 'USER2', value: 1, overdrawn: false }, ] + + export const scoreBoard = [ ...user1ScoreData, ...user2ScoreData, From 4de5147928459f83864de472c6fbe6e0f02fcd6a Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 29 Jan 2022 19:59:24 +0100 Subject: [PATCH 05/51] update of test for calc.ts --- src/store/calc.ts | 14 +- test/chralp.test.ts | 971 +++++++++++++++++++++++++++++--------------- 2 files changed, 657 insertions(+), 328 deletions(-) diff --git a/src/store/calc.ts b/src/store/calc.ts index 65d964e..c456517 100644 --- a/src/store/calc.ts +++ b/src/store/calc.ts @@ -20,7 +20,6 @@ interface CalculateScoreArgs { export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePost[], args?: CalculateScoreArgs): number => { const { listType, scoreType, user } = args; const valueSwitch = (scoreType === 'dec') ? 1 : 0; - console.log(listType, scoreType, user) const { enableOverDraw, enableDecrement} = config.slack; @@ -43,13 +42,13 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos return total + current.value; }, 0); - - if(user === 'USER3') console.log("_scoreOverdrawn", _scoreOverdrawn) - const _score = data.reduce((total: number, current: DatabasePost): number => { // We only want to handle the correct user data depending on listTypeon current[listType] === USER - if(!(current[listType] === user)) return total; + if(!(current[listType] === user)) { + //console.log("VAD I HELVETE") + return total; + } /** * We want to calculate the score differently @@ -147,11 +146,6 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos return total; }, 0); - - - console.log("---------------\n", _score, _scoreOverdrawn) - - return _score - _scoreOverdrawn; }; diff --git a/test/chralp.test.ts b/test/chralp.test.ts index 34c5a9f..03f7d4a 100644 --- a/test/chralp.test.ts +++ b/test/chralp.test.ts @@ -23,32 +23,35 @@ describe('calculateScore', () => { describe('userscore', () => { - - /* - [ - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER3', value: -1 }, - { to: 'USER1', from: 'USER3', value: -1 }, - { to: 'USER1', from: 'USER2', value: -1 }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1 }, - { to: 'USER1', from: 'USER4', value: 1 }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: true } - ] - */ + describe('Should calculate userscore for USER1', () => { + const user = 'USER1'; + + + /* + [ + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER2', value: -1 }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: true } + ] + */ /* @@ -79,332 +82,664 @@ describe('calculateScore', () => { { to: 'USER4', from: 'USER1', value: 1, overdrawn: false } ] */ - - - it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(user1ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(14) - }); - - it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(user1ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(11) - }); - - it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(user1ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(14) - }); - - it('Should calculate userscore for USER1 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(user1ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(11) - }); - - it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: false, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(3) - }); - - it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: false, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(3) - }); - - it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: true, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(3) - }); - - it('Should calculate userscore for USER1 => to & dec => { enableOverDraw: true, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(scoreBoard, [], { listType: 'to', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(3) + describe('with args { listType: to, scoreType: inc }', () => { + const listType = 'to'; + const scoreType = 'inc'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(user1ScoreData, [], { listType, scoreType, user }) + expect(result).toEqual(14) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(user1ScoreData, [], { listType, scoreType, user }) + expect(result).toEqual(11) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(user1ScoreData, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(14) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(user1ScoreData, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(11) + }); + }); + + + + + describe('with args { listType: from, scoreType: inc }', () => { + const listType = 'from'; + const scoreType = 'inc'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(14) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(14) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(18) + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(18) + }); + + }); + describe('with args { listType: to, scoreType: dec }', () => { + const listType = 'to'; + const scoreType = 'dec'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(3) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(3) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(3) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(3) + }); + + + }); + describe('with args { listType: from, scoreType: dec }', () => { + const listType = 'from'; + const scoreType = 'dec'; + it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(6) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(6) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(6) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(6) + }); + }); }); + describe('Should calculate userscore for USER2', () => { - it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: false, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(14) - }); - - it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: false, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(14) - }); - - it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: true, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(18) - }); - - - it('Should calculate userscore for USER1 => from & inc => { enableOverDraw: true, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER1' }) - expect(result).toEqual(18) - }); - - - it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: false, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(6) - }); - - it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: false, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(6) - }); - - it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: true, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(6) - }); - - it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: true, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'dec', user: 'USER1' }) - expect(result).toEqual(6) + /* + [ + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER2', value: 1 }, + { to: 'USER1', from: 'USER2', value: -1 }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: -1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER2', value: 1 }, + { to: 'USER4', from: 'USER2', value: 1 }, + { to: 'USER4', from: 'USER2', value: 1, overdrawn: false } + ] +[ + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: 1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: -1 }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false } +] +*/ + const user = 'USER2'; + describe('with args { listType: to, scoreType: inc }', () => { + const listType = 'to'; + const scoreType = 'inc'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(9) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(5) + }); + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(12) + }); + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(8) + }); + }); + + describe('with args { listType: from, scoreType: inc }', () => { + const listType = 'from'; + const scoreType = 'inc'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(14) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(14) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(14) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(14) + }); + }); + + describe('with args { listType: to, scoreType: dec }', () => { + const listType = 'to'; + const scoreType = 'dec'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(user2ScoreData, [],{ listType, scoreType, user }) + expect(result).toEqual(4) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(user2ScoreData, [],{ listType, scoreType, user }) + expect(result).toEqual(4) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(user2ScoreData, scoreBoard,{ listType, scoreType, user }) + expect(result).toEqual(4) + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(user2ScoreData, scoreBoard,{ listType, scoreType, user }) + expect(result).toEqual(4) + }); + }); + + describe('with args { listType: from, scoreType: dec }', () => { + const listType = 'from'; + const scoreType = 'dec'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [],{ listType, scoreType, user }) + expect(result).toEqual(2) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(2) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard,{ listType, scoreType, user }) + expect(result).toEqual(2) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(2) + }); + }); }); - it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(user2ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER2' }) - expect(result).toEqual(9) - }); - - it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(user2ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER2' }) - expect(result).toEqual(5) - }); - it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(user2ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER2' }) - expect(result).toEqual(12) + describe('Should calculate userscore for USER3', () => { + const user = 'USER3'; + /* + + [ + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER1', value: -1 }, + { to: 'USER3', from: 'USER2', value: -1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER1', value: 1 }, + { to: 'USER3', from: 'USER2', value: 1 }, + { to: 'USER3', from: 'USER4', value: -1 }, + { to: 'USER3', from: 'USER4', value: -1 }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER2', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false } + ] + + + [ + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER3', value: -1 }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: true }, + { to: 'USER2', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER3', value: 1 }, + { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER3', value: 1, overdrawn: false } + ] + */ + describe('with args { listType: to, scoreType: inc }', () => { + const listType = 'to'; + const scoreType = 'inc'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(13) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(9); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(12); + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(8); + }); + }); + + describe('with args { listType: from, scoreType: inc }', () => { + + const listType = 'from'; + const scoreType = 'inc'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(7) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(7); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(11); + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(11); + }); + }); + + + describe('wtih args { listType: to, scoreType: dec }', () => { + + const listType = 'to'; + const scoreType = 'dec'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(4) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(4); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(4); + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(4); + }); + }); + + describe('with args { listType: from, scoreType: dec }', () => { + + const listType = 'from'; + const scoreType = 'dec'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(2) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(2); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(2); + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(2); + }); + }); }); - it('Should calculate userscore for USER2 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(user2ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER2' }) - expect(result).toEqual(8) - }); - - - - - + describe('Should calculate userscore for USER4', () => { /* - [ - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER2', value: -1 }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: -1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1, overdrawn: false }, + [ { to: 'USER4', from: 'USER2', value: 1 }, { to: 'USER4', from: 'USER2', value: 1 }, + { to: 'USER4', from: 'USER3', value: 1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER1', value: -1 }, + { to: 'USER4', from: 'USER1', value: 1 }, + { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, + { to: 'USER4', from: 'USER1', value: 1, overdrawn: false }, { to: 'USER4', from: 'USER2', value: 1, overdrawn: false } ] - - [ - { to: 'USER2', from: 'USER1', value: 1 }, - { to: 'USER2', from: 'USER1', value: 1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER3', value: 1, overdrawn: false }, + [ + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1 }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER1', from: 'USER4', value: 1, overdrawn: true }, { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER4', value: 1, overdrawn: false } + { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: -1 }, + { to: 'USER3', from: 'USER4', value: -1 }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: true }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, + { to: 'USER3', from: 'USER4', value: 1, overdrawn: false } ] - */ - - - + */ + const user = 'USER4'; + + describe('with args { listType: to, scoreType: inc }', () => { + const listType = 'to'; + const scoreType = 'inc'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(10) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(9) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(8) + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(7) + }); + }); + + describe('with args { listType: from, scoreType: inc }', () => { + const listType = 'from'; + const scoreType = 'inc'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(11) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(11) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(13) + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(13) + }); + + }); + describe('with args { listType: to, scoreType: dec }', () => { + const listType = 'to'; + const scoreType = 'dec'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(1) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(1) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(1) + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(1) + }); + }); + + describe('with args { listType: from, scoreType: dec }', () => { + + const listType = 'from'; + const scoreType = 'dec'; + + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(2) + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) + expect(result).toEqual(2) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(2) + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) + expect(result).toEqual(2) + }); + }); + }); + }); + describe('scoreboard', () => { - it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: false, enableDecrement: false }', () => { + it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: false }', async () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER2' }) - expect(result).toEqual(9) + const listType = 'to'; + const scoreType = 'inc' + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 14 }, + { _id: 'USER2', score: 9 }, + { _id: 'USER3', score: 13 }, + { _id: 'USER4', score: 10 } + ]); }); - it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: false, enableDecrement: true }', () => { + + it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: true }', async () => { config.default.slack = { enableOverDraw: false, enableDecrement: true } - const result = calculateScore(scoreBoard, [], { listType: 'from', scoreType: 'inc', user: 'USER2' }) - expect(result).toEqual(5) + const listType = 'to'; + const scoreType = 'inc' + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 11 }, + { _id: 'USER2', score: 5 }, + { _id: 'USER3', score: 9 }, + { _id: 'USER4', score: 9 } + ]); }); - it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: true, enableDecrement: false }', () => { + + it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: false }', async () => { config.default.slack = { enableOverDraw: true, enableDecrement: false } - const result = calculateScore(scoreBoard, scoreBoard, { listType: 'from', scoreType: 'inc', user: 'USER2' }) - expect(result).toEqual(12) + const listType = 'to'; + const scoreType = 'inc' + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 14 }, + { _id: 'USER2', score: 12 }, + { _id: 'USER3', score: 12 }, + { _id: 'USER4', score: 8 } + ]); }); - it('Should calculate userscore for USER2 => from & inc => { enableOverDraw: true, enableDecrement: true }', () => { + it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: true }', async () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } - const result = calculateScore(scoreBoard, scoreBoard, { listType: 'from', scoreType: 'inc', user: 'USER2' }) - - const gg = scoreBoard.filter(data => { - if(data['to'] === "USER2") return data - }) - console.log(gg) - - expect(result).toEqual(8) + const listType = 'to'; + const scoreType = 'inc' + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 11 }, + { _id: 'USER2', score: 8 }, + { _id: 'USER3', score: 8 }, + { _id: 'USER4', score: 7 } + ]); }); - - - - - - // it('User3 score should be 13 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: false } - // const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) - // expect(result).toEqual(13) - // }); - - // it('User3 score should be 9 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: true } - // const result = calculateScore(user3ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER3' }) - // expect(result).toEqual(9) - // }); - - // it('User3 score should be 12 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) - // expect(result).toEqual(12) - // }); - - - // it('User3 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: true } - // const result = calculateScore(user3ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER3' }) - // expect(result).toEqual(8) - // }); - - - - - // it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: false } - // const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) - // expect(result).toEqual(10) - // }); - - // it('User4 score should be 10 => to & inc => { enableOverDraw: false, enableDecrement: true }', () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: true } - // const result = calculateScore(user4ScoreData, [], { listType: 'to', scoreType: 'inc', user: 'USER4' }) - // expect(result).toEqual(9) - // }); - - // it('User4 score should be 8 => to & inc => { enableOverDraw: true, enableDecrement: false }', () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) - // expect(result).toEqual(8) - // }); - - - // it('User4 score should be 7 => to & inc => { enableOverDraw: true, enableDecrement: true }', () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: true } - // const result = calculateScore(user4ScoreData, scoreBoard, { listType: 'to', scoreType: 'inc', user: 'USER4' }) - // expect(result).toEqual(7) - // }); - - - - }); - - describe('scoreboard', () => { - - // it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: false }', async () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: false } - // const listType = 'to'; - // const scoreType = 'inc' - // const scoreList = getScore({ listType, scoreType }) - // expect(scoreList).toEqual([ - // { _id: 'USER1', score: 14 }, - // { _id: 'USER2', score: 9 }, - // { _id: 'USER3', score: 13 }, - // { _id: 'USER4', score: 10 } - // ]); - // }); - - - // it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: true }', async () => { - // config.default.slack = { enableOverDraw: false, enableDecrement: true } - // const listType = 'to'; - // const scoreType = 'inc' - // const scoreList = getScore({ listType, scoreType }) - // expect(scoreList).toEqual([ - // { _id: 'USER1', score: 11 }, - // { _id: 'USER2', score: 5 }, - // { _id: 'USER3', score: 9 }, - // { _id: 'USER4', score: 9 } - // ]); - // }); - - - // it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: false }', async () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const listType = 'to'; - // const scoreType = 'inc' - // const scoreList = getScore({ listType, scoreType }) - // expect(scoreList).toEqual([ - // { _id: 'USER1', score: 14 }, - // { _id: 'USER2', score: 12 }, - // { _id: 'USER3', score: 12 }, - // { _id: 'USER4', score: 8 } - // ]); - // }); - - - // it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: true }', async () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: true } - // const listType = 'to'; - // const scoreType = 'inc' - // const scoreList = getScore({ listType, scoreType }) - // expect(scoreList).toEqual([ - // { _id: 'USER1', score: 11 }, - // { _id: 'USER2', score: 8 }, - // { _id: 'USER3', score: 8 }, - // { _id: 'USER4', score: 7 } - // ]); - // }); - }); }); From 2b141d51cc34c26af4cfe70ba88986764c6d3fe2 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 29 Jan 2022 20:13:50 +0100 Subject: [PATCH 06/51] update of test --- test/chralp.test.ts | 93 +++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/test/chralp.test.ts b/test/chralp.test.ts index 03f7d4a..d2a247d 100644 --- a/test/chralp.test.ts +++ b/test/chralp.test.ts @@ -685,60 +685,63 @@ describe('calculateScore', () => { describe('scoreboard', () => { - it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: false }', async () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } + describe('with args { listType: to, scoreType: from }', () => { const listType = 'to'; - const scoreType = 'inc' - const scoreList = getScore({ listType, scoreType }) - expect(scoreList).toEqual([ - { _id: 'USER1', score: 14 }, - { _id: 'USER2', score: 9 }, - { _id: 'USER3', score: 13 }, - { _id: 'USER4', score: 10 } - ]); - }); + const scoreType = 'inc'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 14 }, + { _id: 'USER2', score: 9 }, + { _id: 'USER3', score: 13 }, + { _id: 'USER4', score: 10 } + ]); + }); - it('Should calculate scoreboard => to & inc => { enableOverDraw: false, enableDecrement: true }', async () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } - const listType = 'to'; - const scoreType = 'inc' - const scoreList = getScore({ listType, scoreType }) + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) expect(scoreList).toEqual([ - { _id: 'USER1', score: 11 }, - { _id: 'USER2', score: 5 }, - { _id: 'USER3', score: 9 }, - { _id: 'USER4', score: 9 } - ]); - }); + { _id: 'USER1', score: 11 }, + { _id: 'USER2', score: 5 }, + { _id: 'USER3', score: 9 }, + { _id: 'USER4', score: 9 } + ]); + }); - it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: false }', async () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const listType = 'to'; - const scoreType = 'inc' - const scoreList = getScore({ listType, scoreType }) - expect(scoreList).toEqual([ - { _id: 'USER1', score: 14 }, - { _id: 'USER2', score: 12 }, - { _id: 'USER3', score: 12 }, - { _id: 'USER4', score: 8 } - ]); - }); + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 14 }, + { _id: 'USER2', score: 12 }, + { _id: 'USER3', score: 12 }, + { _id: 'USER4', score: 8 } + ]); + }); + + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 11 }, + { _id: 'USER2', score: 8 }, + { _id: 'USER3', score: 8 }, + { _id: 'USER4', score: 7 } + ]); + }); - it('Should calculate scoreboard => to & inc => { enableOverDraw: true, enableDecrement: true }', async () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } - const listType = 'to'; - const scoreType = 'inc' - const scoreList = getScore({ listType, scoreType }) - expect(scoreList).toEqual([ - { _id: 'USER1', score: 11 }, - { _id: 'USER2', score: 8 }, - { _id: 'USER3', score: 8 }, - { _id: 'USER4', score: 7 } - ]); }); + // describe('with args { listType: from, scoreType: dec }', () => {}); + // describe('with args { listType: from, scoreType: dec }', () => {}); + // describe('with args { listType: from, scoreType: dec }', () => {}); + + }); From f32aa5dbb8b3bfbee7d4c0e783dc378c2f293684 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 30 Jan 2022 15:07:27 +0100 Subject: [PATCH 07/51] update --- src/store/calc.ts | 108 +++---------- test/chralp.test.ts | 367 ++++++++++++++++++-------------------------- 2 files changed, 175 insertions(+), 300 deletions(-) diff --git a/src/store/calc.ts b/src/store/calc.ts index c456517..7889512 100644 --- a/src/store/calc.ts +++ b/src/store/calc.ts @@ -1,5 +1,5 @@ import config from '../config'; -import { listTypeSwitch, sort } from '../lib/utils'; +import { listTypeSwitch } from '../lib/utils'; import { DatabasePost } from '../database/drivers/Driver'; interface CalculateScoreArgs { @@ -15,26 +15,16 @@ interface CalculateScoreArgs { * makes everything harder. * Trying to add add dumb calculations in this file */ - - export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePost[], args?: CalculateScoreArgs): number => { const { listType, scoreType, user } = args; - const valueSwitch = (scoreType === 'dec') ? 1 : 0; - - const { enableOverDraw, enableDecrement} = config.slack; + const { enableOverDraw, enableDecrement } = config.slack; const _dataOverDrawn = overDrawnData.filter((entry: DatabasePost) => { - if (enableOverDraw) { - /** - * Just ensure that we filter out correct user data if user is present - */ - const list = listType === 'to' ? listTypeSwitch(listType) : listType; - if (listType !== 'from') { - if (user && entry[list] === user && !!entry.overdrawn) { - return entry; - } - } + // Just ensure that we filter out correct user data if user is present + const list = listType === 'to' ? listTypeSwitch(listType) : listType; + if (listType !== 'from' && user && enableOverDraw && entry[list] === user && !!entry.overdrawn) { + return entry; } }); @@ -44,11 +34,8 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos const _score = data.reduce((total: number, current: DatabasePost): number => { - // We only want to handle the correct user data depending on listTypeon current[listType] === USER - if(!(current[listType] === user)) { - //console.log("VAD I HELVETE") - return total; - } + // We only want to handle the correct user data depending on current[listType] === USER + if (!(current[listType] === user)) return total; /** * We want to calculate the score differently @@ -62,97 +49,52 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos if (enableOverDraw && enableDecrement) return total + current.value; - if (enableOverDraw) { if (current.value !== -1) return total + current.value; return total; - } + }; if (enableDecrement) { if (!current.overdrawn) return total + current.value; return total; - } + }; // Ensure we only return positive value and that current.overdrawn is false if (current.value === 1 && !current.overdrawn) return total + current.value; return total; - } - - // We only want to return a list of received dec - if (listType === 'to' && scoreType === 'dec') { - if (current.value === -1) return total + 1; - // Add support for overdrawn? - return total; - } - - - - - - + }; + /** + * scoreBoard: listType === 'from' && scoreType === 'inc' + * This scoreBoard should not count -1 values. Only return postive values + */ if (listType === 'from' && scoreType === 'inc') { - if (enableOverDraw && enableDecrement) { - if (current.value !== -1) return total + current.value; - return total; - } - - if (enableOverDraw) { + if (enableOverDraw && enableDecrement || enableOverDraw) { if (current.value !== -1) return total + current.value; return total; } - if (enableDecrement) { - if (current.value === 1 && !current.overdrawn) return total + current.value; - return total; - } - - // Ensure we only return positive value and that current.overdrawn is false if (current.value === 1 && !current.overdrawn) return total + current.value; return total; + }; - } - - - if (listType === 'from' && scoreType === 'dec') { + /** + * Only match -1 values and return 1 instead + */ + if (listType === 'from' || listType === 'to' && scoreType === 'dec') { if (current.value == -1) return total + 1; return total; - if (enableOverDraw && enableDecrement) { - if (current.value !== -1) return total + current.value; - return total; - } - - if (enableOverDraw) { - if (current.value == -1) return total + current.value; - return total; - } - - if (enableDecrement) { - if (current.value == -1 && !current.overdrawn) return total + 1; - return total; - } - - if (current.value === -1 && !current.overdrawn) return total + 1; - return total; - - } - - - - - + }; return total; }, 0); + return _score - _scoreOverdrawn; }; - - - export const levelScoreList = (scoreList: any) => { const data = scoreList.map((x: any) => { const { scoreRotation } = config.level; @@ -167,6 +109,4 @@ export const levelScoreList = (scoreList: any) => { } }); return data; - - -} +}; diff --git a/test/chralp.test.ts b/test/chralp.test.ts index d2a247d..268c0e7 100644 --- a/test/chralp.test.ts +++ b/test/chralp.test.ts @@ -1,87 +1,23 @@ import { calculateScore } from '../src/store/calc' import * as config from '../src/config'; -import { scoreBoard, user1ScoreData, user2ScoreData, user3ScoreData, user4ScoreData } from './data/calculatescore-data'; +import { scoreBoard, user1ScoreData, user2ScoreData } from './data/calculatescore-data'; +const getScore = ({ listType, scoreType, user }: any) => { + const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; -interface args { - listType: string; - scoreType: string; - user?: string; -} -const getScore = ({ listType, scoreType, user }:args) => { - const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; + const overDrawnData = scoreType === 'dec' ? [] : scoreBoard; const scoreList = uniqueUsername - .map((user) => ({ _id: user, score: calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) })) + .map((user) => ({ _id: user, score: calculateScore(scoreBoard, overDrawnData, { listType, scoreType, user }) })) .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); return scoreList; -} - +}; describe('calculateScore', () => { - describe('userscore', () => { - describe('Should calculate userscore for USER1', () => { const user = 'USER1'; - - - /* - [ - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER3', value: -1 }, - { to: 'USER1', from: 'USER3', value: -1 }, - { to: 'USER1', from: 'USER2', value: -1 }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1 }, - { to: 'USER1', from: 'USER4', value: 1 }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: true } - ] - */ - - - /* - [ - { to: 'USER2', from: 'USER1', value: 1 }, - { to: 'USER2', from: 'USER1', value: 1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER1', value: -1 }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER4', from: 'USER1', value: 1 }, - { to: 'USER4', from: 'USER1', value: 1 }, - { to: 'USER4', from: 'USER1', value: -1 }, - { to: 'USER4', from: 'USER1', value: 1 }, - { to: 'USER4', from: 'USER1', value: 1, overdrawn: false } - ] - */ describe('with args { listType: to, scoreType: inc }', () => { const listType = 'to'; const scoreType = 'inc'; @@ -110,13 +46,9 @@ describe('calculateScore', () => { }); }); - - - describe('with args { listType: from, scoreType: inc }', () => { const listType = 'from'; const scoreType = 'inc'; - it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) @@ -135,18 +67,16 @@ describe('calculateScore', () => { expect(result).toEqual(18) }); - it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) expect(result).toEqual(18) }); - }); + describe('with args { listType: to, scoreType: dec }', () => { const listType = 'to'; const scoreType = 'dec'; - it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) @@ -170,13 +100,12 @@ describe('calculateScore', () => { const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) expect(result).toEqual(3) }); - - }); + describe('with args { listType: from, scoreType: dec }', () => { const listType = 'from'; const scoreType = 'dec'; - it('Should calculate userscore for USER1 => from & dec => { enableOverDraw: false, enableDecrement: false }', () => { + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) expect(result).toEqual(6) @@ -203,45 +132,6 @@ describe('calculateScore', () => { }); describe('Should calculate userscore for USER2', () => { - - /* - [ - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER2', value: 1 }, - { to: 'USER1', from: 'USER2', value: -1 }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: -1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER4', from: 'USER2', value: 1 }, - { to: 'USER4', from: 'USER2', value: 1 }, - { to: 'USER4', from: 'USER2', value: 1, overdrawn: false } - ] -[ - { to: 'USER2', from: 'USER1', value: 1 }, - { to: 'USER2', from: 'USER1', value: 1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: -1 }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER4', value: 1, overdrawn: false } -] -*/ const user = 'USER2'; describe('with args { listType: to, scoreType: inc }', () => { const listType = 'to'; @@ -357,52 +247,8 @@ describe('calculateScore', () => { }); }); - - describe('Should calculate userscore for USER3', () => { const user = 'USER3'; - /* - - [ - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER1', value: -1 }, - { to: 'USER3', from: 'USER2', value: -1 }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER1', value: 1 }, - { to: 'USER3', from: 'USER2', value: 1 }, - { to: 'USER3', from: 'USER4', value: -1 }, - { to: 'USER3', from: 'USER4', value: -1 }, - { to: 'USER3', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER3', from: 'USER1', value: 1, overdrawn: true }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: true }, - { to: 'USER3', from: 'USER2', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: false } - ] - - - [ - { to: 'USER1', from: 'USER3', value: -1 }, - { to: 'USER1', from: 'USER3', value: -1 }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER1', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER3', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER4', from: 'USER3', value: 1 }, - { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER4', from: 'USER3', value: 1, overdrawn: false } - ] - */ describe('with args { listType: to, scoreType: inc }', () => { const listType = 'to'; const scoreType = 'inc'; @@ -424,7 +270,6 @@ describe('calculateScore', () => { expect(result).toEqual(12); }); - it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) @@ -433,10 +278,8 @@ describe('calculateScore', () => { }); describe('with args { listType: from, scoreType: inc }', () => { - const listType = 'from'; const scoreType = 'inc'; - it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) @@ -463,12 +306,9 @@ describe('calculateScore', () => { }); }); - describe('wtih args { listType: to, scoreType: dec }', () => { - const listType = 'to'; const scoreType = 'dec'; - it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) @@ -518,7 +358,6 @@ describe('calculateScore', () => { expect(result).toEqual(2); }); - it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) @@ -527,43 +366,8 @@ describe('calculateScore', () => { }); }); - describe('Should calculate userscore for USER4', () => { - /* - [ - { to: 'USER4', from: 'USER2', value: 1 }, - { to: 'USER4', from: 'USER2', value: 1 }, - { to: 'USER4', from: 'USER3', value: 1 }, - { to: 'USER4', from: 'USER1', value: 1 }, - { to: 'USER4', from: 'USER1', value: 1 }, - { to: 'USER4', from: 'USER1', value: -1 }, - { to: 'USER4', from: 'USER1', value: 1 }, - { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER4', from: 'USER3', value: 1, overdrawn: false }, - { to: 'USER4', from: 'USER1', value: 1, overdrawn: false }, - { to: 'USER4', from: 'USER2', value: 1, overdrawn: false } - ] - - [ - { to: 'USER1', from: 'USER4', value: 1 }, - { to: 'USER1', from: 'USER4', value: 1 }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER1', from: 'USER4', value: 1, overdrawn: true }, - { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER2', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER4', value: -1 }, - { to: 'USER3', from: 'USER4', value: -1 }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: true }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: false }, - { to: 'USER3', from: 'USER4', value: 1, overdrawn: false } - ] - */ const user = 'USER4'; - describe('with args { listType: to, scoreType: inc }', () => { const listType = 'to'; const scoreType = 'inc'; @@ -643,7 +447,6 @@ describe('calculateScore', () => { expect(result).toEqual(1) }); - it('with ENVS: { enableOverDraw: true, enableDecrement: true }', () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } const result = calculateScore(scoreBoard, [], { listType, scoreType, user }) @@ -652,10 +455,8 @@ describe('calculateScore', () => { }); describe('with args { listType: from, scoreType: dec }', () => { - const listType = 'from'; const scoreType = 'dec'; - it('with ENVS: { enableOverDraw: false, enableDecrement: false }', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const result = calculateScore(scoreBoard, scoreBoard, { listType, scoreType, user }) @@ -685,7 +486,7 @@ describe('calculateScore', () => { describe('scoreboard', () => { - describe('with args { listType: to, scoreType: from }', () => { + describe('with args { listType: to, scoreType: inc }', () => { const listType = 'to'; const scoreType = 'inc'; it('with ENVS: { enableOverDraw: false, enableDecrement: false }', async () => { @@ -699,7 +500,6 @@ describe('calculateScore', () => { ]); }); - it('with ENVS: { enableOverDraw: false, enableDecrement: true }', async () => { config.default.slack = { enableOverDraw: false, enableDecrement: true } const scoreList = getScore({ listType, scoreType }) @@ -711,7 +511,6 @@ describe('calculateScore', () => { ]); }); - it('with ENVS: { enableOverDraw: true, enableDecrement: false }', async () => { config.default.slack = { enableOverDraw: true, enableDecrement: false } const scoreList = getScore({ listType, scoreType }) @@ -723,7 +522,6 @@ describe('calculateScore', () => { ]); }); - it('with ENVS: { enableOverDraw: true, enableDecrement: true }', async () => { config.default.slack = { enableOverDraw: true, enableDecrement: true } const scoreList = getScore({ listType, scoreType }) @@ -734,15 +532,152 @@ describe('calculateScore', () => { { _id: 'USER4', score: 7 } ]); }); + }); + + describe('with args { listType: from, scoreType: inc }', () => { + const listType = 'from'; + const scoreType = 'inc'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 14 }, + { _id: 'USER3', score: 7 }, + { _id: 'USER4', score: 11 }, + { _id: 'USER1', score: 14 }, + ]); + }); + + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 14 }, + { _id: 'USER3', score: 7 }, + { _id: 'USER4', score: 11 }, + { _id: 'USER1', score: 14 }, + ]); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 14 }, + { _id: 'USER3', score: 11 }, + { _id: 'USER4', score: 13 }, + { _id: 'USER1', score: 18 }, + ]); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 14 }, + { _id: 'USER3', score: 11 }, + { _id: 'USER4', score: 13 }, + { _id: 'USER1', score: 18 }, + ]); + }); + }); + + describe('with args { listType: to, scoreType: dec }', () => { + + const listType = 'to'; + const scoreType = 'dec'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 3 }, + { _id: 'USER2', score: 4 }, + { _id: 'USER3', score: 4 }, + { _id: 'USER4', score: 1 }, + ]); + }); + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 3 }, + { _id: 'USER2', score: 4 }, + { _id: 'USER3', score: 4 }, + { _id: 'USER4', score: 1 }, + ]); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 3 }, + { _id: 'USER2', score: 4 }, + { _id: 'USER3', score: 4 }, + { _id: 'USER4', score: 1 }, + ]); + }); + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER1', score: 3 }, + { _id: 'USER2', score: 4 }, + { _id: 'USER3', score: 4 }, + { _id: 'USER4', score: 1 }, + ]); + }); }); - // describe('with args { listType: from, scoreType: dec }', () => {}); - // describe('with args { listType: from, scoreType: dec }', () => {}); - // describe('with args { listType: from, scoreType: dec }', () => {}); + describe('with args { listType: from, scoreType: dec }', () => { + const listType = 'from'; + const scoreType = 'dec'; + it('with ENVS: { enableOverDraw: false, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 2 }, + { _id: 'USER3', score: 2 }, + { _id: 'USER4', score: 2 }, + { _id: 'USER1', score: 6 }, + ]); + }); - }); + it('with ENVS: { enableOverDraw: false, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 2 }, + { _id: 'USER3', score: 2 }, + { _id: 'USER4', score: 2 }, + { _id: 'USER1', score: 6 }, + ]); + }); + it('with ENVS: { enableOverDraw: true, enableDecrement: false }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 2 }, + { _id: 'USER3', score: 2 }, + { _id: 'USER4', score: 2 }, + { _id: 'USER1', score: 6 }, + ]); + }); + + it('with ENVS: { enableOverDraw: true, enableDecrement: true }', async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: true } + const scoreList = getScore({ listType, scoreType }) + expect(scoreList).toEqual([ + { _id: 'USER2', score: 2 }, + { _id: 'USER3', score: 2 }, + { _id: 'USER4', score: 2 }, + { _id: 'USER1', score: 6 }, + ]); + }); + }); + }); }); From 9aea2cd9e499b5391a6d55adfcc357a8e8464c61 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 30 Jan 2022 17:00:05 +0100 Subject: [PATCH 08/51] move out utils.ts to seperat files --- src/config/index.ts | 13 +-- src/database/drivers/GenericDriver.ts | 2 +- src/database/drivers/MongoDBDriver.ts | 2 +- src/lib/boot.ts | 2 +- src/lib/themeHandler.ts | 3 +- src/lib/utils.ts | 110 -------------------------- src/lib/utils/env.ts | 7 ++ src/lib/utils/path.ts | 33 ++++++++ src/lib/utils/sort.ts | 15 ++++ src/lib/utils/switch.ts | 1 + src/lib/utils/theme.ts | 26 ++++++ src/lib/utils/time.ts | 10 +++ src/middleware.ts | 2 +- src/store/BurritoStore.ts | 6 +- src/store/calc.ts | 2 +- 15 files changed, 103 insertions(+), 131 deletions(-) delete mode 100644 src/lib/utils.ts create mode 100644 src/lib/utils/env.ts create mode 100644 src/lib/utils/path.ts create mode 100644 src/lib/utils/sort.ts create mode 100644 src/lib/utils/switch.ts create mode 100644 src/lib/utils/theme.ts create mode 100644 src/lib/utils/time.ts diff --git a/src/config/index.ts b/src/config/index.ts index 4078804..caa0c34 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,14 +1,7 @@ import log from 'loglevel'; -import { - env, - fixPath, - mustHave, - themeRootPath, - defaultTheme, - root, - getThemePath, - getThemeName -} from '../lib/utils'; +import { env, mustHave } from '../lib/utils/env'; +import { getThemePath, getThemeName, themeRootPath, defaultTheme} from '../lib/utils/theme'; +import { fixPath, root} from '../lib/utils/path'; const isFalse = (input: string) => (input === 'false' || input === 'no' || input === '0'); diff --git a/src/database/drivers/GenericDriver.ts b/src/database/drivers/GenericDriver.ts index e17f192..6ed578c 100644 --- a/src/database/drivers/GenericDriver.ts +++ b/src/database/drivers/GenericDriver.ts @@ -1,7 +1,7 @@ import Store from './Store'; import Driver, { GivePost } from './Driver'; -import { time } from '../../lib/utils'; +import { time } from '../../lib/utils/time'; function id() { // Cred => https://gist.github.com/gordonbrander/2230317 diff --git a/src/database/drivers/MongoDBDriver.ts b/src/database/drivers/MongoDBDriver.ts index 461b155..e5510f2 100644 --- a/src/database/drivers/MongoDBDriver.ts +++ b/src/database/drivers/MongoDBDriver.ts @@ -1,4 +1,4 @@ -import { time } from '../../lib/utils'; +import { time } from '../../lib/utils/time'; const mongoConf = { useNewUrlParser: true, diff --git a/src/lib/boot.ts b/src/lib/boot.ts index c80e60c..ee35233 100644 --- a/src/lib/boot.ts +++ b/src/lib/boot.ts @@ -1,6 +1,6 @@ import log from 'loglevel'; import config from '../config'; -import { pathExists, createPath } from './utils'; +import { pathExists, createPath } from './utils/path'; import themeHandler from './themeHandler'; export default async () => { diff --git a/src/lib/themeHandler.ts b/src/lib/themeHandler.ts index 342cbbf..5b5599d 100644 --- a/src/lib/themeHandler.ts +++ b/src/lib/themeHandler.ts @@ -8,13 +8,14 @@ let times = 0; async function gitFunc(args, cwd: string) { const [option, url] = args; - + console.log(args,cwd) if (option === 'clone') log.info('Cloning theme:', url); if (option === 'pull') log.info('Pulling latest theme:', url); return new Promise((resolve, reject) => { const process = spawn('git', args, { cwd }); process.on('close', (status: any) => { + console.log(status) if (status === 0) { resolve(true); } else { diff --git a/src/lib/utils.ts b/src/lib/utils.ts deleted file mode 100644 index 2205803..0000000 --- a/src/lib/utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -import log from 'loglevel'; -import fs from 'fs'; -import path from 'path'; -import UserInterface from '../types/User.interface'; - -const root: string = path.normalize(`${__dirname}/../../`); -const themeRootPath: string = `${root}www/themes/`; -const defaultTheme: string = 'https://github.com/chralp/heyburrito-theme'; - - -const time = () => { - const start = new Date(); - const end = new Date(); - start.setHours(0, 0, 0, 0); - end.setHours(23, 59, 59, 999); - return { - start, - end, - }; -}; - -const sort = (input: UserInterface[], sortType: string = 'desc'): UserInterface[] => { - const sorted = input.sort((a, b) => { - if (a.score) { - if (sortType === 'desc') return b.score - a.score; - return a.score - b.score; - } else { - if (sortType === 'desc') return b.scoreinc - a.scoreinc; - return a.scoreinc - b.scoreinc; - } - }); - return sorted; -}; - -const env: string = process.env.NODE_ENV || 'development'; - -const fixPath = (p: string): string => { - if (!p.startsWith('/')) return `/${p}`; - if (!p.endsWith('/')) return `${p}/`; - return p; -}; - -const pathExists = (inPath: string) => { - try { - log.debug('Checking if path exists', inPath); - return fs.lstatSync(inPath).isDirectory(); - } catch (e) { - return false; - } -}; - -const createPath = (inPath: string) => { - try { - log.debug(`Trying to create path ${inPath}`); - fs.mkdirSync(inPath); - const exists = pathExists(inPath); - if (exists) return true; - throw new Error('Neit'); - } catch (e) { - log.debug(`Could not create path ${inPath}`); - return false; - } -}; - -const mustHave = (key: string) => { - if (env === 'development' || env === 'testing') return process.env[key]; - if (!process.env[key]) throw new Error(`Missing ENV ${key}`); - return process.env[key]; -}; - -const getThemeName = () => { - if (process.env.THEME_PATH) { - const themePath = process.env.THEME_PATH; - const [themeName] = themePath.split('/').slice(-1); - return themeName; - } - const theme = process.env.THEME_URL || defaultTheme; - const [themeName] = theme.split('/').slice(-1); - return themeName; -}; - -const getThemePath = () => { - if (process.env.THEME_PATH) { - const themePath = process.env.THEME_PATH; - if (themePath.endsWith('/')) return themePath; - return `${themePath}/`; - } - - const themeName = getThemeName(); - return `${themeRootPath}${themeName}/`; -}; - - -const listTypeSwitch = (listType: string) => listType === 'to' ? 'from' : 'to'; - -export { - time, - sort, - mustHave, - fixPath, - env, - pathExists, - createPath, - themeRootPath, - defaultTheme, - root, - getThemePath, - getThemeName, - listTypeSwitch, -}; diff --git a/src/lib/utils/env.ts b/src/lib/utils/env.ts new file mode 100644 index 0000000..a0e7dea --- /dev/null +++ b/src/lib/utils/env.ts @@ -0,0 +1,7 @@ +export const env: string = process.env.NODE_ENV || 'development'; + +export const mustHave = (key: string) => { + if (env === 'development' || env === 'testing') return process.env[key]; + if (!process.env[key]) throw new Error(`Missing ENV ${key}`); + return process.env[key]; +}; diff --git a/src/lib/utils/path.ts b/src/lib/utils/path.ts new file mode 100644 index 0000000..bb77abb --- /dev/null +++ b/src/lib/utils/path.ts @@ -0,0 +1,33 @@ +import log from 'loglevel'; +import path from 'path'; +import fs from 'fs'; + +export const root: string = path.normalize(`${__dirname}/../../`); + +export const fixPath = (p: string): string => { + if (!p.startsWith('/')) return `/${p}`; + if (!p.endsWith('/')) return `${p}/`; + return p; +}; + +export const pathExists = (inPath: string) => { + try { + log.debug('Checking if path exists', inPath); + return fs.lstatSync(inPath).isDirectory(); + } catch (e) { + return false; + } +}; + +export const createPath = (inPath: string) => { + try { + log.debug(`Trying to create path ${inPath}`); + fs.mkdirSync(inPath); + const exists = pathExists(inPath); + if (exists) return true; + throw new Error('Neit'); + } catch (e) { + log.debug(`Could not create path ${inPath}`); + return false; + } +}; diff --git a/src/lib/utils/sort.ts b/src/lib/utils/sort.ts new file mode 100644 index 0000000..56a5337 --- /dev/null +++ b/src/lib/utils/sort.ts @@ -0,0 +1,15 @@ + +import UserInterface from '../../types/User.interface'; + +export const sort = (input: UserInterface[], sortType: string = 'desc'): UserInterface[] => { + const sorted = input.sort((a, b) => { + if (a.score) { + if (sortType === 'desc') return b.score - a.score; + return a.score - b.score; + } else { + if (sortType === 'desc') return b.scoreinc - a.scoreinc; + return a.scoreinc - b.scoreinc; + } + }); + return sorted; +}; diff --git a/src/lib/utils/switch.ts b/src/lib/utils/switch.ts new file mode 100644 index 0000000..200d0c0 --- /dev/null +++ b/src/lib/utils/switch.ts @@ -0,0 +1 @@ +export const listTypeSwitch = (listType: string) => listType === 'to' ? 'from' : 'to'; diff --git a/src/lib/utils/theme.ts b/src/lib/utils/theme.ts new file mode 100644 index 0000000..e68ff38 --- /dev/null +++ b/src/lib/utils/theme.ts @@ -0,0 +1,26 @@ +import {root} from './path'; + +export const themeRootPath: string = `${root}www/themes/`; +export const defaultTheme: string = 'https://github.com/chralp/heyburrito-theme'; + +export const getThemeName = () => { + if (process.env.THEME_PATH) { + const themePath = process.env.THEME_PATH; + const [themeName] = themePath.split('/').slice(-1); + return themeName; + } + const theme = process.env.THEME_URL || defaultTheme; + const [themeName] = theme.split('/').slice(-1); + return themeName; +}; + +export const getThemePath = () => { + if (process.env.THEME_PATH) { + const themePath = process.env.THEME_PATH; + if (themePath.endsWith('/')) return themePath; + return `${themePath}/`; + } + + const themeName = getThemeName(); + return `${themeRootPath}${themeName}/`; +}; diff --git a/src/lib/utils/time.ts b/src/lib/utils/time.ts new file mode 100644 index 0000000..3bc2674 --- /dev/null +++ b/src/lib/utils/time.ts @@ -0,0 +1,10 @@ +export const time = () => { + const start = new Date(); + const end = new Date(); + start.setHours(0, 0, 0, 0); + end.setHours(23, 59, 59, 999); + return { + start, + end, + }; +}; diff --git a/src/middleware.ts b/src/middleware.ts index 2f4b440..9b30826 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,6 +1,6 @@ import config from './config'; import mapper from './lib/mapper'; -import { sort } from './lib/utils'; +import { sort } from './lib/utils/sort'; import BurritoStore from './store/BurritoStore'; import { levelScoreList, calculateScore } from './store/calc'; diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 2082cc9..48f88a9 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -1,7 +1,7 @@ import log from 'loglevel'; import { EventEmitter } from 'events'; import config from '../config'; -import { listTypeSwitch } from '../lib/utils'; +import { listTypeSwitch } from '../lib/utils/switch'; import {calculateScore} from './calc'; import Driver, { GetScoreBoard, @@ -30,10 +30,6 @@ interface BurritoUpdate { overdrawn?: boolean; } - -console.log("OUTSIDE", config.slack.enableOverDraw, config.slack.enableDecrement) - - class BurritoStore extends EventEmitter { database: Driver; diff --git a/src/store/calc.ts b/src/store/calc.ts index 7889512..c1f386e 100644 --- a/src/store/calc.ts +++ b/src/store/calc.ts @@ -1,5 +1,5 @@ import config from '../config'; -import { listTypeSwitch } from '../lib/utils'; +import { listTypeSwitch } from '../lib/utils/switch'; import { DatabasePost } from '../database/drivers/Driver'; interface CalculateScoreArgs { From 65d02c41e3c2f750fc3b57b1762a420c25cd4dd6 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 30 Jan 2022 17:47:32 +0100 Subject: [PATCH 09/51] update --- test/{chralp.test.ts => calc.test.ts} | 0 test/data/slackUsers.ts | 528 +++++++++++++------------- test/lib/seedDatabase.ts | 3 +- test/utils.test.ts | 2 +- 4 files changed, 267 insertions(+), 266 deletions(-) rename test/{chralp.test.ts => calc.test.ts} (100%) diff --git a/test/chralp.test.ts b/test/calc.test.ts similarity index 100% rename from test/chralp.test.ts rename to test/calc.test.ts diff --git a/test/data/slackUsers.ts b/test/data/slackUsers.ts index 62a8f8e..0d312f9 100644 --- a/test/data/slackUsers.ts +++ b/test/data/slackUsers.ts @@ -1,275 +1,275 @@ const wbcList = { - "ok": true, - "members": [ - { - "id": "USER1", - "team_id": "TEAMBURRITO", - "name": "User numero uno", - "deleted": false, - "color": "4bbe2e", - "real_name": "User1", - "tz": "Europe/Amsterdam", - "tz_label": "Central European Time", - "tz_offset": 3600, - "profile": { - "title": "", - "phone": "", - "skype": "", - "real_name": "User numero uno", - "real_name_normalized": "Numero Uno", - "display_name": "", - "display_name_normalized": "", - "status_text": "", - "status_emoji": "", - "status_expiration": 0, - "avatar_hash": "avatarohasho", - "email": "uno@hey.burrito", - "image_24": "https://link.to.avatar.24.burrito", - "image_32": "https://link.to.avatar.32.burrito", - "image_48": "https://link.to.avatar.48.burrito", - "image_72": "https://link.to.avatar.72.burrito", - "image_192": "https://link.to.avatar.192.burrito", - "image_512": "https://link.to.avatar.512.burrito", - "status_text_canonical": "", - "team": "TEAMBURRITO" - }, - "is_admin": false, - "is_owner": false, - "is_primary_owner": false, - "is_restricted": false, - "is_ultra_restricted": false, - "is_bot": false, - "is_app_user": false, - "updated": 1543910803 - }, - { - "id": "USER2", - "team_id": "TEAMBURRITO", - "name": "User numero dos", - "deleted": false, - "color": "4bbe2e", - "real_name": "User2", - "tz": "Europe/Amsterdam", - "tz_label": "Central European Time", - "tz_offset": 3600, - "profile": { - "title": "", - "phone": "", - "skype": "", - "real_name": "User numero dos", - "real_name_normalized": "Numero dos", - "display_name": "", - "display_name_normalized": "", - "status_text": "", - "status_emoji": "", - "status_expiration": 0, - "avatar_hash": "avatarohasho", - "email": "dos@hey.burrito", - "image_24": "https://link.to.avatar.24.burrito", - "image_32": "https://link.to.avatar.32.burrito", - "image_48": "https://link.to.avatar.48.burrito", - "image_72": "https://link.to.avatar.72.burrito", - "image_192": "https://link.to.avatar.192.burrito", - "image_512": "https://link.to.avatar.512.burrito", - "status_text_canonical": "", - "team": "TEAMBURRITO" - }, - "is_admin": false, - "is_owner": false, - "is_primary_owner": false, - "is_restricted": false, - "is_ultra_restricted": false, - "is_bot": false, - "is_app_user": false, - "updated": 1543910803 - }, - { - "id": "USER3", - "team_id": "TEAMBURRITO", - "name": "User numero tres", - "deleted": false, - "color": "4bbe2e", - "real_name": "User3", - "tz": "Europe/Amsterdam", - "tz_label": "Central European Time", - "tz_offset": 3600, - "profile": { - "title": "", - "phone": "", - "skype": "", - "real_name": "User numero tre", - "real_name_normalized": "Numero tres", - "display_name": "", - "display_name_normalized": "", - "status_text": "", - "status_emoji": "", - "status_expiration": 0, - "avatar_hash": "avatarohasho", - "email": "tres@hey.burrito", - "image_24": "https://link.to.avatar.24.burrito", - "image_32": "https://link.to.avatar.32.burrito", - "image_48": "https://link.to.avatar.48.burrito", - "image_72": "https://link.to.avatar.72.burrito", - "image_192": "https://link.to.avatar.192.burrito", - "image_512": "https://link.to.avatar.512.burrito", - "status_text_canonical": "", - "team": "TEAMBURRITO" - }, - "is_admin": false, - "is_owner": false, - "is_primary_owner": false, - "is_restricted": false, - "is_ultra_restricted": false, - "is_bot": false, - "is_app_user": false, - "updated": 1543910803 - }, - { - "id": "USER4", - "team_id": "TEAMBURRITO", - "name": "User numero quatro", - "deleted": false, - "color": "4bbe2e", - "real_name": "User4", - "tz": "Europe/Amsterdam", - "tz_label": "Central European Time", - "tz_offset": 3600, - "profile": { - "title": "", - "phone": "", - "skype": "", - "real_name": "User numero quatro", - "real_name_normalized": "Numero quatro", - "display_name": "", - "display_name_normalized": "", - "status_text": "", - "status_emoji": "", - "status_expiration": 0, - "avatar_hash": "avatarohasho", - "email": "quatro@hey.burrito", - "image_24": "https://link.to.avatar.24.burrito", - "image_32": "https://link.to.avatar.32.burrito", - "image_48": "https://link.to.avatar.48.burrito", - "image_72": "https://link.to.avatar.72.burrito", - "image_192": "https://link.to.avatar.192.burrito", - "image_512": "https://link.to.avatar.512.burrito", - "status_text_canonical": "", - "team": "TEAMBURRITO" - }, - "is_admin": false, - "is_owner": false, - "is_primary_owner": false, - "is_restricted": false, - "is_ultra_restricted": false, - "is_bot": false, - "is_app_user": false, - "updated": 1543910803 - }, - {"id":"USER7","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER8","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER9","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER10","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER11","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER12","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER13","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER14","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER15","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER16","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER17","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER18","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER19","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER20","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER21","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER22","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER23","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER24","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER25","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER26","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER27","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER28","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER29","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER30","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER31","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER32","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER33","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER34","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER35","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER36","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER37","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER38","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER39","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER40","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER41","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER42","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER43","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER44","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER45","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER46","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER47","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER48","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER49","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803},{"id":"USER50","team_id":"TEAMBURRITO","name":"User numero uno","deleted":false,"color":"4bbe2e","real_name":"User1","tz":"Europe/Amsterdam","tz_label":"Central European Time","tz_offset":3600,"profile":{"title":"","phone":"","skype":"","real_name":"User numero uno","real_name_normalized":"Numero Uno","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"avatarohasho","email":"uno@hey.burrito","image_24":"https://link.to.avatar.24.burrito","image_32":"https://link.to.avatar.32.burrito","image_48":"https://link.to.avatar.48.burrito","image_72":"https://link.to.avatar.72.burrito","image_192":"https://link.to.avatar.192.burrito","image_512":"https://link.to.avatar.512.burrito","status_text_canonical":"","team":"TEAMBURRITO"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1543910803}, - { - "id": "BURRITOBOT", - "team_id": "TEAMBURRITO", - "name": "heyburrito", - "deleted": false, - "color": "674b1b", - "real_name": "heyburrito", - "tz": "America/Los_Angeles", - "tz_label": "Pacific Standard Time", - "tz_offset": -28800, - "profile": { - "title": "", - "phone": "", - "skype": "", - "real_name": "heyburrito", - "real_name_normalized": "heyburrito", - "display_name": "", - "display_name_normalized": "", - "status_text": "", - "status_emoji": "", - "status_expiration": 0, - "avatar_hash": "avatarohaso", - "bot_id": "BURRITOBOT", - "api_app_id": "", - "always_active": false, - "image_original": "https://link.to.avatar.original.burrito", - "image_24": "https://link.to.avatar.24.burrito", - "image_32": "https://link.to.avatar.32.burrito", - "image_48": "https://link.to.avatar.48.burrito", - "image_72": "https://link.to.avatar.72.burrito", - "image_192": "https://link.to.avatar.192.burrito", - "image_512": "https://link.to.avatar.512.burrito", - "image_1024": "https://link.to.avatar.1024.burrito", - "status_text_canonical": "", - "team": "TEAMBURRITO", - "is_custom_image": true - }, - "is_admin": false, - "is_owner": false, - "is_primary_owner": false, - "is_restricted": false, - "is_ultra_restricted": false, - "is_bot": true, - "is_app_user": false, - "updated": 1546207422 - } - ], - "cache_ts": 1546217431, - "response_metadata": { - "next_cursor": "" + "ok": true, + "members": [ + { + "id": "USER1", + "team_id": "TEAMBURRITO", + "name": "User numero uno", + "deleted": false, + "color": "4bbe2e", + "real_name": "User1", + "tz": "Europe/Amsterdam", + "tz_label": "Central European Time", + "tz_offset": 3600, + "profile": { + "title": "", + "phone": "", + "skype": "", + "real_name": "User numero uno", + "real_name_normalized": "Numero Uno", + "display_name": "", + "display_name_normalized": "", + "status_text": "", + "status_emoji": "", + "status_expiration": 0, + "avatar_hash": "avatarohasho", + "email": "uno@hey.burrito", + "image_24": "https://link.to.avatar.24.burrito", + "image_32": "https://link.to.avatar.32.burrito", + "image_48": "https://link.to.avatar.48.burrito", + "image_72": "https://link.to.avatar.72.burrito", + "image_192": "https://link.to.avatar.192.burrito", + "image_512": "https://link.to.avatar.512.burrito", + "status_text_canonical": "", + "team": "TEAMBURRITO" + }, + "is_admin": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "is_bot": false, + "is_app_user": false, + "updated": 1543910803 }, - "scopes": [ - "identify", - "read", - "post", - "client", - "apps" - ], - "acceptedScopes": [ - "users:read", - "read" - ] + { + "id": "USER2", + "team_id": "TEAMBURRITO", + "name": "User numero dos", + "deleted": false, + "color": "4bbe2e", + "real_name": "User2", + "tz": "Europe/Amsterdam", + "tz_label": "Central European Time", + "tz_offset": 3600, + "profile": { + "title": "", + "phone": "", + "skype": "", + "real_name": "User numero dos", + "real_name_normalized": "Numero dos", + "display_name": "", + "display_name_normalized": "", + "status_text": "", + "status_emoji": "", + "status_expiration": 0, + "avatar_hash": "avatarohasho", + "email": "dos@hey.burrito", + "image_24": "https://link.to.avatar.24.burrito", + "image_32": "https://link.to.avatar.32.burrito", + "image_48": "https://link.to.avatar.48.burrito", + "image_72": "https://link.to.avatar.72.burrito", + "image_192": "https://link.to.avatar.192.burrito", + "image_512": "https://link.to.avatar.512.burrito", + "status_text_canonical": "", + "team": "TEAMBURRITO" + }, + "is_admin": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "is_bot": false, + "is_app_user": false, + "updated": 1543910803 + }, + { + "id": "USER3", + "team_id": "TEAMBURRITO", + "name": "User numero tres", + "deleted": false, + "color": "4bbe2e", + "real_name": "User3", + "tz": "Europe/Amsterdam", + "tz_label": "Central European Time", + "tz_offset": 3600, + "profile": { + "title": "", + "phone": "", + "skype": "", + "real_name": "User numero tre", + "real_name_normalized": "Numero tres", + "display_name": "", + "display_name_normalized": "", + "status_text": "", + "status_emoji": "", + "status_expiration": 0, + "avatar_hash": "avatarohasho", + "email": "tres@hey.burrito", + "image_24": "https://link.to.avatar.24.burrito", + "image_32": "https://link.to.avatar.32.burrito", + "image_48": "https://link.to.avatar.48.burrito", + "image_72": "https://link.to.avatar.72.burrito", + "image_192": "https://link.to.avatar.192.burrito", + "image_512": "https://link.to.avatar.512.burrito", + "status_text_canonical": "", + "team": "TEAMBURRITO" + }, + "is_admin": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "is_bot": false, + "is_app_user": false, + "updated": 1543910803 + }, + { + "id": "USER4", + "team_id": "TEAMBURRITO", + "name": "User numero quatro", + "deleted": false, + "color": "4bbe2e", + "real_name": "User4", + "tz": "Europe/Amsterdam", + "tz_label": "Central European Time", + "tz_offset": 3600, + "profile": { + "title": "", + "phone": "", + "skype": "", + "real_name": "User numero quatro", + "real_name_normalized": "Numero quatro", + "display_name": "", + "display_name_normalized": "", + "status_text": "", + "status_emoji": "", + "status_expiration": 0, + "avatar_hash": "avatarohasho", + "email": "quatro@hey.burrito", + "image_24": "https://link.to.avatar.24.burrito", + "image_32": "https://link.to.avatar.32.burrito", + "image_48": "https://link.to.avatar.48.burrito", + "image_72": "https://link.to.avatar.72.burrito", + "image_192": "https://link.to.avatar.192.burrito", + "image_512": "https://link.to.avatar.512.burrito", + "status_text_canonical": "", + "team": "TEAMBURRITO" + }, + "is_admin": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "is_bot": false, + "is_app_user": false, + "updated": 1543910803 + }, + { "id": "USER7", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER8", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER9", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER10", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER11", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER12", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER13", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER14", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER15", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER16", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER17", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER18", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER19", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER20", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER21", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER22", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER23", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER24", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER25", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER26", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER27", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER28", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER29", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER30", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER31", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER32", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER33", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER34", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER35", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER36", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER37", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER38", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER39", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER40", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER41", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER42", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER43", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER44", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER45", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER46", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER47", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER48", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER49", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER50", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, + { + "id": "BURRITOBOT", + "team_id": "TEAMBURRITO", + "name": "heyburrito", + "deleted": false, + "color": "674b1b", + "real_name": "heyburrito", + "tz": "America/Los_Angeles", + "tz_label": "Pacific Standard Time", + "tz_offset": -28800, + "profile": { + "title": "", + "phone": "", + "skype": "", + "real_name": "heyburrito", + "real_name_normalized": "heyburrito", + "display_name": "", + "display_name_normalized": "", + "status_text": "", + "status_emoji": "", + "status_expiration": 0, + "avatar_hash": "avatarohaso", + "bot_id": "BURRITOBOT", + "api_app_id": "", + "always_active": false, + "image_original": "https://link.to.avatar.original.burrito", + "image_24": "https://link.to.avatar.24.burrito", + "image_32": "https://link.to.avatar.32.burrito", + "image_48": "https://link.to.avatar.48.burrito", + "image_72": "https://link.to.avatar.72.burrito", + "image_192": "https://link.to.avatar.192.burrito", + "image_512": "https://link.to.avatar.512.burrito", + "image_1024": "https://link.to.avatar.1024.burrito", + "status_text_canonical": "", + "team": "TEAMBURRITO", + "is_custom_image": true + }, + "is_admin": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "is_bot": true, + "is_app_user": false, + "updated": 1546207422 + } + ], + "cache_ts": 1546217431, + "response_metadata": { + "next_cursor": "" + }, + "scopes": [ + "identify", + "read", + "post", + "client", + "apps" + ], + "acceptedScopes": [ + "users:read", + "read" + ] } const wbcListParsed = { - users: [ - { - id: 'USER1', - memberType: 'member', - name: 'User1', - avatar: 'https://link.to.avatar.48.burrito' - }, - { - id: 'USER2', - memberType: 'member', - name: 'User2', - avatar: 'https://link.to.avatar.48.burrito' - }, - { - id: 'USER3', - memberType: 'member', - name: 'User3', - avatar: 'https://link.to.avatar.48.burrito' - }, - { - id: 'USER4', - memberType: 'member', - name: 'User4', - avatar: 'https://link.to.avatar.48.burrito' - } - ], - bots: [ - { - id: 'BURRITOBOT', - memberType: 'member', - name: 'heyburrito', - avatar: 'https://link.to.avatar.48.burrito' - } - ] + users: [ + { + id: 'USER1', + memberType: 'member', + name: 'User1', + avatar: 'https://link.to.avatar.48.burrito' + }, + { + id: 'USER2', + memberType: 'member', + name: 'User2', + avatar: 'https://link.to.avatar.48.burrito' + }, + { + id: 'USER3', + memberType: 'member', + name: 'User3', + avatar: 'https://link.to.avatar.48.burrito' + }, + { + id: 'USER4', + memberType: 'member', + name: 'User4', + avatar: 'https://link.to.avatar.48.burrito' + } + ], + bots: [ + { + id: 'BURRITOBOT', + memberType: 'member', + name: 'heyburrito', + avatar: 'https://link.to.avatar.48.burrito' + } + ] } export { - wbcList, - wbcListParsed + wbcList, + wbcListParsed }; diff --git a/test/lib/seedDatabase.ts b/test/lib/seedDatabase.ts index 8a7a3ce..d4952a4 100644 --- a/test/lib/seedDatabase.ts +++ b/test/lib/seedDatabase.ts @@ -2,7 +2,8 @@ import * as dotenv from 'dotenv'; dotenv.config(); import * as fs from 'fs'; import config from '../../src/config'; -import { env, pathExists, createPath } from '../../src/lib/utils'; +import { env } from '../../src/lib/utils/env'; +import {pathExists, createPath } from '../../src/lib/utils/path'; import { MongoMemoryServer } from 'mongodb-memory-server'; diff --git a/test/utils.test.ts b/test/utils.test.ts index 45977f0..fd47f06 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -1,4 +1,4 @@ -import { sort } from '../src/lib/utils'; +import { sort } from '../src/lib/utils/sort'; let data; beforeEach(() => { data = [ From b5cbf182f5668da4859a44fef853ba9ad1b3e2b8 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 30 Jan 2022 19:25:28 +0100 Subject: [PATCH 10/51] update --- src/config/index.ts | 6 +++--- src/lib/utils/path.ts | 4 ++-- src/server.ts | 5 +---- src/store/BurritoStore.ts | 25 ------------------------- src/store/calc.ts | 2 +- 5 files changed, 7 insertions(+), 35 deletions(-) diff --git a/src/config/index.ts b/src/config/index.ts index caa0c34..883d40b 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -89,9 +89,9 @@ const config = { disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), - overdrawCap: getBool(process.env.ENABLE_OVERDRAW, true) ? getNum(process.env.SLACK_OVERDRAW_CAP, 5) : 0, - enableOverDraw: getBool(process.env.ENABLE_OVERDRAW, true), - enableDecrement: getBool(process.env.ENABLE_DECREMENT, false), + overdrawCap: getBool(process.env.ENABLE_OVERDRAW, false) ? getNum(process.env.SLACK_OVERDRAW_CAP, 5) : 0, + enableOverDraw: getBool(process.env.ENABLE_OVERDRAW, false), + enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), }, http: { http_port: getNum(process.env.HTTP_PORT, 3333), diff --git a/src/lib/utils/path.ts b/src/lib/utils/path.ts index bb77abb..7a68ca8 100644 --- a/src/lib/utils/path.ts +++ b/src/lib/utils/path.ts @@ -2,8 +2,8 @@ import log from 'loglevel'; import path from 'path'; import fs from 'fs'; -export const root: string = path.normalize(`${__dirname}/../../`); - +export const root: string = path.normalize(`${__dirname}/../../../`); +console.log("root", root) export const fixPath = (p: string): string => { if (!p.startsWith('/')) return `/${p}`; if (!p.endsWith('/')) return `${p}/`; diff --git a/src/server.ts b/src/server.ts index 8655819..6c49789 100644 --- a/src/server.ts +++ b/src/server.ts @@ -24,16 +24,13 @@ init().then(() => { log.setLevel(config.misc.log_level); log.info('Staring heyburrito'); - + console.log(config) // Configure BurritoStore BurritoStore.setDatabase(database); // Set and start slack services const { rtm, wbc } = slack; - //BurritoStore.getUserScore("UEKN9GNAJ", 'to', 'dec'); - //BurritoStore.getUserScore("UEHUXHG0G", 'to', 'inc'); - rtm.start(); RTMHandler.register(rtm); WBCHandler.register(wbc); diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 48f88a9..b7079ae 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -107,8 +107,6 @@ class BurritoStore extends EventEmitter { }; - - /** * Get UserScore depending on listType and scoreType. */ @@ -127,29 +125,6 @@ class BurritoStore extends EventEmitter { }; - - public filterScoreData(data: DatabasePost[], scoreType: string) { - - const scoreSwitch = (scoreType === 'inc') ? 1 : -1; - const valueSwitch = (scoreType === 'dec') ? 1 : 0; - - return data.filter((entry) => { - if (config.slack.enableDecrement) { - if (!config.slack.enableOverDraw) { - return valueSwitch - ? (entry.overdrawn !== true && entry.value === scoreSwitch) - : entry.overdrawn !== true; - } else { - return valueSwitch ? entry.value === scoreSwitch : entry; - } - } else { - if (entry.value == scoreSwitch) { - if (config.slack.enableOverDraw) return entry; - return entry.overdrawn !== true; - } - } - }); - }; } export default new BurritoStore(); diff --git a/src/store/calc.ts b/src/store/calc.ts index c1f386e..817db7e 100644 --- a/src/store/calc.ts +++ b/src/store/calc.ts @@ -19,7 +19,7 @@ export const calculateScore = (data: DatabasePost[], overDrawnData?: DatabasePos const { listType, scoreType, user } = args; const { enableOverDraw, enableDecrement } = config.slack; - const _dataOverDrawn = overDrawnData.filter((entry: DatabasePost) => { + const _dataOverDrawn = scoreType === 'dec' ? [] : overDrawnData.filter((entry: DatabasePost) => { // Just ensure that we filter out correct user data if user is present const list = listType === 'to' ? listTypeSwitch(listType) : listType; From 7af53bcc7d301e55e4e61ade18912a4f0333dcce Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Mon, 31 Jan 2022 18:14:58 +0100 Subject: [PATCH 11/51] update --- src/lib/utils/path.ts | 1 - src/middleware.ts | 1 - .../{burritostore.test.ts => burritostore.ts} | 0 test/calc.test.ts | 3 - test/handleBurritos.test.ts | 86 ++++++++++ test/lib/seedDatabase.ts | 156 +++++++++--------- 6 files changed, 164 insertions(+), 83 deletions(-) rename test/{burritostore.test.ts => burritostore.ts} (100%) create mode 100644 test/handleBurritos.test.ts diff --git a/src/lib/utils/path.ts b/src/lib/utils/path.ts index 7a68ca8..379b2d2 100644 --- a/src/lib/utils/path.ts +++ b/src/lib/utils/path.ts @@ -3,7 +3,6 @@ import path from 'path'; import fs from 'fs'; export const root: string = path.normalize(`${__dirname}/../../../`); -console.log("root", root) export const fixPath = (p: string): string => { if (!p.startsWith('/')) return `/${p}`; if (!p.endsWith('/')) return `${p}/`; diff --git a/src/middleware.ts b/src/middleware.ts index 9b30826..988f9d5 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -114,7 +114,6 @@ const givenBurritosToday = async (user: string) => { * @param {string} user - Slack userId */ const getUserScore = async (user: string, listType: string, scoreType: string) => { - console.log("HAALÃ…Ã…Ã…") const scoreList = await BurritoStore.getScoreBoard({ listType }); const userScore = scoreList.filter((x) => x[listType] === user); diff --git a/test/burritostore.test.ts b/test/burritostore.ts similarity index 100% rename from test/burritostore.test.ts rename to test/burritostore.ts diff --git a/test/calc.test.ts b/test/calc.test.ts index 268c0e7..396957e 100644 --- a/test/calc.test.ts +++ b/test/calc.test.ts @@ -4,10 +4,7 @@ import { scoreBoard, user1ScoreData, user2ScoreData } from './data/calculatescor const getScore = ({ listType, scoreType, user }: any) => { const uniqueUsername: string[] = [...new Set(scoreBoard.map((x) => x[listType]))]; - - const overDrawnData = scoreType === 'dec' ? [] : scoreBoard; - const scoreList = uniqueUsername .map((user) => ({ _id: user, score: calculateScore(scoreBoard, overDrawnData, { listType, scoreType, user }) })) .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); diff --git a/test/handleBurritos.test.ts b/test/handleBurritos.test.ts new file mode 100644 index 0000000..3cdbf5d --- /dev/null +++ b/test/handleBurritos.test.ts @@ -0,0 +1,86 @@ +import { init } from './lib/seedDatabase'; +import { handleBurritos } from '../src/handleBurritos'; +import * as config from '../src/config'; +let mongod: any, mongoDriver: any; + +describe('handleBurritos-test', () => { + [ + // { + // describe: 'file Driver', + // driver: 'file' + // }, + { + describe: 'Array Driver', + driver: 'array' + }, + // { + // describe: 'Mongodb Driver', + // driver: 'mongodb' + // }, + ].forEach((test) => { + describe(test.describe, () => { + + async function connectDB(seedDB = false) { + const dbinit: any = await init({ driver: test.driver, random: false, seedDB }); + if (dbinit.mongod && dbinit.mongoDriver) { + mongod = dbinit.mongod + mongoDriver = dbinit.mongoDriver + } + } + + async function closeDB() { + if (test.driver === 'mongodb') { + if (mongoDriver.client) await mongoDriver.client.close(); + if (mongod) await mongod.stop(); + } + } + + beforeAll(async () => { + await connectDB() + + }); + + afterAll(async () => { + await closeDB() + }); + + + + + + describe('USER1 should give USER2 5 burritos', () => { + it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const updates = [ + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }]; + await handleBurritos('USER1', updates) + }); + }); + + describe('USER1 should NOT give USER2 5 burritos', () => { + it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { + config.default.slack = { enableOverDraw: true, enableDecrement: false } + const updates = [ + { username: 'USER1', burritoType: 'inc' }, + { username: 'USER1', burritoType: 'inc' }, + { username: 'USER1', burritoType: 'inc' }, + { username: 'USER1', burritoType: 'inc' }, + { username: 'USER1', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }]; + await handleBurritos('USER2', updates) + }); + }); + + + + }); + }); +}); diff --git a/test/lib/seedDatabase.ts b/test/lib/seedDatabase.ts index d4952a4..2e72c55 100644 --- a/test/lib/seedDatabase.ts +++ b/test/lib/seedDatabase.ts @@ -3,7 +3,7 @@ dotenv.config(); import * as fs from 'fs'; import config from '../../src/config'; import { env } from '../../src/lib/utils/env'; -import {pathExists, createPath } from '../../src/lib/utils/path'; +import { pathExists, createPath } from '../../src/lib/utils/path'; import { MongoMemoryServer } from 'mongodb-memory-server'; @@ -26,109 +26,109 @@ const oneWeek = new Date(today); yesterDay.setDate(yesterDay.getDate() - 1); oneWeek.setDate(today.getDate() - 7); function pickRandomDate(start, end) { - return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); + return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); } async function give(to, from, date, overdrawn = false) { - await BurritoStore.give({ to, from, type: 'inc', overdrawn }) + await BurritoStore.give({ to, from, type: 'inc', overdrawn }) } async function takeaway(to, from, date, overdrawn = false) { - await BurritoStore.give({ to, from, type: 'dec', overdrawn }) + await BurritoStore.give({ to, from, type: 'dec', overdrawn }) } function pickRandom(input) { - switch (input) { - case 'user': - return SLACKUSERS[Math.floor(Math.random() * SLACKUSERS.length)] - break; - } + switch (input) { + case 'user': + return SLACKUSERS[Math.floor(Math.random() * SLACKUSERS.length)] + break; + } } async function init({ driver = config.db.db_driver, random, seedDB = true }) { - // Set and start slack services - const { wbc } = slack; - - SLACKUSERS = [] + // Set and start slack services + const { wbc } = slack; - if (!pathExists(config.db.db_path)) { - if (createPath(config.db.db_path)) { - } else { - throw new Error('Could not create database path'); - } - } - - await WBCHandler.register(wbc); - await Localstore.fetch(); - const users = await Localstore.getSlackUsers(); - SLACKUSERS = users.map(x => x.id) - - if (env === 'testing' && driver === 'file') { - try { - fs.unlinkSync(`${config.db.db_path}${config.db.db_fileName}`); - } - catch (e) { - } - }; + SLACKUSERS = [] - if (env === 'testing' && driver === 'mongodb') { - mongod = new MongoMemoryServer(); - const uri = await mongod.getConnectionString(); - const database = await mongod.getDbName(); - mongoDriver = databaseDrivers[driver]({ db_uri: uri, db_name: database }); - BurritoStore.setDatabase(mongoDriver); + if (!pathExists(config.db.db_path)) { + if (createPath(config.db.db_path)) { } else { - BurritoStore.setDatabase(databaseDrivers[driver]()) + throw new Error('Could not create database path'); } + } + await WBCHandler.register(wbc); + await Localstore.fetch(); + const users = await Localstore.getSlackUsers(); + SLACKUSERS = users.map(x => x.id) - if (!seedDB) { - return { - mongoDriver, - mongod - }; + if (env === 'testing' && driver === 'file') { + try { + fs.unlinkSync(`${config.db.db_path}${config.db.db_fileName}`); } + catch (e) { + } + }; + if (env === 'testing' && driver === 'mongodb') { + mongod = new MongoMemoryServer(); + const uri = await mongod.getConnectionString(); + const database = await mongod.getDbName(); + mongoDriver = databaseDrivers[driver]({ db_uri: uri, db_name: database }); + BurritoStore.setDatabase(mongoDriver); + } else { + BurritoStore.setDatabase(databaseDrivers[driver]()) + } - if (random) { - for (let i = 1; i <= 100; i++) { - const fromUser = pickRandom('user'); - let toUser = pickRandom('user') - while (fromUser === toUser) { - toUser = pickRandom('user') - } - - const typeBurrito = TYPES[Math.floor(Math.random() * TYPES.length)] - switch (typeBurrito) { - case 'give': - await give(toUser, fromUser, pickRandomDate(oneWeek, today)); - break; - case 'takeaway': - await takeaway(toUser, fromUser, pickRandomDate(oneWeek, today)) - break; - } - } - } else { - mockData.forEach(async (data) => { - const date = (data.date === 'random') ? pickRandomDate(oneWeek, yesterDay) : undefined; - switch (data.type) { - case 'inc': - await give(data.to, data.from, date); - break; - case 'dec': - await takeaway(data.to, data.from, date); - break; - } - }); - } + if (!seedDB) { return { - mongoDriver, - mongod + mongoDriver, + mongod }; + } + + + if (random) { + for (let i = 1; i <= 100; i++) { + const fromUser = pickRandom('user'); + let toUser = pickRandom('user') + while (fromUser === toUser) { + toUser = pickRandom('user') + } + + const typeBurrito = TYPES[Math.floor(Math.random() * TYPES.length)] + switch (typeBurrito) { + case 'give': + await give(toUser, fromUser, pickRandomDate(oneWeek, today)); + break; + case 'takeaway': + await takeaway(toUser, fromUser, pickRandomDate(oneWeek, today)) + break; + } + } + } else { + mockData.forEach(async (data) => { + const date = (data.date === 'random') ? pickRandomDate(oneWeek, yesterDay) : undefined; + switch (data.type) { + case 'inc': + await give(data.to, data.from, date); + break; + case 'dec': + await takeaway(data.to, data.from, date); + break; + } + }); + + } + return { + mongoDriver, + mongod + }; } export { - init, + init, } From 69da8a0484e9aaf1fbb041feda5d01aaab41c0cd Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:31:10 +0100 Subject: [PATCH 12/51] new way to setup and seed test db --- test/lib/mockDatabase.ts | 7 -- test/lib/seedDatabase.ts | 134 --------------------------------------- 2 files changed, 141 deletions(-) delete mode 100644 test/lib/mockDatabase.ts delete mode 100644 test/lib/seedDatabase.ts diff --git a/test/lib/mockDatabase.ts b/test/lib/mockDatabase.ts deleted file mode 100644 index 4316a7f..0000000 --- a/test/lib/mockDatabase.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { init } from './seedDatabase'; - -const random = true - -init({ random }).then((data) => { - console.log("Database filled with data"); -}); diff --git a/test/lib/seedDatabase.ts b/test/lib/seedDatabase.ts deleted file mode 100644 index 2e72c55..0000000 --- a/test/lib/seedDatabase.ts +++ /dev/null @@ -1,134 +0,0 @@ -import * as dotenv from 'dotenv'; -dotenv.config(); -import * as fs from 'fs'; -import config from '../../src/config'; -import { env } from '../../src/lib/utils/env'; -import { pathExists, createPath } from '../../src/lib/utils/path'; - -import { MongoMemoryServer } from 'mongodb-memory-server'; - -import databaseDrivers from '../../src/database/drivers'; -import BurritoStore from '../../src/store/BurritoStore'; -import Localstore from '../../src/store/LocalStore'; -import WBCHandler from '../../src/slack/Wbc'; -import slack from '../../src/slack'; -const mockData = require('../data/mockData'); - -const TYPES = ['give', 'takeaway']; -let SLACKUSERS = []; -let mongod, mongoDriver - - - -const today = new Date(); -const yesterDay = new Date(today); -const oneWeek = new Date(today); -yesterDay.setDate(yesterDay.getDate() - 1); -oneWeek.setDate(today.getDate() - 7); -function pickRandomDate(start, end) { - return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); -} - -async function give(to, from, date, overdrawn = false) { - await BurritoStore.give({ to, from, type: 'inc', overdrawn }) -} -async function takeaway(to, from, date, overdrawn = false) { - await BurritoStore.give({ to, from, type: 'dec', overdrawn }) - -} - -function pickRandom(input) { - switch (input) { - case 'user': - return SLACKUSERS[Math.floor(Math.random() * SLACKUSERS.length)] - break; - } -} - - -async function init({ driver = config.db.db_driver, random, seedDB = true }) { - - // Set and start slack services - const { wbc } = slack; - - SLACKUSERS = [] - - if (!pathExists(config.db.db_path)) { - if (createPath(config.db.db_path)) { - } else { - throw new Error('Could not create database path'); - } - } - - await WBCHandler.register(wbc); - await Localstore.fetch(); - const users = await Localstore.getSlackUsers(); - SLACKUSERS = users.map(x => x.id) - - if (env === 'testing' && driver === 'file') { - try { - fs.unlinkSync(`${config.db.db_path}${config.db.db_fileName}`); - } - catch (e) { - } - }; - - if (env === 'testing' && driver === 'mongodb') { - mongod = new MongoMemoryServer(); - const uri = await mongod.getConnectionString(); - const database = await mongod.getDbName(); - mongoDriver = databaseDrivers[driver]({ db_uri: uri, db_name: database }); - BurritoStore.setDatabase(mongoDriver); - } else { - BurritoStore.setDatabase(databaseDrivers[driver]()) - } - - - if (!seedDB) { - return { - mongoDriver, - mongod - }; - } - - - if (random) { - for (let i = 1; i <= 100; i++) { - const fromUser = pickRandom('user'); - let toUser = pickRandom('user') - while (fromUser === toUser) { - toUser = pickRandom('user') - } - - const typeBurrito = TYPES[Math.floor(Math.random() * TYPES.length)] - switch (typeBurrito) { - case 'give': - await give(toUser, fromUser, pickRandomDate(oneWeek, today)); - break; - case 'takeaway': - await takeaway(toUser, fromUser, pickRandomDate(oneWeek, today)) - break; - } - } - } else { - mockData.forEach(async (data) => { - const date = (data.date === 'random') ? pickRandomDate(oneWeek, yesterDay) : undefined; - switch (data.type) { - case 'inc': - await give(data.to, data.from, date); - break; - case 'dec': - await takeaway(data.to, data.from, date); - break; - } - }); - - } - return { - mongoDriver, - mongod - }; -} -export { - init, -} From c661044accefd8ad988415ecd681e2a4998f238c Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:31:29 +0100 Subject: [PATCH 13/51] new way to setup and test db --- test/lib/database/database-functions.ts | 18 +++++++++ test/lib/database/index.ts | 32 +++++++++++++++ test/lib/database/init-database-driver.ts | 47 +++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 test/lib/database/database-functions.ts create mode 100644 test/lib/database/index.ts create mode 100644 test/lib/database/init-database-driver.ts diff --git a/test/lib/database/database-functions.ts b/test/lib/database/database-functions.ts new file mode 100644 index 0000000..003086f --- /dev/null +++ b/test/lib/database/database-functions.ts @@ -0,0 +1,18 @@ +import { init } from './index'; + +let DBmongoDriver, DBmongod; + +export async function connectDB(driver) { + const { mongoDriver, mongod } = await init({ driver }); + if (mongod && mongoDriver) { + DBmongod = mongod + DBmongoDriver = mongoDriver + } +} + +export async function closeDB(driver) { + if (driver === 'mongodb') { + if (DBmongoDriver.client) await DBmongoDriver.client.close(); + if (DBmongod) await DBmongod.stop(); + } +} diff --git a/test/lib/database/index.ts b/test/lib/database/index.ts new file mode 100644 index 0000000..2f2cea7 --- /dev/null +++ b/test/lib/database/index.ts @@ -0,0 +1,32 @@ +import * as dotenv from 'dotenv'; +dotenv.config(); +import { initDatabase, seedDatabase } from './init-database-driver'; +import Localstore from '../../../src/store/LocalStore'; +import WBCHandler from '../../../src/slack/Wbc'; +import slack from '../../../src/slack'; + + +// await give(toUser, fromUser, pickRandomDate(oneWeek, today)); + +async function init({ driver }) { + + // Set and start slack services + const { wbc } = slack; + + let SLACKUSERS = [] + + await WBCHandler.register(wbc); + await Localstore.fetch(); + const users = await Localstore.getSlackUsers(); + SLACKUSERS = users.map(x => x.id) + + + const { database, ...rest } = await initDatabase({ driver }); + await seedDatabase(database); + return { + ...rest + }; +} +export { + init, +} diff --git a/test/lib/database/init-database-driver.ts b/test/lib/database/init-database-driver.ts new file mode 100644 index 0000000..ad826d8 --- /dev/null +++ b/test/lib/database/init-database-driver.ts @@ -0,0 +1,47 @@ +import * as dotenv from 'dotenv'; +dotenv.config(); +import fs from 'fs'; +import { MongoMemoryServer } from 'mongodb-memory-server'; +import BurritoStore from '../../../src/store/BurritoStore'; +import { env } from '../../../src/lib/utils/env'; +import config from '../../../src/config'; +import { pathExists, createPath } from '../../../src/lib/utils/path'; +import databaseDrivers from '../../../src/database/drivers'; +import { scoreBoard } from '../../data/calculatescore-data'; +import { randomDate } from '../time' + +// await give(toUser, fromUser, pickRandomDate(oneWeek, today)); + +export const initDatabase = async ({ driver }) => { + + if (env === 'testing' && driver === 'file') { + if (!pathExists(config.db.db_path)) { + if (!createPath(config.db.db_path)) { + throw new Error('Could not create database path'); + } + } + try { + fs.unlinkSync(`${config.db.db_path}${config.db.db_fileName}`); + } + catch (e) { + } + }; + + if (env === 'testing' && driver === 'mongodb') { + // let mongod = new MongoMemoryServer(); + // const uri = await mongod.getConnectionString(); + // const database = await mongod.getDbName(); + // const mongoDriver = databaseDrivers[driver]({ db_uri: uri, db_name: database }); + // BurritoStore.setDatabase(mongoDriver); + } else { + const database = databaseDrivers[driver](); + BurritoStore.setDatabase(database); + return Promise.resolve({ driver, database, mongod: false, mongoDriver: false }); + } +} + +export const seedDatabase = async (database) => { + scoreBoard.forEach(async ({ to, from, value }) => { + await database.give({ to, from, value, given_at: randomDate() }); + }) +}; From d529364499e6da939f5021b22323b66a707bb96b Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:31:46 +0100 Subject: [PATCH 14/51] as seperat file --- test/lib/time.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 test/lib/time.ts diff --git a/test/lib/time.ts b/test/lib/time.ts new file mode 100644 index 0000000..6837f21 --- /dev/null +++ b/test/lib/time.ts @@ -0,0 +1,9 @@ +const today = new Date(); +const yesterDay = new Date(today); +const oneWeek = new Date(today); +yesterDay.setDate(yesterDay.getDate() - 1); +oneWeek.setDate(today.getDate() - 7); + +export const randomDate = (start = oneWeek, end = today) => { + return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); +} From efd3ad51e95afa2d1b8e8cbef9acf0c8f1c7fe6d Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:32:09 +0100 Subject: [PATCH 15/51] lint --- src/web/index.ts | 92 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/web/index.ts b/src/web/index.ts index 60faaac..f45666e 100644 --- a/src/web/index.ts +++ b/src/web/index.ts @@ -10,59 +10,59 @@ const publicPath: string = config.theme.themePath; const libPath: string = path.normalize('./www/lib/'); export default (request: http.IncomingMessage, response: http.ServerResponse) => { - let urlReplaced: string = request.url.replace(defaultUrlPath, ''); - let filePath: string = publicPath + urlReplaced; + let urlReplaced: string = request.url.replace(defaultUrlPath, ''); + let filePath: string = publicPath + urlReplaced; - if (!urlReplaced) urlReplaced = '/'; + if (!urlReplaced) urlReplaced = '/'; - if (urlReplaced === '/') filePath += 'index.html'; + if (urlReplaced === '/') filePath += 'index.html'; - const extname = String(path.extname(filePath)).toLowerCase(); + const extname = String(path.extname(filePath)).toLowerCase(); - const mimeTypes: object = { - '.html': 'text/html', - '.js': 'text/javascript', - '.css': 'text/css', - '.json': 'application/json', - '.png': 'image/png', - '.ico': 'image/x-icon', - '.jpg': 'image/jpg', - }; + const mimeTypes: object = { + '.html': 'text/html', + '.js': 'text/javascript', + '.css': 'text/css', + '.json': 'application/json', + '.png': 'image/png', + '.ico': 'image/x-icon', + '.jpg': 'image/jpg', + }; - const contentType: string = mimeTypes[extname] || 'application/octet-stream'; + const contentType: string = mimeTypes[extname] || 'application/octet-stream'; - if (contentType.startsWith('image')) { - fs.readFile(filePath, (err, content) => { - if (!err) { - response.writeHead(200, { 'Content-type': contentType }); - response.end(content, 'utf-8'); - } - }); + if (contentType.startsWith('image')) { + fs.readFile(filePath, (err, content) => { + if (!err) { + response.writeHead(200, { 'Content-type': contentType }); + response.end(content, 'utf-8'); + } + }); - } else { - fs.readFile(filePath, 'utf-8', (error: any, content: any) => { - if (error) { - if (error.code === 'ENOENT') { - fs.readFile(`${publicPath}404.html`, (err: any, cont: any) => { - if (err) log.warn('No 404 page found'); - response.writeHead(200, { 'Content-Type': 'text/html' }); - response.end(cont, 'utf-8'); - }); - } else { - response.writeHead(500); - response.end(`Sorry, check with the site admin for error: ${error.code} ..\n`); - response.end(); - } - } else { - if (contentType === 'text/html') { - const js: string = fs.readFileSync(`${libPath}Hey.js`, 'utf-8'); - content = content.replace('', ``); - } - response.writeHead(200, { 'Content-Type': contentType }); - response.end(content, 'utf-8'); - } - }); - } + } else { + fs.readFile(filePath, 'utf-8', (error: any, content: any) => { + if (error) { + if (error.code === 'ENOENT') { + fs.readFile(`${publicPath}404.html`, (err: any, cont: any) => { + if (err) log.warn('No 404 page found'); + response.writeHead(200, { 'Content-Type': 'text/html' }); + response.end(cont, 'utf-8'); + }); + } else { + response.writeHead(500); + response.end(`Sorry, check with the site admin for error: ${error.code} ..\n`); + response.end(); + } + } else { + if (contentType === 'text/html') { + const js: string = fs.readFileSync(`${libPath}Hey.js`, 'utf-8'); + content = content.replace('', ``); + } + response.writeHead(200, { 'Content-Type': contentType }); + response.end(content, 'utf-8'); + } + }); + } }; From 879debdb751fdea9680b96cd37d1b2f6ac002bfd Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:32:46 +0100 Subject: [PATCH 16/51] remove throw --- src/lib/utils/path.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/utils/path.ts b/src/lib/utils/path.ts index 379b2d2..d61c3a3 100644 --- a/src/lib/utils/path.ts +++ b/src/lib/utils/path.ts @@ -24,7 +24,6 @@ export const createPath = (inPath: string) => { fs.mkdirSync(inPath); const exists = pathExists(inPath); if (exists) return true; - throw new Error('Neit'); } catch (e) { log.debug(`Could not create path ${inPath}`); return false; From bd6b8cde2e574090cf01a293cf6d85f8ae72cca8 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:33:58 +0100 Subject: [PATCH 17/51] lint --- src/slack/Rtm.ts | 52 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/slack/Rtm.ts b/src/slack/Rtm.ts index a14b202..8c9360b 100644 --- a/src/slack/Rtm.ts +++ b/src/slack/Rtm.ts @@ -2,37 +2,37 @@ import log from 'loglevel'; import { EventEmitter } from 'events'; interface SlackEvent { - type: string; - text: string; - user: string; - client_msg_id?: string; - suppress_notification?: boolean; - team?: string; - channel?: string, - event_ts?: string; - ts?: string; - subtype?: string; + type: string; + text: string; + user: string; + client_msg_id?: string; + suppress_notification?: boolean; + team?: string; + channel?: string, + event_ts?: string; + ts?: string; + subtype?: string; } class Rtm extends EventEmitter { - rtm: any; + rtm: any; - register(rtm: any) { - this.rtm = rtm; - this.listener(); - } + register(rtm: any) { + this.rtm = rtm; + this.listener(); + } - listener(): void { - log.info('Listening on slack messages'); - this.rtm.on('message', (event: SlackEvent) => { - if ((!!event.subtype) && (event.subtype === 'channel_join')) { - log.info('Joined channel', event.channel); - } - if (event.type === 'message') { - this.emit('slackMessage', event); - } - }); - } + listener(): void { + log.info('Listening on slack messages'); + this.rtm.on('message', (event: SlackEvent) => { + if ((!!event.subtype) && (event.subtype === 'channel_join')) { + log.info('Joined channel', event.channel); + } + if (event.type === 'message') { + this.emit('slackMessage', event); + } + }); + } } export default new Rtm(); From bccf9aeba20b76e87d8b4f1ba76c6d2cf15481b3 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:34:28 +0100 Subject: [PATCH 18/51] update of conf --- src/config/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/config/index.ts b/src/config/index.ts index 883d40b..23b2822 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -130,9 +130,12 @@ const config = { emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), - dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5000), - dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5000), + dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), + dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), + overdrawCap: getBool(process.env.ENABLE_OVERDRAW, false) ? getNum(process.env.SLACK_OVERDRAW_CAP, 5) : 0, + enableOverDraw: getBool(process.env.ENABLE_OVERDRAW, false), + }, http: { http_port: process.env.HTTP_PORT || 3333, @@ -154,6 +157,7 @@ const config = { }, misc: { slackMock: true, + log_level: process.env.LOG_LEVEL || 'debug' }, }, }; From 64c530a1780814e7e3dcbc8f5c0ca67c20809885 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:34:47 +0100 Subject: [PATCH 19/51] remove interface --- src/store/BurritoStore.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index b7079ae..627465a 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -8,13 +8,6 @@ import Driver, { DatabasePost, } from '../database/drivers/Driver'; - -interface CalucateUserScore { - listType?: string; - scoreType?: string; - user?: string; -} - interface GetUserStats { _id: string; received: number; From 1dfd98750e7c88ff1abeacf51a19637a2a67902f Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 15:35:04 +0100 Subject: [PATCH 20/51] update --- src/handleBurritos.ts | 30 +++++++------- test/burritostore.ts | 6 +-- test/handleBurritos.test.ts | 78 +++++++++++++------------------------ 3 files changed, 48 insertions(+), 66 deletions(-) diff --git a/src/handleBurritos.ts b/src/handleBurritos.ts index 95d92c9..c1e53a0 100644 --- a/src/handleBurritos.ts +++ b/src/handleBurritos.ts @@ -18,24 +18,31 @@ interface Updates { overdrawn?: boolean; } +const _give = async ({ giver, username, burritoType, overdrawn }: any) => { + return await BurritoStore.give({ + to: username, + from: giver, + type: burritoType, + overdrawn: !!overdrawn + }); +}; const giveBurritos = async (giver: string, updates: Updates[]) => { return updates.reduce(async (prev: any, burrito) => { return prev.then(async () => { - if (burrito.burritoType === 'inc') { - await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); - } else if (burrito.burritoType === 'dec') { - if (enableDecrement) { - const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'dec'); - } else { - await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); - } - } + if (burrito.burritoType === 'inc') return await _give({ giver, ...burrito }) + if (burrito.burritoType === 'dec' && !enableDecrement) return await _give({ giver, ...burrito }) + + // receiver can not have less then 0 score + const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'dec'); + }); }, Promise.resolve()); }; const handleUpdates = async (giver: string, updates: Updates[], scoreType: string) => { + const { enableDecrement, enableOverDraw } = config.slack; + log.debug("handleUpdates => scoreType => ", scoreType); log.debug("handleUpdates => enableOverDraw => ", enableOverDraw); log.debug("handleUpdates => enableDecrement => ", enableDecrement); @@ -46,19 +53,15 @@ const handleUpdates = async (giver: string, updates: Updates[], scoreType: strin log.debug("handleUpdates => args => updates => ", updates); log.debug("handleUpdates => args => scoreType: => ", scoreType); - const burritoType = (scoreType === 'inc') ? 'burrito' : 'rottenburrito'; const cap = (scoreType === 'inc') ? dailyCap : dailyDecCap; // GivenToday const GT = await BurritoStore.givenToday(giver, 'from', scoreType); - // GivenToday Overdrawn const GTO = await BurritoStore.givenToday(giver, 'from', scoreType, true); - // Total Given today const TGT = GT + GTO; - const dailyDiff = cap - GT; const dailyDiffTotal = cap + overdrawCap - TGT; @@ -94,6 +97,7 @@ const handleUpdates = async (giver: string, updates: Updates[], scoreType: strin }; export const handleBurritos = async (giver: string, updates: Updates[]) => { + const { enableDecrement } = config.slack; /** * We want to handle burritos differently depending on ENVs. diff --git a/test/burritostore.ts b/test/burritostore.ts index dacaa00..e5df61a 100644 --- a/test/burritostore.ts +++ b/test/burritostore.ts @@ -1,5 +1,5 @@ import BurritoStore from '../src/store/BurritoStore'; -import { init } from './lib/seedDatabase'; +import { init } from './lib/database'; let mongod: any, mongoDriver: any; @@ -22,8 +22,8 @@ describe('Burritostore-test', () => { describe(test.describe, () => { - async function connectDB(seedDB = false) { - const dbinit: any = await init({ driver: test.driver, random: false, seedDB }); + async function connectDB() { + const dbinit: any = await init({ driver: test.driver }); if (dbinit.mongod && dbinit.mongoDriver) { mongod = dbinit.mongod mongoDriver = dbinit.mongoDriver diff --git a/test/handleBurritos.test.ts b/test/handleBurritos.test.ts index 3cdbf5d..2960910 100644 --- a/test/handleBurritos.test.ts +++ b/test/handleBurritos.test.ts @@ -1,7 +1,9 @@ -import { init } from './lib/seedDatabase'; +import { init } from './lib/database'; import { handleBurritos } from '../src/handleBurritos'; import * as config from '../src/config'; -let mongod: any, mongoDriver: any; +import { connectDB, closeDB } from './lib/database/database-functions'; + +// let DBmongod: any, DBmongoDriver: any; describe('handleBurritos-test', () => { [ @@ -9,44 +11,19 @@ describe('handleBurritos-test', () => { // describe: 'file Driver', // driver: 'file' // }, - { - describe: 'Array Driver', - driver: 'array' - }, // { + // describe: 'Array Driver', + // driver: 'array' + // }, + // // // { // describe: 'Mongodb Driver', // driver: 'mongodb' // }, ].forEach((test) => { describe(test.describe, () => { - async function connectDB(seedDB = false) { - const dbinit: any = await init({ driver: test.driver, random: false, seedDB }); - if (dbinit.mongod && dbinit.mongoDriver) { - mongod = dbinit.mongod - mongoDriver = dbinit.mongoDriver - } - } - - async function closeDB() { - if (test.driver === 'mongodb') { - if (mongoDriver.client) await mongoDriver.client.close(); - if (mongod) await mongod.stop(); - } - } - - beforeAll(async () => { - await connectDB() - - }); - - afterAll(async () => { - await closeDB() - }); - - - - + beforeAll(async () => await connectDB(test.driver)); + afterAll(async () => await closeDB(test.driver)); describe('USER1 should give USER2 5 burritos', () => { it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { @@ -56,28 +33,29 @@ describe('handleBurritos-test', () => { { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }]; await handleBurritos('USER1', updates) }); }); - describe('USER1 should NOT give USER2 5 burritos', () => { - it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { - config.default.slack = { enableOverDraw: true, enableDecrement: false } - const updates = [ - { username: 'USER1', burritoType: 'inc' }, - { username: 'USER1', burritoType: 'inc' }, - { username: 'USER1', burritoType: 'inc' }, - { username: 'USER1', burritoType: 'inc' }, - { username: 'USER1', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }]; - await handleBurritos('USER2', updates) - }); - }); + // describe('USER1 should NOT give USER2 5 burritos', () => { + // it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { + // config.default.slack = { enableOverDraw: true, enableDecrement: false } + // const updates = [ + // { username: 'USER1', burritoType: 'inc' }, + // { username: 'USER1', burritoType: 'inc' }, + // { username: 'USER1', burritoType: 'inc' }, + // { username: 'USER1', burritoType: 'inc' }, + // { username: 'USER1', burritoType: 'inc' }, + // { username: 'USER2', burritoType: 'inc' }, + // { username: 'USER2', burritoType: 'inc' }, + // { username: 'USER2', burritoType: 'inc' }, + // { username: 'USER2', burritoType: 'inc' }, + // { username: 'USER2', burritoType: 'inc' }]; + // await handleBurritos('USER2', updates) + // }); + // }); From 1b552b7de034c66bfb70b3bae83068eff649c0b4 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Tue, 1 Feb 2022 20:18:20 +0100 Subject: [PATCH 21/51] update --- src/handleBurritos.ts | 44 ++++----- src/slack/index.ts | 5 +- src/store/BurritoStore.ts | 4 +- test/data/{mockData.json => _mockData.json} | 0 test/data/slackUsers.ts | 1 - test/handleBurritos.test.ts | 99 +++++++++++++++------ test/lib/database/index.ts | 17 ---- test/lib/slack/index.ts | 12 +++ test/lib/slack/slack-mock.ts | 28 ++++++ test/lib/slackMock.ts | 27 ------ test/lib/time.ts | 15 ++-- test/mapper.test.ts | 8 +- test/{wbc.test.ts => wbc.ts} | 6 +- 13 files changed, 155 insertions(+), 111 deletions(-) rename test/data/{mockData.json => _mockData.json} (100%) create mode 100644 test/lib/slack/index.ts create mode 100644 test/lib/slack/slack-mock.ts delete mode 100644 test/lib/slackMock.ts rename test/{wbc.test.ts => wbc.ts} (77%) diff --git a/src/handleBurritos.ts b/src/handleBurritos.ts index c1e53a0..d493e59 100644 --- a/src/handleBurritos.ts +++ b/src/handleBurritos.ts @@ -18,31 +18,32 @@ interface Updates { overdrawn?: boolean; } -const _give = async ({ giver, username, burritoType, overdrawn }: any) => { - return await BurritoStore.give({ - to: username, - from: giver, - type: burritoType, - overdrawn: !!overdrawn - }); -}; - const giveBurritos = async (giver: string, updates: Updates[]) => { + const { enableDecrement } = config.slack; return updates.reduce(async (prev: any, burrito) => { return prev.then(async () => { - if (burrito.burritoType === 'inc') return await _give({ giver, ...burrito }) - if (burrito.burritoType === 'dec' && !enableDecrement) return await _give({ giver, ...burrito }) - - // receiver can not have less then 0 score - const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'dec'); - + console.log(burrito) + if (burrito.burritoType === 'inc') { + return await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); + } else if (burrito.burritoType === 'dec') { + console.log(enableDecrement) + if (enableDecrement) { + const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'dec'); + } else { + console.log("JAAAAAAAAAAAAAAAaa") + await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); + } + } }); }, Promise.resolve()); }; + const handleUpdates = async (giver: string, updates: Updates[], scoreType: string) => { const { enableDecrement, enableOverDraw } = config.slack; - + console.log("updates", updates) + console.log("dailyDecCap", dailyDecCap) + console.log("overdrawCap", overdrawCap) log.debug("handleUpdates => scoreType => ", scoreType); log.debug("handleUpdates => enableOverDraw => ", enableOverDraw); log.debug("handleUpdates => enableDecrement => ", enableDecrement); @@ -67,30 +68,34 @@ const handleUpdates = async (giver: string, updates: Updates[], scoreType: strin // Send right total in message, so we dont send - if overdrawn was disabled the same day. const messTotal = enableOverDraw ? dailyDiffTotal : dailyDiff; - + console.log(!(dailyDiffTotal >= updates.length)) + console.log("dailyDiffTotal", dailyDiffTotal) // Check if user can send all updates. if(!(dailyDiffTotal >= updates.length)) return notifyUser(giver, `You are trying to give away ${updates.length} ${burritoType}, but you only have ${messTotal} ${burritoType} left today!`); // Check if update.length exceeds dailyDiff if(!(dailyDiff >= updates.length)) { - + console.log("AHA?") /** * When overdraw we want to do a credit check of giver first. * Giver needs to be able to pay the bill. * ( Lowest userScore can be 0 ) */ const giverScore = await BurritoStore.getUserScore(giver, 'to', scoreType); if (!(giverScore >= updates.length)) return notifyUser(giver, `Trying to give more ${burritoType}s then u have`); + console.log("AHA?2") + } /** * We want to first handle the all the updates that we can as daily given ( from dailyCap ). * So we need to slice out the entries that we want to count as daily. */ const countAsDaily = updates.slice(0, dailyDiff); + console.log("countAsDaily", countAsDaily) if (countAsDaily.length) await giveBurritos(giver, countAsDaily); // Get the rest entries and count them as overDrawn const overDrawnUpdates = updates.slice(dailyDiff); - + console.log("overDrawnUpdates", overDrawnUpdates) // When overdraw we want to add type overdrawn const updatesOverDrawn = overDrawnUpdates.map(({ ...all }) => ({ ...all, overdrawn: true })); return await giveBurritos(giver, updatesOverDrawn); @@ -116,7 +121,6 @@ export const handleBurritos = async (giver: string, updates: Updates[]) => { const incUpdates = updates.filter((x) => x.burritoType === 'inc'); const decUpdates = updates.filter((x) => x.burritoType === 'dec'); - if (incUpdates.length) await handleUpdates(giver, incUpdates, 'inc'); if (decUpdates.length) await handleUpdates(giver, decUpdates, 'dec'); diff --git a/src/slack/index.ts b/src/slack/index.ts index fe2342f..8b9c270 100644 --- a/src/slack/index.ts +++ b/src/slack/index.ts @@ -1,14 +1,13 @@ import log from 'loglevel'; import { WebClient } from '@slack/web-api'; import { RTMClient } from '@slack/rtm-api'; -import { RTMMock, WebMock } from '../../test/lib/slackMock'; +import { RTMMock, WEBMock } from '../../test/lib/slack/slack-mock'; import config from '../config'; const { slackMock } = config.misc; - log.info('Slack mockApi loaded', slackMock); export default { rtm: slackMock ? new RTMMock() : new RTMClient(config.slack.api_token), - wbc: slackMock ? new WebMock() : new WebClient(config.slack.api_token), + wbc: slackMock ? new WEBMock() : new WebClient(config.slack.api_token), }; diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 627465a..974169f 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -41,6 +41,7 @@ class BurritoStore extends EventEmitter { overdrawn, }; + console.log("SCORE", score) await this.database.give(score); if (type === 'inc') { @@ -87,7 +88,7 @@ class BurritoStore extends EventEmitter { const givenToday = await this.database.findFromToday(user, listType); if (scoreType && ['inc', 'dec'].includes(scoreType)) { const scoreTypeFilter = (scoreType === 'inc') ? 1 : -1; - + //console.log(listType, scoreType,givenToday) const givenFilter = givenToday.filter((x) => { if (x.value === scoreTypeFilter) { if(overdrawn) return !!x.overdrawn @@ -106,7 +107,6 @@ class BurritoStore extends EventEmitter { public async getUserScore(user: string, listType: string, scoreType: string): Promise { const { enableDecrement, enableOverDraw } = config.slack - console.log("INSIDE", enableOverDraw, enableDecrement) // Get users score from DB, ( Only all inc not calculated with dec or overdrwan) const _data = await this.database.getScore(user, listType); if (enableOverDraw) { diff --git a/test/data/mockData.json b/test/data/_mockData.json similarity index 100% rename from test/data/mockData.json rename to test/data/_mockData.json diff --git a/test/data/slackUsers.ts b/test/data/slackUsers.ts index 0d312f9..d2feda4 100644 --- a/test/data/slackUsers.ts +++ b/test/data/slackUsers.ts @@ -166,7 +166,6 @@ const wbcList = { "is_app_user": false, "updated": 1543910803 }, - { "id": "USER7", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER8", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER9", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER10", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER11", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER12", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER13", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER14", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER15", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER16", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER17", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER18", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER19", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER20", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER21", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER22", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER23", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER24", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER25", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER26", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER27", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER28", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER29", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER30", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER31", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER32", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER33", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER34", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER35", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER36", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER37", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER38", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER39", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER40", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER41", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER42", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER43", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER44", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER45", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER46", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER47", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER48", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER49", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "USER50", "team_id": "TEAMBURRITO", "name": "User numero uno", "deleted": false, "color": "4bbe2e", "real_name": "User1", "tz": "Europe/Amsterdam", "tz_label": "Central European Time", "tz_offset": 3600, "profile": { "title": "", "phone": "", "skype": "", "real_name": "User numero uno", "real_name_normalized": "Numero Uno", "display_name": "", "display_name_normalized": "", "status_text": "", "status_emoji": "", "status_expiration": 0, "avatar_hash": "avatarohasho", "email": "uno@hey.burrito", "image_24": "https://link.to.avatar.24.burrito", "image_32": "https://link.to.avatar.32.burrito", "image_48": "https://link.to.avatar.48.burrito", "image_72": "https://link.to.avatar.72.burrito", "image_192": "https://link.to.avatar.192.burrito", "image_512": "https://link.to.avatar.512.burrito", "status_text_canonical": "", "team": "TEAMBURRITO" }, "is_admin": false, "is_owner": false, "is_primary_owner": false, "is_restricted": false, "is_ultra_restricted": false, "is_bot": false, "is_app_user": false, "updated": 1543910803 }, { "id": "BURRITOBOT", "team_id": "TEAMBURRITO", diff --git a/test/handleBurritos.test.ts b/test/handleBurritos.test.ts index 2960910..91fa096 100644 --- a/test/handleBurritos.test.ts +++ b/test/handleBurritos.test.ts @@ -1,31 +1,60 @@ import { init } from './lib/database'; import { handleBurritos } from '../src/handleBurritos'; +import BurritoStore from '../src/store/BurritoStore'; import * as config from '../src/config'; import { connectDB, closeDB } from './lib/database/database-functions'; +import { notifyUser } from '../src/bot'; +import { initSlack } from './lib/slack'; +initSlack() // let DBmongod: any, DBmongoDriver: any; describe('handleBurritos-test', () => { [ - // { - // describe: 'file Driver', - // driver: 'file' - // }, - // { + { + describe: 'file Driver', + driver: 'file' + }, +// { // describe: 'Array Driver', // driver: 'array' // }, - // // // { + // // { // describe: 'Mongodb Driver', // driver: 'mongodb' // }, ].forEach((test) => { describe(test.describe, () => { - beforeAll(async () => await connectDB(test.driver)); - afterAll(async () => await closeDB(test.driver)); + beforeEach(async () => { + //await + await connectDB(test.driver) + }); + afterEach(async () => await closeDB(test.driver)); - describe('USER1 should give USER2 5 burritos', () => { + describe('USER1 should give USER2 5inc and 5dec', () => { + it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const updates = [ + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }]; + await handleBurritos('USER1', updates) + const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); + const giverDataDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); + expect(giverDataInc).toEqual(5) + expect(giverDataDec).toEqual(5) + }); + }); + + describe('USER1 should not be able to give USER2 6inc ( CAP 5 )', () => { it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const updates = [ @@ -36,28 +65,46 @@ describe('handleBurritos-test', () => { { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }]; await handleBurritos('USER1', updates) + const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); + expect(giverDataInc).toEqual(0) + }); + }); + + + describe('USER1 should not be able to give USER2 6 dec ( CAP 5 )', () => { + it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: false } + const updates = [ + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' },]; + await handleBurritos('USER1', updates) + const giverDataDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); + expect(giverDataDec).toEqual(0) }); }); - // describe('USER1 should NOT give USER2 5 burritos', () => { - // it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { - // config.default.slack = { enableOverDraw: true, enableDecrement: false } - // const updates = [ - // { username: 'USER1', burritoType: 'inc' }, - // { username: 'USER1', burritoType: 'inc' }, - // { username: 'USER1', burritoType: 'inc' }, - // { username: 'USER1', burritoType: 'inc' }, - // { username: 'USER1', burritoType: 'inc' }, - // { username: 'USER2', burritoType: 'inc' }, - // { username: 'USER2', burritoType: 'inc' }, - // { username: 'USER2', burritoType: 'inc' }, - // { username: 'USER2', burritoType: 'inc' }, - // { username: 'USER2', burritoType: 'inc' }]; - // await handleBurritos('USER2', updates) - // }); - // }); + describe('USER1 should not be able to give USER2 3 dec 3inc ( CAP 5 )', () => { + it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const updates = [ + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + ]; + await handleBurritos('USER1', updates) + const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); + expect(giverDataInc).toEqual(0) + }); + }); }); }); diff --git a/test/lib/database/index.ts b/test/lib/database/index.ts index 2f2cea7..adea9d5 100644 --- a/test/lib/database/index.ts +++ b/test/lib/database/index.ts @@ -1,26 +1,9 @@ import * as dotenv from 'dotenv'; dotenv.config(); import { initDatabase, seedDatabase } from './init-database-driver'; -import Localstore from '../../../src/store/LocalStore'; -import WBCHandler from '../../../src/slack/Wbc'; -import slack from '../../../src/slack'; - - -// await give(toUser, fromUser, pickRandomDate(oneWeek, today)); async function init({ driver }) { - // Set and start slack services - const { wbc } = slack; - - let SLACKUSERS = [] - - await WBCHandler.register(wbc); - await Localstore.fetch(); - const users = await Localstore.getSlackUsers(); - SLACKUSERS = users.map(x => x.id) - - const { database, ...rest } = await initDatabase({ driver }); await seedDatabase(database); return { diff --git a/test/lib/slack/index.ts b/test/lib/slack/index.ts new file mode 100644 index 0000000..6904eb5 --- /dev/null +++ b/test/lib/slack/index.ts @@ -0,0 +1,12 @@ +import slack from '../../../src/slack'; +import WBCHandler from '../../../src/slack/Wbc'; +import Localstore from '../../../src/store/LocalStore'; + +export const initSlack = async () => { + // Set and start slack services + const { wbc } = slack; + + WBCHandler.register(wbc); + await Localstore.fetch(); + await Localstore.getSlackUsers(); +} diff --git a/test/lib/slack/slack-mock.ts b/test/lib/slack/slack-mock.ts new file mode 100644 index 0000000..ff57ab4 --- /dev/null +++ b/test/lib/slack/slack-mock.ts @@ -0,0 +1,28 @@ +import { wbcList } from '../../data/slackUsers' +import { EventEmitter } from 'events'; + +export class RTMMock extends EventEmitter { + + start() { + return Promise.resolve(true); + } + + // Function to test emits + async publish(message: any) { + this.emit('message', message); + } +} + +export class WEBMock { + users = { + list: () => { + return Promise.resolve(wbcList) + } + }; + + chat = { + postMessage: (data) => { + return Promise.resolve(data) + } + }; +} diff --git a/test/lib/slackMock.ts b/test/lib/slackMock.ts deleted file mode 100644 index 0ebb284..0000000 --- a/test/lib/slackMock.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { wbcList } from '../data/slackUsers' -import { EventEmitter } from 'events'; - -class RTMMock extends EventEmitter { - - start() { - return Promise.resolve(true); - } - - // Function to test emits - async publish(message: any) { - this.emit('message', message); - } -} - -class WebMock { - users = { - list: function() { - return Promise.resolve(wbcList) - } - } -} - -export { - RTMMock, - WebMock -} diff --git a/test/lib/time.ts b/test/lib/time.ts index 6837f21..e091a9c 100644 --- a/test/lib/time.ts +++ b/test/lib/time.ts @@ -1,9 +1,10 @@ -const today = new Date(); -const yesterDay = new Date(today); -const oneWeek = new Date(today); -yesterDay.setDate(yesterDay.getDate() - 1); -oneWeek.setDate(today.getDate() - 7); -export const randomDate = (start = oneWeek, end = today) => { - return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); +export const randomDate = () => { + const today = new Date(); + const yesterDay = new Date(today); + const oneWeek = new Date(today); + yesterDay.setDate(yesterDay.getDate() - 1); + oneWeek.setDate(today.getDate() - 7); + const time = new Date(oneWeek.getTime() + Math.random() * (today.getTime() - oneWeek.getTime())); + return oneWeek; } diff --git a/test/mapper.test.ts b/test/mapper.test.ts index ee17853..55373df 100644 --- a/test/mapper.test.ts +++ b/test/mapper.test.ts @@ -1,14 +1,12 @@ import dotenv from 'dotenv'; dotenv.config(); -import { init } from './lib/seedDatabase'; import mapper from '../src/lib/mapper'; - -beforeEach(async () => { - await init({ random: false, seedDB: false }); -}); +import { initSlack } from './lib/slack'; describe('/src/lib/mapper', () => { + beforeAll(async () => await initSlack()); + it('Should map USER2 with data from LocalStore', async () => { const result = mapper([{ _id: 'USER2', score: 10 }]) expect(result).toEqual([ diff --git a/test/wbc.test.ts b/test/wbc.ts similarity index 77% rename from test/wbc.test.ts rename to test/wbc.ts index dd0b4f7..d003ead 100644 --- a/test/wbc.test.ts +++ b/test/wbc.ts @@ -1,11 +1,11 @@ -import { WebMock } from './lib/slackMock' +import { WebMock } from './lib/slack/slack-mock'; import WBCHandler from '../src/slack/Wbc'; import { wbcListParsed } from './data/slackUsers'; let wbc: any beforeEach(() => { - wbc = new WebMock(); - WBCHandler.register(wbc); + wbc = new WebMock(); + WBCHandler.register(wbc); }) describe('Wbc-test', () => { From a257449185e930f2ce63a19b469bed664ce10e84 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Wed, 2 Feb 2022 13:42:59 +0100 Subject: [PATCH 22/51] update --- src/database/drivers/GenericDriver.ts | 6 +- src/handleBurritos.ts | 35 ++++---- src/store/BurritoStore.ts | 13 +-- test/handleBurritos.test.ts | 97 ++++++++++++++++++++--- test/lib/database/init-database-driver.ts | 4 +- 5 files changed, 112 insertions(+), 43 deletions(-) diff --git a/src/database/drivers/GenericDriver.ts b/src/database/drivers/GenericDriver.ts index 6ed578c..1ed429c 100644 --- a/src/database/drivers/GenericDriver.ts +++ b/src/database/drivers/GenericDriver.ts @@ -15,12 +15,10 @@ class GenericDriver extends Store implements Driver { }; async give({ ...score }: GivePost) { - //score._id = id(); - const hej = { + await this.storeData({ _id: id(), ...score - }; - await this.storeData(hej); + }); return Promise.resolve(true); } diff --git a/src/handleBurritos.ts b/src/handleBurritos.ts index d493e59..22af576 100644 --- a/src/handleBurritos.ts +++ b/src/handleBurritos.ts @@ -18,21 +18,28 @@ interface Updates { overdrawn?: boolean; } +const _give = async () => { }; + const giveBurritos = async (giver: string, updates: Updates[]) => { const { enableDecrement } = config.slack; return updates.reduce(async (prev: any, burrito) => { return prev.then(async () => { - console.log(burrito) - if (burrito.burritoType === 'inc') { - return await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); - } else if (burrito.burritoType === 'dec') { - console.log(enableDecrement) - if (enableDecrement) { - const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'dec'); - } else { - console.log("JAAAAAAAAAAAAAAAaa") - await BurritoStore.give({ to: burrito.username, from: giver, type: burrito.burritoType, overdrawn: !!burrito.overdrawn }); - } + if (burrito.burritoType === 'inc' || burrito.burritoType === 'dec' && !enableDecrement) { + return await BurritoStore.give({ + to: burrito.username, + from: giver, + type: burrito.burritoType, + overdrawn: !!burrito.overdrawn + }); + }; + const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'inc'); + if (receiverScore > 0) { + return await BurritoStore.give({ + to: burrito.username, + from: giver, + type: burrito.burritoType, + overdrawn: !!burrito.overdrawn + }); } }); }, Promise.resolve()); @@ -41,9 +48,6 @@ const giveBurritos = async (giver: string, updates: Updates[]) => { const handleUpdates = async (giver: string, updates: Updates[], scoreType: string) => { const { enableDecrement, enableOverDraw } = config.slack; - console.log("updates", updates) - console.log("dailyDecCap", dailyDecCap) - console.log("overdrawCap", overdrawCap) log.debug("handleUpdates => scoreType => ", scoreType); log.debug("handleUpdates => enableOverDraw => ", enableOverDraw); log.debug("handleUpdates => enableDecrement => ", enableDecrement); @@ -90,7 +94,6 @@ const handleUpdates = async (giver: string, updates: Updates[], scoreType: strin * We want to first handle the all the updates that we can as daily given ( from dailyCap ). * So we need to slice out the entries that we want to count as daily. */ const countAsDaily = updates.slice(0, dailyDiff); - console.log("countAsDaily", countAsDaily) if (countAsDaily.length) await giveBurritos(giver, countAsDaily); // Get the rest entries and count them as overDrawn @@ -113,9 +116,9 @@ export const handleBurritos = async (giver: string, updates: Updates[]) => { if (enableDecrement) { const givenToday = await BurritoStore.givenToday(giver, 'from'); const diff = dailyCap - givenToday; - if (updates.length > diff) return notifyUser(giver, `You are trying to give away ${updates.length} burritos, but you only have ${diff} burritos left today!`); if (givenToday >= dailyCap) return false; + await giveBurritos(giver, updates); } else { diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 974169f..398e0f7 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -41,7 +41,6 @@ class BurritoStore extends EventEmitter { overdrawn, }; - console.log("SCORE", score) await this.database.give(score); if (type === 'inc') { @@ -106,15 +105,11 @@ class BurritoStore extends EventEmitter { */ public async getUserScore(user: string, listType: string, scoreType: string): Promise { - const { enableDecrement, enableOverDraw } = config.slack + const { enableOverDraw } = config.slack // Get users score from DB, ( Only all inc not calculated with dec or overdrwan) - const _data = await this.database.getScore(user, listType); - if (enableOverDraw) { - const _dataSwitched = await this.database.getScore(user, listTypeSwitch(listType)); - const data = _dataSwitched.filter((entry) => (!!entry.overdrawn)); - return calculateScore(_data, [], { listType, scoreType, user }); - } - return calculateScore(_data, [], { listType, scoreType, user }); + const data = await this.database.getScore(user, listType); + const _data = enableOverDraw ? await this.database.getScore(user, listTypeSwitch(listType)) : []; + return calculateScore(data, _data, { listType, scoreType, user }); }; diff --git a/test/handleBurritos.test.ts b/test/handleBurritos.test.ts index 91fa096..64d6f20 100644 --- a/test/handleBurritos.test.ts +++ b/test/handleBurritos.test.ts @@ -34,7 +34,9 @@ describe('handleBurritos-test', () => { describe('USER1 should give USER2 5inc and 5dec', () => { it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { - config.default.slack = { enableOverDraw: false, enableDecrement: false } + config.default.slack = { enableOverDraw: false, enableDecrement: false }; + const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const updates = [ { username: 'USER2', burritoType: 'dec' }, { username: 'USER2', burritoType: 'dec' }, @@ -47,16 +49,23 @@ describe('handleBurritos-test', () => { { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }]; await handleBurritos('USER1', updates) + const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usAfterDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); const giverDataDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); - expect(giverDataInc).toEqual(5) - expect(giverDataDec).toEqual(5) + expect(usBeforeInc).toEqual(9); + expect(usBeforeDec).toEqual(4); + expect(usAfterInc).toEqual(14); + expect(usAfterDec).toEqual(9); + expect(giverDataInc).toEqual(5); + expect(giverDataDec).toEqual(5); }); }); describe('USER1 should not be able to give USER2 6inc ( CAP 5 )', () => { it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } + const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const updates = [ { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }, @@ -64,34 +73,71 @@ describe('handleBurritos-test', () => { { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }, { username: 'USER2', burritoType: 'inc' }]; - await handleBurritos('USER1', updates) + await handleBurritos('USER1', updates); + const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); - expect(giverDataInc).toEqual(0) + expect(usBeforeInc).toEqual(9); + expect(usAfterInc).toEqual(9); + expect(giverDataInc).toEqual(0); }); }); - describe('USER1 should not be able to give USER2 6 dec ( CAP 5 )', () => { it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } + const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const updates = [ { username: 'USER2', burritoType: 'dec' }, { username: 'USER2', burritoType: 'dec' }, { username: 'USER2', burritoType: 'dec' }, { username: 'USER2', burritoType: 'dec' }, { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' },]; + { username: 'USER2', burritoType: 'dec' }]; await handleBurritos('USER1', updates) + const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usAfterDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); + const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); const giverDataDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); - expect(giverDataDec).toEqual(0) + expect(usBeforeInc).toEqual(9); + expect(usBeforeDec).toEqual(4); + expect(usAfterInc).toEqual(9); + expect(usAfterDec).toEqual(4); + expect(giverDataInc).toEqual(0); + expect(giverDataDec).toEqual(0); }); }); - + describe('USER1 should give USER2 2 dec 3inc ( CAP 5 )', () => { + it(`with ENVS: { enableOverDraw: false, enableDecrement: true }`, async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true } + const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); + const updates = [ + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'dec' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }, + { username: 'USER2', burritoType: 'inc' }]; + await handleBurritos('USER1', updates) + const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); + const giverDataDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); + const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usAfterDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); + expect(usBeforeInc).toEqual(5); + expect(usBeforeDec).toEqual(4); + expect(usAfterInc).toEqual(6); + expect(usAfterDec).toEqual(6); + expect(giverDataInc).toEqual(3); + expect(giverDataDec).toEqual(2); + }); + }); describe('USER1 should not be able to give USER2 3 dec 3inc ( CAP 5 )', () => { - it(`with ENVS: { enableOverDraw: false, enableDecrement: false }`, async () => { - config.default.slack = { enableOverDraw: false, enableDecrement: true } + it(`with ENVS: { enableOverDraw: false, enableDecrement: true }`, async () => { + config.default.slack = { enableOverDraw: false, enableDecrement: true }; + const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const updates = [ { username: 'USER2', burritoType: 'dec' }, { username: 'USER2', burritoType: 'dec' }, @@ -102,10 +148,37 @@ describe('handleBurritos-test', () => { ]; await handleBurritos('USER1', updates) const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); - expect(giverDataInc).toEqual(0) + const giverDataDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); + const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); + const usAfterDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); + expect(usBeforeInc).toEqual(5); + expect(usBeforeDec).toEqual(4); + expect(usAfterInc).toEqual(5); + expect(usAfterDec).toEqual(4); + expect(giverDataInc).toEqual(0); + expect(giverDataDec).toEqual(0); }); }); + + + + + + + + + + + + + + + + + + + }); }); }); diff --git a/test/lib/database/init-database-driver.ts b/test/lib/database/init-database-driver.ts index ad826d8..89d0061 100644 --- a/test/lib/database/init-database-driver.ts +++ b/test/lib/database/init-database-driver.ts @@ -41,7 +41,7 @@ export const initDatabase = async ({ driver }) => { } export const seedDatabase = async (database) => { - scoreBoard.forEach(async ({ to, from, value }) => { - await database.give({ to, from, value, given_at: randomDate() }); + scoreBoard.forEach(async ({ to, from, value, overdrawn}) => { + await database.give({ to, from, value, given_at: randomDate(), overdrawn}); }) }; From 8e16d27ceb4ea73716035a9faf7a3db44798f3ee Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Wed, 2 Feb 2022 18:55:24 +0100 Subject: [PATCH 23/51] update --- src/bot.ts | 27 +++++- src/database/drivers.ts | 6 +- src/handleBurritos.ts | 48 ++++------- src/lib/parseMessage.ts | 20 +++-- src/lib/validator.ts | 2 +- src/types/Http.ts | 12 +-- src/types/Score.interface.ts | 12 +-- src/types/Slack.interface.ts | 140 +++++++++++++++---------------- src/types/User.interface.ts | 22 ++--- src/types/UserScore.interface.ts | 4 +- test/handleBurritos.test.ts | 66 +++++++-------- 11 files changed, 181 insertions(+), 178 deletions(-) diff --git a/src/bot.ts b/src/bot.ts index 1409df7..66b841a 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -6,21 +6,40 @@ import { emojis } from './lib/emojis'; import Rtm from './slack/Rtm'; import Wbc from './slack/Wbc'; + export const notifyUser = (user: string, message: string) => Wbc.sendDM(user, message); +export const start = () => Rtm.on('slackMessage', (event: any) => incomingMessage(event)); + export const incomingMessage = async (message) => { // If message not valid then dont process it if (!validMessage(message, emojis, LocalStore.getAllBots())) return false; // If botMention handle message seperate later on. No support today - if (validBotMention(message, LocalStore.botUserID())) return false; + if (validBotMention(message, LocalStore.botUserID())) { + return await handleBotInteraction(message); + } const result = parseMessage(message, emojis); if (result?.updates) { - const { giver, updates } = result; - await handleBurritos(giver, updates); + const { from, updates } = result; + await handleBurritos(from, updates); } }; -export const start = () => Rtm.on('slackMessage', (event: any) => incomingMessage(event)); + +const BOT_INTERACTIONS = [ + 'help', + 'stats', + 'emojis' +]; + +const handleBotInteraction = async(message) => { + + console.log(message) + const hits = BOT_INTERACTIONS.map((arg) => { + if(message.text.includes(arg)) return arg; + }).filter(s => s); + console.log(hits); +}; diff --git a/src/database/drivers.ts b/src/database/drivers.ts index bf872b2..eb6b6e8 100644 --- a/src/database/drivers.ts +++ b/src/database/drivers.ts @@ -4,7 +4,7 @@ import MongoDBDriver from './drivers/MongoDBDriver'; import GenericDriver from './drivers/GenericDriver'; export default { - mongodb: (conf = config.db) => new MongoDBDriver(MongoClient, conf), - array: () => new GenericDriver('array'), - file: () => new GenericDriver('file'), + mongodb: (conf = config.db) => new MongoDBDriver(MongoClient, conf), + array: () => new GenericDriver('array'), + file: () => new GenericDriver('file'), }; diff --git a/src/handleBurritos.ts b/src/handleBurritos.ts index 22af576..1fe7e6b 100644 --- a/src/handleBurritos.ts +++ b/src/handleBurritos.ts @@ -2,6 +2,7 @@ import log from 'loglevel'; import config from './config'; import BurritoStore from './store/BurritoStore'; import { notifyUser } from './bot'; +import { Updates, Update } from './lib/parseMessage'; const { enableDecrement, @@ -11,41 +12,22 @@ const { overdrawCap, } = config.slack; -interface Updates { - username: string; - burritoType: string; - type?: string; - overdrawn?: boolean; -} - -const _give = async () => { }; +const give = async (update: Updates) => { + return await BurritoStore.give(update); +}; -const giveBurritos = async (giver: string, updates: Updates[]) => { +const giveBurritos = async (updates: Updates[]) => { const { enableDecrement } = config.slack; - return updates.reduce(async (prev: any, burrito) => { + return updates.reduce(async (prev: any, { type, ...burrito }: Updates) => { return prev.then(async () => { - if (burrito.burritoType === 'inc' || burrito.burritoType === 'dec' && !enableDecrement) { - return await BurritoStore.give({ - to: burrito.username, - from: giver, - type: burrito.burritoType, - overdrawn: !!burrito.overdrawn - }); - }; - const receiverScore: number = await BurritoStore.getUserScore(burrito.username, 'to', 'inc'); - if (receiverScore > 0) { - return await BurritoStore.give({ - to: burrito.username, - from: giver, - type: burrito.burritoType, - overdrawn: !!burrito.overdrawn - }); - } + if (type === 'inc' || type === 'dec' && !enableDecrement) return await give({ ...burrito, type }); + + const receiverScore: number = await BurritoStore.getUserScore(burrito.to, 'to', 'inc'); + if (receiverScore > 0) return await give({ ...burrito, type }); }); }, Promise.resolve()); }; - const handleUpdates = async (giver: string, updates: Updates[], scoreType: string) => { const { enableDecrement, enableOverDraw } = config.slack; log.debug("handleUpdates => scoreType => ", scoreType); @@ -94,14 +76,14 @@ const handleUpdates = async (giver: string, updates: Updates[], scoreType: strin * We want to first handle the all the updates that we can as daily given ( from dailyCap ). * So we need to slice out the entries that we want to count as daily. */ const countAsDaily = updates.slice(0, dailyDiff); - if (countAsDaily.length) await giveBurritos(giver, countAsDaily); + if (countAsDaily.length) await giveBurritos(countAsDaily); // Get the rest entries and count them as overDrawn const overDrawnUpdates = updates.slice(dailyDiff); console.log("overDrawnUpdates", overDrawnUpdates) // When overdraw we want to add type overdrawn const updatesOverDrawn = overDrawnUpdates.map(({ ...all }) => ({ ...all, overdrawn: true })); - return await giveBurritos(giver, updatesOverDrawn); + return await giveBurritos(updatesOverDrawn); }; export const handleBurritos = async (giver: string, updates: Updates[]) => { @@ -119,11 +101,11 @@ export const handleBurritos = async (giver: string, updates: Updates[]) => { if (updates.length > diff) return notifyUser(giver, `You are trying to give away ${updates.length} burritos, but you only have ${diff} burritos left today!`); if (givenToday >= dailyCap) return false; - await giveBurritos(giver, updates); + await giveBurritos(updates); } else { - const incUpdates = updates.filter((x) => x.burritoType === 'inc'); - const decUpdates = updates.filter((x) => x.burritoType === 'dec'); + const incUpdates = updates.filter(({ type }) => type === 'inc'); + const decUpdates = updates.filter(({ type }) => type === 'dec'); if (incUpdates.length) await handleUpdates(giver, incUpdates, 'inc'); if (decUpdates.length) await handleUpdates(giver, decUpdates, 'dec'); diff --git a/src/lib/parseMessage.ts b/src/lib/parseMessage.ts index 1c8b670..68046b1 100644 --- a/src/lib/parseMessage.ts +++ b/src/lib/parseMessage.ts @@ -2,14 +2,16 @@ import { Emojis } from './emojis'; const usernameRegex: RegExp = /(<@[A-Z0-9]{2,}>)/g; -interface Update { - username: string; - burritoType: string; +export interface Updates { + to: string; + from: string; + type: string; + overdrawn?: boolean; } -interface Updates { - giver?: string; - updates?: Update[] +export interface Update { + from?: string; + updates?: Updates[] } /** @@ -36,7 +38,7 @@ const parseUsernames = (text: string): string[] => { * - [ { username: 'USER2', type: 'inc' }, * { username: 'USER2', type: 'dec' } ] } */ -const parseMessage = (msg: any, emojis: Emojis[]): Updates => { +const parseMessage = (msg: any, emojis: Emojis[]): Update => { // Array containg data of whom to give / remove points from const updates = []; @@ -65,10 +67,10 @@ const parseMessage = (msg: any, emojis: Emojis[]): Updates => { if (!hits.length) return {}; // For each emojiHits give each user a update - hits.map((x) => users.forEach((u) => updates.push({ username: u, burritoType: x.type }))); + hits.map((x) => users.forEach((u) => updates.push({ to: u, from: msg.user, type: x.type }))); return { updates, - giver: msg.user, + from: msg.user, }; } diff --git a/src/lib/validator.ts b/src/lib/validator.ts index 3f7285d..c9c4bd6 100644 --- a/src/lib/validator.ts +++ b/src/lib/validator.ts @@ -65,7 +65,7 @@ function validMessage(message: any, emojis: any, allBots: any): boolean { } function validBotMention(message: any, botUserID: any) { - if ((message.text.match(`<@${botUserID}>`)) && (message.text.match('stats'))) { + if ((message.text.match(`<@${botUserID}>`))) { return true; } return false; diff --git a/src/types/Http.ts b/src/types/Http.ts index 1d56f56..a787dbf 100644 --- a/src/types/Http.ts +++ b/src/types/Http.ts @@ -1,11 +1,11 @@ declare module Http { - export interface Response { - error: boolean; - code?: number, - message?: string | null, - data?: object | null - } + export interface Response { + error: boolean; + code?: number, + message?: string | null, + data?: object | null + } } diff --git a/src/types/Score.interface.ts b/src/types/Score.interface.ts index fc49cd9..4beef9c 100644 --- a/src/types/Score.interface.ts +++ b/src/types/Score.interface.ts @@ -1,8 +1,8 @@ export default interface Score { - _id?:string; - to:string; - from:string; - value:number; - given_at:Date; - type?: string; + _id?: string; + to: string; + from: string; + value: number; + given_at: Date; + type?: string; } diff --git a/src/types/Slack.interface.ts b/src/types/Slack.interface.ts index f7c9aa6..9ff7be3 100644 --- a/src/types/Slack.interface.ts +++ b/src/types/Slack.interface.ts @@ -1,79 +1,79 @@ declare module Slack { - /** - * Interface describes object for stored user or bot - */ - export interface Stored { - id: string; - name: string; - avatar: string; - } + /** + * Interface describes object for stored user or bot + */ + export interface Stored { + id: string; + name: string; + avatar: string; + } - export interface Profile { - title: string; - phone: string; - skype: string; - real_name: string; - real_name_normalized: string; - display_name: string; - display_name_normalized: string; - fields?: any; - status_text: string; - status_emoji: string; - status_expiration: number; - avatar_hash: string; - always_active: boolean; - first_name: string; - last_name: string; - image_24: string; - image_32: string; - image_48: string; - image_72: string; - image_192: string; - image_512: string; - status_text_canonical: string; - team: string; - email: string; - bot_id: string; - api_app_id: string; - image_original: string; - image_1024: string; - is_custom_image?: boolean; - } + export interface Profile { + title: string; + phone: string; + skype: string; + real_name: string; + real_name_normalized: string; + display_name: string; + display_name_normalized: string; + fields?: any; + status_text: string; + status_emoji: string; + status_expiration: number; + avatar_hash: string; + always_active: boolean; + first_name: string; + last_name: string; + image_24: string; + image_32: string; + image_48: string; + image_72: string; + image_192: string; + image_512: string; + status_text_canonical: string; + team: string; + email: string; + bot_id: string; + api_app_id: string; + image_original: string; + image_1024: string; + is_custom_image?: boolean; + } - export interface Member { - id: string; - team_id: string; - name: string; - deleted: boolean; - color: string; - real_name: string; - tz: string; - tz_label: string; - tz_offset: number; - profile: Profile; - is_admin: boolean; - is_owner: boolean; - is_primary_owner: boolean; - is_restricted: boolean; - is_ultra_restricted: boolean; - is_bot: boolean; - is_app_user: boolean; - updated: number; - } + export interface Member { + id: string; + team_id: string; + name: string; + deleted: boolean; + color: string; + real_name: string; + tz: string; + tz_label: string; + tz_offset: number; + profile: Profile; + is_admin: boolean; + is_owner: boolean; + is_primary_owner: boolean; + is_restricted: boolean; + is_ultra_restricted: boolean; + is_bot: boolean; + is_app_user: boolean; + updated: number; + } - export interface ResponseMetadata { - next_cursor: string; - } + export interface ResponseMetadata { + next_cursor: string; + } - export interface WbcList { - ok: boolean; - members: Member[]; - cache_ts: number; - response_metadata: ResponseMetadata; - scopes: string[]; - acceptedScopes: string[]; - } + export interface WbcList { + ok: boolean; + members: Member[]; + cache_ts: number; + response_metadata: ResponseMetadata; + scopes: string[]; + acceptedScopes: string[]; + } } diff --git a/src/types/User.interface.ts b/src/types/User.interface.ts index 6d8a72b..b5bab47 100644 --- a/src/types/User.interface.ts +++ b/src/types/User.interface.ts @@ -1,13 +1,13 @@ export default interface User { - _id?: string; - username?: string; - name?: string; - avatar?: string; - score?: number; - received?: number; - gived?: number; - receivedToday?: number; - givedToday?: number; - scoreinc?: number; - scoredec?: number; + _id?: string; + username?: string; + name?: string; + avatar?: string; + score?: number; + received?: number; + gived?: number; + receivedToday?: number; + givedToday?: number; + scoreinc?: number; + scoredec?: number; } diff --git a/src/types/UserScore.interface.ts b/src/types/UserScore.interface.ts index f83800c..1e719e0 100644 --- a/src/types/UserScore.interface.ts +++ b/src/types/UserScore.interface.ts @@ -1,4 +1,4 @@ export default interface UserScore { - _id:string; - score:number; + _id: string; + score: number; } diff --git a/test/handleBurritos.test.ts b/test/handleBurritos.test.ts index 64d6f20..5a4b7f8 100644 --- a/test/handleBurritos.test.ts +++ b/test/handleBurritos.test.ts @@ -38,16 +38,16 @@ describe('handleBurritos-test', () => { const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const updates = [ - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }]; + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }]; await handleBurritos('USER1', updates) const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const usAfterDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); @@ -67,12 +67,12 @@ describe('handleBurritos-test', () => { config.default.slack = { enableOverDraw: false, enableDecrement: false } const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const updates = [ - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }]; + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }]; await handleBurritos('USER1', updates); const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); @@ -88,12 +88,12 @@ describe('handleBurritos-test', () => { const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const updates = [ - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }]; + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }]; await handleBurritos('USER1', updates) const usAfterInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const usAfterDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); @@ -114,11 +114,11 @@ describe('handleBurritos-test', () => { const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const updates = [ - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }]; + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }]; await handleBurritos('USER1', updates) const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); const giverDataDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); @@ -139,12 +139,12 @@ describe('handleBurritos-test', () => { const usBeforeInc = await BurritoStore.getUserScore('USER2', 'to', 'inc'); const usBeforeDec = await BurritoStore.getUserScore('USER2', 'to', 'dec'); const updates = [ - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'dec' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, + { from: 'USER1', to: 'USER2', type: 'inc' }, ]; await handleBurritos('USER1', updates) const giverDataInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); From 825f9166973db877b677b7d94f9783adf9f59fe8 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Thu, 3 Feb 2022 00:44:57 +0100 Subject: [PATCH 24/51] fix test --- test/parseMessage.test.ts | 68 +++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/test/parseMessage.test.ts b/test/parseMessage.test.ts index 4a70771..ba82b03 100644 --- a/test/parseMessage.test.ts +++ b/test/parseMessage.test.ts @@ -126,10 +126,10 @@ describe('/src/lib/parseMessage', () => { } resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }] + from: 'USER1', + updates: [ + { to: 'USER2', from: 'USER1', type: 'inc' }, + { to: 'USER2', from: 'USER1', type: 'inc' }] } res = parseMessage(msg, emojis) expect(res).toEqual(resultShouldBe) @@ -144,12 +144,12 @@ describe('/src/lib/parseMessage', () => { } resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', burritoType: 'inc' }, - { username: 'USER3', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER3', burritoType: 'inc' }] + from: 'USER1', + updates: [ + { to: 'USER2', from: 'USER1', type: 'inc' }, + { to: 'USER3', from: 'USER1', type: 'inc' }, + { to: 'USER2', from: 'USER1', type: 'inc' }, + { to: 'USER3', from: 'USER1', type: 'inc' }] } res = parseMessage(msg, emojis) expect(res).toEqual(resultShouldBe) @@ -164,12 +164,12 @@ describe('/src/lib/parseMessage', () => { } resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', burritoType: 'inc' }, - { username: 'USER3', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER3', burritoType: 'inc' }] + from: 'USER1', + updates: [ + { to: 'USER2', from: 'USER1', type: 'inc' }, + { to: 'USER3', from: 'USER1', type: 'inc' }, + { to: 'USER2', from: 'USER1', type: 'inc' }, + { to: 'USER3', from: 'USER1', type: 'inc' }] } res = parseMessage(msg, emojis) expect(res).toEqual(resultShouldBe) @@ -184,10 +184,10 @@ describe('/src/lib/parseMessage', () => { } resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }] + from: 'USER1', + updates: [ + { to: 'USER2', from: 'USER1', type: 'dec' }, + { to: 'USER2', from: 'USER1', type: 'dec' }] } res = parseMessage(msg, emojis) expect(res).toEqual(resultShouldBe) @@ -202,12 +202,12 @@ describe('/src/lib/parseMessage', () => { } resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', burritoType: 'dec' }, - { username: 'USER3', burritoType: 'dec' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER3', burritoType: 'dec' }] + from: 'USER1', + updates: [ + { to: 'USER2', from: 'USER1', type: 'dec' }, + { to: 'USER3', from: 'USER1', type: 'dec' }, + { to: 'USER2', from: 'USER1', type: 'dec' }, + { to: 'USER3', from: 'USER1', type: 'dec' }] } res = parseMessage(msg, emojis) expect(res).toEqual(resultShouldBe) @@ -222,14 +222,14 @@ describe('/src/lib/parseMessage', () => { } resultShouldBe = { - giver: 'USER1', - updates: - [{ username: 'USER2', burritoType: 'inc' }, - { username: 'USER3', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'inc' }, - { username: 'USER3', burritoType: 'inc' }, - { username: 'USER2', burritoType: 'dec' }, - { username: 'USER3', burritoType: 'dec' }] + from: 'USER1', + updates: [ + { to: 'USER2', from: 'USER1', type: 'inc' }, + { to: 'USER3', from: 'USER1', type: 'inc' }, + { to: 'USER2', from: 'USER1', type: 'inc' }, + { to: 'USER3', from: 'USER1', type: 'inc' }, + { to: 'USER2', from: 'USER1', type: 'dec' }, + { to: 'USER3', from: 'USER1', type: 'dec' }] } res = parseMessage(msg, emojis) expect(res).toEqual(resultShouldBe) From 830f3076b74143c48cddb04acc1a6a9fa960e900 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Thu, 3 Feb 2022 14:38:13 +0100 Subject: [PATCH 25/51] update --- src/bot.ts | 45 -------- src/bot/index.ts | 31 +++++ src/bot/interaction.ts | 35 ++++++ src/bot/tmpl/help.ts | 18 +++ src/handleBurritos.ts | 2 +- src/slack/Wbc.ts | 8 +- test/bot-test.ts | 224 ------------------------------------ test/bot.test.ts | 15 +++ test/handleBurritos.test.ts | 2 +- 9 files changed, 106 insertions(+), 274 deletions(-) delete mode 100644 src/bot.ts create mode 100644 src/bot/index.ts create mode 100644 src/bot/interaction.ts create mode 100644 src/bot/tmpl/help.ts delete mode 100644 test/bot-test.ts create mode 100644 test/bot.test.ts diff --git a/src/bot.ts b/src/bot.ts deleted file mode 100644 index 66b841a..0000000 --- a/src/bot.ts +++ /dev/null @@ -1,45 +0,0 @@ -import LocalStore from './store/LocalStore'; -import { parseMessage } from './lib/parseMessage'; -import { handleBurritos } from './handleBurritos'; -import { validBotMention, validMessage } from './lib/validator'; -import { emojis } from './lib/emojis'; -import Rtm from './slack/Rtm'; -import Wbc from './slack/Wbc'; - - -export const notifyUser = (user: string, message: string) => Wbc.sendDM(user, message); - -export const start = () => Rtm.on('slackMessage', (event: any) => incomingMessage(event)); - -export const incomingMessage = async (message) => { - - // If message not valid then dont process it - if (!validMessage(message, emojis, LocalStore.getAllBots())) return false; - - // If botMention handle message seperate later on. No support today - if (validBotMention(message, LocalStore.botUserID())) { - return await handleBotInteraction(message); - } - - const result = parseMessage(message, emojis); - if (result?.updates) { - const { from, updates } = result; - await handleBurritos(from, updates); - } -}; - - -const BOT_INTERACTIONS = [ - 'help', - 'stats', - 'emojis' -]; - -const handleBotInteraction = async(message) => { - - console.log(message) - const hits = BOT_INTERACTIONS.map((arg) => { - if(message.text.includes(arg)) return arg; - }).filter(s => s); - console.log(hits); -}; diff --git a/src/bot/index.ts b/src/bot/index.ts new file mode 100644 index 0000000..80174cd --- /dev/null +++ b/src/bot/index.ts @@ -0,0 +1,31 @@ +import LocalStore from '../store/LocalStore'; +import { parseMessage } from '../lib/parseMessage'; +import { handleBurritos } from '../handleBurritos'; +import { handleInteraction } from './interaction'; +import { validBotMention, validMessage } from '../lib/validator'; +import { emojis } from '../lib/emojis'; +import Rtm from '../slack/Rtm'; + + +/** + * Start listen to slack messages / events */ +export const start = () => Rtm.on('slackMessage', (event: any) => incomingMessage(event)); + + + +export const incomingMessage = async (message) => { + + // If message not valid then dont process it + if (!validMessage(message, emojis, LocalStore.getAllBots())) return false; + + // If botMention handle message seperate later on. No support today + if (validBotMention(message, LocalStore.botUserID())) { + return await handleInteraction(message); + } + + const result = parseMessage(message, emojis); + if (result?.updates) { + const { from, updates } = result; + await handleBurritos(from, updates); + } +}; diff --git a/src/bot/interaction.ts b/src/bot/interaction.ts new file mode 100644 index 0000000..b8fb955 --- /dev/null +++ b/src/bot/interaction.ts @@ -0,0 +1,35 @@ +import Wbc from '../slack/Wbc'; +import { tmplHelp } from './tmpl/help'; +export const BOT_INTERACTIONS = [ + 'help', + 'stats', + 'emojis' +]; + + + +const parseCommands = (text) => { + return BOT_INTERACTIONS.map((arg) => { + if (text.includes(arg)) return arg; + }).filter(s => s); +}; + + +/** + * Send message back to user or channel */ +export const notifyUser = (user: string, message: any) => Wbc.sendDM(user, message); + +export const handleInteraction = async (message) => { + + const res = parseCommands(message.text); + if(!res.length) return false; + console.log(message) + res.forEach((command) => { + switch (command) { + case 'help': + const data = tmplHelp(); + return notifyUser(message.username, data) + } + + }); +}; diff --git a/src/bot/tmpl/help.ts b/src/bot/tmpl/help.ts new file mode 100644 index 0000000..5b46149 --- /dev/null +++ b/src/bot/tmpl/help.ts @@ -0,0 +1,18 @@ +import { BOT_INTERACTIONS } from '../interaction'; +export const tmplHelp = () => { + return { + blocks: [ + { + type: "section", + fields: BOT_INTERACTIONS.map((command) => { + if (command !== 'help') { + return { + type: 'plain_text', + text: `*${command}* \n` + } + } + }).filter(y => y) + } + ] + } +}; diff --git a/src/handleBurritos.ts b/src/handleBurritos.ts index 1fe7e6b..a162b44 100644 --- a/src/handleBurritos.ts +++ b/src/handleBurritos.ts @@ -1,7 +1,7 @@ import log from 'loglevel'; import config from './config'; import BurritoStore from './store/BurritoStore'; -import { notifyUser } from './bot'; +import { notifyUser } from './bot/interaction'; import { Updates, Update } from './lib/parseMessage'; const { diff --git a/src/slack/Wbc.ts b/src/slack/Wbc.ts index a1fc83c..ce3b912 100644 --- a/src/slack/Wbc.ts +++ b/src/slack/Wbc.ts @@ -34,10 +34,12 @@ class Wbc { return { users, bots }; } - async sendDM(username: string, text: string) { + async sendDM(username: string, text: any) { + console.log("text", text) const res = await this.wbc.chat.postMessage({ - text, - channel: username, + text: " ", + blocks: text.blocks, + channel: 'CF3RYAETU', username: config.slack.bot_name, icon_emoji: ':burrito:', }); diff --git a/test/bot-test.ts b/test/bot-test.ts deleted file mode 100644 index 174f5eb..0000000 --- a/test/bot-test.ts +++ /dev/null @@ -1,224 +0,0 @@ -import { expect } from 'chai'; -import { init } from './lib/seedDatabase'; -import BurritoStore from '../src/store/BurritoStore'; - -let mongod: any, mongoDriver: any, handleBurritos: any; - -const proxyquire = require('proxyquire').noCallThru(); - - -const loadMiddleware = ({ enable_decrement }) => { - - const bot = proxyquire('../src/bot', { - './config': { - slack: { - enableDecrement: enable_decrement, - dailyCap: 5, - dailyDecCap: 5, - emojiInc: ' :burrito: ', - emojiDec: ':rottenburrito:', - disableEmojiDec: false, - } - - }, - './slack/Wbc': { - sendDM: (user: string, text: string) => { - return true - }, - } - }) - - handleBurritos = bot.handleBurritos - -} - -describe('bot-test', async () => { - [ - { - describe: 'With file Driver as database', - driver: 'file' - }, - { - describe: 'With Array Driver as database', - driver: 'array' - }, - { - describe: 'With Mongodb Driver as database', - driver: 'mongodb' - }, - ].forEach((test) => { - - describe(test.describe, async () => { - - async function connectDB({ seedDB = false, enable_decrement }) { - const dbinit: any = await init({ driver: test.driver, random: false, seedDB }); - if (dbinit.mongod && dbinit.mongoDriver) { - mongod = dbinit.mongod - mongoDriver = dbinit.mongoDriver - } - loadMiddleware({ enable_decrement }) - } - - async function closeDB() { - if (test.driver === 'mongodb') { - if (mongoDriver.client) await mongoDriver.client.close(); - if (mongod) await mongod.stop(); - } - } - - async function reset(enable_decrement = true) { - await closeDB(); - await connectDB({ enable_decrement }); - } - - before(async () => { - await connectDB({ enable_decrement: true }) - - }); - - after(async () => { - await closeDB() - }); - - - describe('handleBurritos', async () => { - it('Should give burritos, enable_decrement: true', async () => { - const updates = [ - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'dec' - }, - { - username: 'USER2', - type: 'dec' - } - ]; - - await handleBurritos('USER1', updates); - const givenToday = await BurritoStore.givenToday('USER1', 'from'); - expect(givenToday).to.equal(5); - }); - - it('Should not give burritos, enable_decrement: true', async () => { - await reset() - const updates = [ - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'dec' - }, - { - username: 'USER2', - type: 'dec' - }, - { - username: 'USER2', - type: 'inc' - }, - ]; - - await handleBurritos('USER1', updates); - const givenToday = await BurritoStore.givenToday('USER1', 'from'); - expect(givenToday).to.equal(0); - }); - - - it('should give burritos, enable_decrement: false', async () => { - await reset(false) - const updates = [ - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'dec' - }, - { - username: 'USER2', - type: 'dec' - } - ] - const gg = await handleBurritos('USER1', updates); - const givenTodayInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); - const givenTodayDec = await BurritoStore.givenToday('USER1', 'from', 'dec'); - expect(givenTodayInc).to.equal(4); - expect(givenTodayDec).to.equal(2); - }); - - - - it('should not give burritos, enable_decrement: false', async () => { - await reset(false) - const updates = [ - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - { - username: 'USER2', - type: 'inc' - }, - - ] - const gg = await handleBurritos('USER1', updates); - const givenTodayInc = await BurritoStore.givenToday('USER1', 'from', 'inc'); - expect(givenTodayInc).to.equal(0); - }); - - }); - - }); - }); -}); diff --git a/test/bot.test.ts b/test/bot.test.ts new file mode 100644 index 0000000..e7d8b29 --- /dev/null +++ b/test/bot.test.ts @@ -0,0 +1,15 @@ +import { handleInteraction } from '../src/bot/interaction'; +describe('bot', () => { + + describe('handleInteraction', () => { + it('should match help and return list of commands to user / channel', async () => { + const message = { + text: " help" + }; + const res = await handleInteraction(message); + console.log("IN TEST", res); + }); + + }); + +}); diff --git a/test/handleBurritos.test.ts b/test/handleBurritos.test.ts index 5a4b7f8..2b1a90a 100644 --- a/test/handleBurritos.test.ts +++ b/test/handleBurritos.test.ts @@ -3,7 +3,7 @@ import { handleBurritos } from '../src/handleBurritos'; import BurritoStore from '../src/store/BurritoStore'; import * as config from '../src/config'; import { connectDB, closeDB } from './lib/database/database-functions'; -import { notifyUser } from '../src/bot'; +import { notifyUser } from '../src/bot/interaction'; import { initSlack } from './lib/slack'; initSlack() From 77e6c35d8683268404de5840379f4af75365825b Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Thu, 3 Feb 2022 20:06:19 +0100 Subject: [PATCH 26/51] added two commands to @heyburrito message --- src/bot/interaction.ts | 21 ++++++++++------- src/bot/tmpl/emojis.ts | 52 ++++++++++++++++++++++++++++++++++++++++++ src/bot/tmpl/help.ts | 34 ++++++++++++++++++++------- 3 files changed, 91 insertions(+), 16 deletions(-) create mode 100644 src/bot/tmpl/emojis.ts diff --git a/src/bot/interaction.ts b/src/bot/interaction.ts index b8fb955..419b5b8 100644 --- a/src/bot/interaction.ts +++ b/src/bot/interaction.ts @@ -1,20 +1,18 @@ import Wbc from '../slack/Wbc'; import { tmplHelp } from './tmpl/help'; +import { tmplEmoji } from './tmpl/emojis'; + export const BOT_INTERACTIONS = [ 'help', - 'stats', 'emojis' ]; - - const parseCommands = (text) => { return BOT_INTERACTIONS.map((arg) => { if (text.includes(arg)) return arg; }).filter(s => s); }; - /** * Send message back to user or channel */ export const notifyUser = (user: string, message: any) => Wbc.sendDM(user, message); @@ -22,14 +20,21 @@ export const notifyUser = (user: string, message: any) => Wbc.sendDM(user, messa export const handleInteraction = async (message) => { const res = parseCommands(message.text); - if(!res.length) return false; - console.log(message) + if (!res.length) return false; + res.forEach((command) => { switch (command) { - case 'help': + case 'help': { const data = tmplHelp(); return notifyUser(message.username, data) + } + case 'emojis': { + const data = tmplEmoji(); + return notifyUser(message.username, data) + } + default: { + return false; + } } - }); }; diff --git a/src/bot/tmpl/emojis.ts b/src/bot/tmpl/emojis.ts new file mode 100644 index 0000000..9a4ab82 --- /dev/null +++ b/src/bot/tmpl/emojis.ts @@ -0,0 +1,52 @@ +import { emojis } from '../../lib/emojis'; + +const inc = emojis.map(emoji => { + if (emoji.type === 'inc') return emoji.emoji +}).filter(y => y); + +const incTxt = inc.map((emoji) => { + return `${emoji} `; +}).filter(y => y).join().replace(/,/g, '') + +const dec = emojis.map(emoji => { + if (emoji.type === 'dec') return emoji.emoji +}).filter(y => y); + + +const decTxt = dec.map((emoji) => { + return `${emoji} `; +}).filter(y => y).join().replace(/,/g, '') + +export const tmplEmoji = () => { + return { + blocks: [ + { + type: "section", + text: { + type: 'mrkdwn', + text: "Available emojis" + } + }, + { + type: "divider" + }, + { + type: "section", + text: { + type: 'mrkdwn', + text: `*+ * ${incTxt}` + } + }, + { + type: "divider" + }, + { + type: "section", + text: { + type: 'mrkdwn', + text: `*- * ${decTxt}` + } + } + ] + } +}; diff --git a/src/bot/tmpl/help.ts b/src/bot/tmpl/help.ts index 5b46149..63f3a88 100644 --- a/src/bot/tmpl/help.ts +++ b/src/bot/tmpl/help.ts @@ -1,17 +1,35 @@ import { BOT_INTERACTIONS } from '../interaction'; + export const tmplHelp = () => { + const botTxt = BOT_INTERACTIONS.map((command) => { + return `*${command}*`; + }).filter(y => y).join().replace(/,/g, "\n"); + return { blocks: [ { type: "section", - fields: BOT_INTERACTIONS.map((command) => { - if (command !== 'help') { - return { - type: 'plain_text', - text: `*${command}* \n` - } - } - }).filter(y => y) + text: { + type: 'mrkdwn', + text: "Available commands" + } + }, + { + type: "section", + text: { + type: 'mrkdwn', + text: "@heyburrito " + } + }, + { + type: "divider" + }, + { + type: "section", + text: { + type: 'mrkdwn', + text: botTxt + } } ] } From 9851b1774f80754379e6459e8547a991236dd99e Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 02:09:09 +0100 Subject: [PATCH 27/51] moving interfaces to right files --- src/types/Http.ts | 12 ----- src/types/Score.interface.ts | 8 ---- src/types/Slack.interface.ts | 81 -------------------------------- src/types/User.interface.ts | 13 ----- src/types/UserScore.interface.ts | 4 -- 5 files changed, 118 deletions(-) delete mode 100644 src/types/Http.ts delete mode 100644 src/types/Score.interface.ts delete mode 100644 src/types/Slack.interface.ts delete mode 100644 src/types/User.interface.ts delete mode 100644 src/types/UserScore.interface.ts diff --git a/src/types/Http.ts b/src/types/Http.ts deleted file mode 100644 index a787dbf..0000000 --- a/src/types/Http.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare module Http { - - export interface Response { - error: boolean; - code?: number, - message?: string | null, - data?: object | null - } - -} - -export default Http; diff --git a/src/types/Score.interface.ts b/src/types/Score.interface.ts deleted file mode 100644 index 4beef9c..0000000 --- a/src/types/Score.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default interface Score { - _id?: string; - to: string; - from: string; - value: number; - given_at: Date; - type?: string; -} diff --git a/src/types/Slack.interface.ts b/src/types/Slack.interface.ts deleted file mode 100644 index 9ff7be3..0000000 --- a/src/types/Slack.interface.ts +++ /dev/null @@ -1,81 +0,0 @@ -declare module Slack { - - /** - * Interface describes object for stored user or bot - */ - export interface Stored { - id: string; - name: string; - avatar: string; - } - - export interface Profile { - title: string; - phone: string; - skype: string; - real_name: string; - real_name_normalized: string; - display_name: string; - display_name_normalized: string; - fields?: any; - status_text: string; - status_emoji: string; - status_expiration: number; - avatar_hash: string; - always_active: boolean; - first_name: string; - last_name: string; - image_24: string; - image_32: string; - image_48: string; - image_72: string; - image_192: string; - image_512: string; - status_text_canonical: string; - team: string; - email: string; - bot_id: string; - api_app_id: string; - image_original: string; - image_1024: string; - is_custom_image?: boolean; - } - - export interface Member { - id: string; - team_id: string; - name: string; - deleted: boolean; - color: string; - real_name: string; - tz: string; - tz_label: string; - tz_offset: number; - profile: Profile; - is_admin: boolean; - is_owner: boolean; - is_primary_owner: boolean; - is_restricted: boolean; - is_ultra_restricted: boolean; - is_bot: boolean; - is_app_user: boolean; - updated: number; - } - - export interface ResponseMetadata { - next_cursor: string; - } - - export interface WbcList { - ok: boolean; - members: Member[]; - cache_ts: number; - response_metadata: ResponseMetadata; - scopes: string[]; - acceptedScopes: string[]; - } - -} - - -export default Slack; diff --git a/src/types/User.interface.ts b/src/types/User.interface.ts deleted file mode 100644 index b5bab47..0000000 --- a/src/types/User.interface.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default interface User { - _id?: string; - username?: string; - name?: string; - avatar?: string; - score?: number; - received?: number; - gived?: number; - receivedToday?: number; - givedToday?: number; - scoreinc?: number; - scoredec?: number; -} diff --git a/src/types/UserScore.interface.ts b/src/types/UserScore.interface.ts deleted file mode 100644 index 1e719e0..0000000 --- a/src/types/UserScore.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default interface UserScore { - _id: string; - score: number; -} From d4a40a67ae10bb2b58d12a52575efd6527c6c413 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 02:09:30 +0100 Subject: [PATCH 28/51] remove old burritostore --- src/store/_BurritoStore.old.ts | 115 --------------------------------- 1 file changed, 115 deletions(-) delete mode 100644 src/store/_BurritoStore.old.ts diff --git a/src/store/_BurritoStore.old.ts b/src/store/_BurritoStore.old.ts deleted file mode 100644 index 7e073b9..0000000 --- a/src/store/_BurritoStore.old.ts +++ /dev/null @@ -1,115 +0,0 @@ -import * as log from 'bog'; -import { EventEmitter } from 'events'; - -interface Find { - _id: string; - to: string; - from: string; - value: number; - given_at: Date; -} - -interface Sum { - _id?: string; // Username - score?: number; -} - -interface GetUserStats { - _id: string; - received: number; - given: number; - receivedToday: number; - givenToday: number; -} - -interface DatabasePost { - _id: string, - to: string, - from: string, - value: number, - given_at: Date -} - -class BurritoStore extends EventEmitter { - database: any = null; - - // Set and Store database object - setDatabase(database: any) { - this.database = database; - } - - async giveBurrito(to: string, from: string, date = new Date()): Promise { - log.info(`Burrito given to ${to} from ${from}`); - await this.database.give(to, from, date); - this.emit('GIVE', to, from); - return to; - } - - async takeAwayBurrito(to: string, from: string, date = new Date()): Promise { - log.info(`Burrito taken away from ${to} by ${from}`); - const score: number = await this.database.getScore(to, 'to', true); - if (!score) return []; - await this.database.takeAway(to, from, date); - this.emit('TAKE_AWAY', to, from); - return to; - } - - async getUserStats(user: string): Promise { - const [ - received, - given, - receivedToday, - givenToday, - ]: [Sum[], Sum[], number, number] = await Promise.all([ - this.database.getScore(user, 'to'), - this.database.getScore(user, 'from'), - this.givenBurritosToday(user, 'to'), - this.givenBurritosToday(user, 'from'), - ]); - return { - receivedToday, - givenToday, - _id: user, - received: received.length, - given: given.length, - }; - } - - async getScoreBoard({ ...args }): Promise { - return this.database.getScoreBoard({ ...args }); - } - - /** - * @param {string} user - userId - * @param {string} listType - to / from defaults from - */ - async givenBurritosToday(user: string, listType: string): Promise { - const givenToday: Find[] = await this.database.findFromToday(user, listType); - return givenToday.length; - } - - /** - * @param {string} user - userId - * @param {string} listType - to / from defaults from - */ - async givenToday(user: string, listType: string, type: any = false): Promise { - const givenToday: Find[] = await this.database.findFromToday(user, listType); - if (type) { - if (['inc', 'dec'].includes(type)) { - const valueFilter = (type === 'inc') ? 1 : -1; - const givenFilter = givenToday.filter((x) => x.value === valueFilter); - return givenFilter.length; - } - } - return givenToday.length; - } - - /** - * @param {string} user - userId - */ - async getUserScore(user: string, listType: string, num): Promise { - return this.database.getScore(user, listType, num); - } -} - -export default new BurritoStore(); From 5dd17f7b721791ce125ee72ff732801a3ee9b9ea Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 02:16:58 +0100 Subject: [PATCH 29/51] formatting --- src/store/LocalStore.ts | 98 +++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/src/store/LocalStore.ts b/src/store/LocalStore.ts index 17ec8a0..458285d 100644 --- a/src/store/LocalStore.ts +++ b/src/store/LocalStore.ts @@ -3,59 +3,53 @@ import config from '../config'; import WBCHandler from '../slack/Wbc'; class LocalStore { - botId: string = null; - storedBots: any; - storedUsers: any; - botName: string = config.slack.bot_name; - - async start() { - await this.fetch(); - - // Run update of localstore every hour - setTimeout(() => this.start(), 60 * 60 * 1000); - } - - async fetch() { - log.info('Fetching slackUsers'); - const { users, bots } = await WBCHandler.fetchSlackUsers(); - this.storedUsers = []; - this.storedBots = []; - this.storedUsers = users; - this.storedUsers.push({ - id: 'BurritoFee', - name: 'BurritoFee bank', - avatar: 'https://secure.gravatar.com/avatar/c8facda114a361db902d0cbf6481e819.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0006-48.png', - memberType: 'member', - }) - this.storedBots = bots; - - this.getBotUsername(); - return true; - } - - getSlackUsers() { - return this.storedUsers; - } - - botUserID() { - return this.botId; - } - - getAllBots() { - return this.storedBots; - } - - getBotUsername(): void { - this.storedBots.forEach((x: any) => { - if (x.name === this.botName) { - this.botId = x.id; - } - }); - - if (!this.botId) { - log.warn(`Could not found bot ${config.slack.bot_name} on slack account`); - } + botId: string = null; + storedBots: any; + storedUsers: any; + botName: string = config.slack.bot_name; + + async start() { + await this.fetch(); + + // Run update of localstore every hour + setTimeout(() => this.start(), 60 * 60 * 1000); + } + + async fetch() { + log.info('Fetching slackUsers'); + const { users, bots } = await WBCHandler.fetchSlackUsers(); + this.storedUsers = []; + this.storedBots = []; + this.storedUsers = users; + this.storedBots = bots; + + this.getBotUsername(); + return true; + } + + getSlackUsers() { + return this.storedUsers; + } + + botUserID() { + return this.botId; + } + + getAllBots() { + return this.storedBots; + } + + getBotUsername(): void { + this.storedBots.forEach((x: any) => { + if (x.name === this.botName) { + this.botId = x.id; + } + }); + + if (!this.botId) { + log.warn(`Could not found bot ${config.slack.bot_name} on slack account`); } + } } export default new LocalStore(); From d34acecb62612e3afcbb0ec26a1a34e5b10806d0 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 02:19:35 +0100 Subject: [PATCH 30/51] adding interface --- src/api/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/api/index.ts b/src/api/index.ts index a91cab9..7ae98a4 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -3,9 +3,6 @@ import Route from './Route'; import { getScoreBoard, getUserStats, givenBurritosToday, getUserScore } from '../middleware'; import config from '../config'; -// Types -import Http from '../types/Http'; - // defaults const apiPath: string = config.http.api_path; @@ -19,13 +16,20 @@ const ALLOWED_SCORETYPES: string[] = [ 'dec', ]; +interface Response { + error: boolean; + code?: number, + message?: string | null, + data?: object | null +}; + /** * http response function * @param { object } content * @param { object } res * @params { number } statuscode */ -const response = (content: Http.Response, res: any, statusCode: number = 200): void => { +const response = (content: Response, res: any, statusCode: number = 200): void => { res.writeHead(statusCode, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(content), 'utf-8'); }; @@ -65,8 +69,6 @@ Route.add({ }, }); - - Route.add({ method: 'GET', path: `${apiPath}scoreboard/{listType}/{scoreTypeInput}`, From 4794a4a1f37d00dadf5d7d871ea4dc9c359acb40 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 02:20:09 +0100 Subject: [PATCH 31/51] adding interface --- src/lib/mapper.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lib/mapper.ts b/src/lib/mapper.ts index 331e82d..f77db95 100644 --- a/src/lib/mapper.ts +++ b/src/lib/mapper.ts @@ -1,5 +1,18 @@ import LocalStore from '../store/LocalStore'; -import User from '../types/User.interface'; + +export interface User { + _id?: string; + username?: string; + name?: string; + avatar?: string; + score?: number; + received?: number; + gived?: number; + receivedToday?: number; + givedToday?: number; + scoreinc?: number; + scoredec?: number; +} export default (data: User[]): User[] => { const slackUsers = LocalStore.getSlackUsers(); From 790509eded75096ad605e8f1f8aa36045f35e6cc Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 02:23:31 +0100 Subject: [PATCH 32/51] formatting --- src/bot/index.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/bot/index.ts b/src/bot/index.ts index 80174cd..d4e0fb4 100644 --- a/src/bot/index.ts +++ b/src/bot/index.ts @@ -6,13 +6,10 @@ import { validBotMention, validMessage } from '../lib/validator'; import { emojis } from '../lib/emojis'; import Rtm from '../slack/Rtm'; - /** * Start listen to slack messages / events */ export const start = () => Rtm.on('slackMessage', (event: any) => incomingMessage(event)); - - export const incomingMessage = async (message) => { // If message not valid then dont process it From ce7aac6e1a2e6262aa401f7ab54df42983273734 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 17:29:56 +0100 Subject: [PATCH 33/51] style of slack message --- src/bot/commands.ts | 24 +++++++++++++++++++++++ src/bot/interaction.ts | 43 ++++++++++++++++++++++++----------------- src/bot/tmpl/help.ts | 18 ++++++++++++----- src/bot/tmpl/toplist.ts | 27 ++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 src/bot/commands.ts create mode 100644 src/bot/tmpl/toplist.ts diff --git a/src/bot/commands.ts b/src/bot/commands.ts new file mode 100644 index 0000000..b1d1a30 --- /dev/null +++ b/src/bot/commands.ts @@ -0,0 +1,24 @@ +export const commands = [ + { + cmd: 'help', + info: 'Show all available commands', + }, + { + cmd: 'emojis', + info: 'Show all available emojis', + }, + { + cmd: 'top5', + info: 'Show top5 list today ', + subCmd: [ + { + cmd: 'to', + info: 'Return list of top5 receiver' + }, + { + cmd: 'from', + info: 'Return list of top5 sender' + } + ] + } +]; diff --git a/src/bot/interaction.ts b/src/bot/interaction.ts index 419b5b8..0084781 100644 --- a/src/bot/interaction.ts +++ b/src/bot/interaction.ts @@ -1,39 +1,46 @@ import Wbc from '../slack/Wbc'; import { tmplHelp } from './tmpl/help'; import { tmplEmoji } from './tmpl/emojis'; - -export const BOT_INTERACTIONS = [ - 'help', - 'emojis' -]; +import { tmplToplist } from './tmpl/toplist'; +import { commands } from './commands'; +import { SendDM } from '../slack/Wbc'; const parseCommands = (text) => { - return BOT_INTERACTIONS.map((arg) => { - if (text.includes(arg)) return arg; + return commands.map(({ cmd }) => { + if (text.includes(cmd)) return cmd; }).filter(s => s); }; /** * Send message back to user or channel */ -export const notifyUser = (user: string, message: any) => Wbc.sendDM(user, message); +export const notifyUser = (args: SendDM) => Wbc.sendDM(args); + +export const handleInteraction = ({ user, channel, text }) => { -export const handleInteraction = async (message) => { + const res = parseCommands(text); - const res = parseCommands(message.text); - if (!res.length) return false; + if (!res.length) { + const { blocks } = tmplHelp(); + return notifyUser({ user, channel, blocks, text: ' ' }) + } - res.forEach((command) => { - switch (command) { + res.forEach(async (cmd) => { + switch (cmd) { case 'help': { - const data = tmplHelp(); - return notifyUser(message.username, data) + const { blocks } = tmplHelp(); + return notifyUser({ user, channel, blocks, text: ' ' }); } case 'emojis': { - const data = tmplEmoji(); - return notifyUser(message.username, data) + const { blocks } = tmplEmoji(); + return notifyUser({ user, channel, blocks, text: ' ' }); + } + case 'top5': { + const { blocks } = await tmplToplist({ listType: 'to', amount: 5 }) + return notifyUser({ user, channel, blocks, text: ' ' }); } default: { - return false; + const { blocks } = tmplHelp(); + return notifyUser({ user, channel, blocks, text: ' ' }); } } }); diff --git a/src/bot/tmpl/help.ts b/src/bot/tmpl/help.ts index 63f3a88..ae9af2b 100644 --- a/src/bot/tmpl/help.ts +++ b/src/bot/tmpl/help.ts @@ -1,8 +1,16 @@ -import { BOT_INTERACTIONS } from '../interaction'; +import { commands } from '../commands' export const tmplHelp = () => { - const botTxt = BOT_INTERACTIONS.map((command) => { - return `*${command}*`; + const botTxt = commands.map(({ cmd, info, subCmd }) => { + if (!subCmd) return `*${cmd}* - ${info}`; + + let txt = `*${cmd}* - ${info}`; + subCmd.map(({ cmd, info }) => { + txt += `\n - *${cmd}* - ${info}` + }); + + return txt; + }).filter(y => y).join().replace(/,/g, "\n"); return { @@ -11,14 +19,14 @@ export const tmplHelp = () => { type: "section", text: { type: 'mrkdwn', - text: "Available commands" + text: "Available commands:" } }, { type: "section", text: { type: 'mrkdwn', - text: "@heyburrito " + text: "@heyburrito " } }, { diff --git a/src/bot/tmpl/toplist.ts b/src/bot/tmpl/toplist.ts new file mode 100644 index 0000000..e4cd0c7 --- /dev/null +++ b/src/bot/tmpl/toplist.ts @@ -0,0 +1,27 @@ +import { getScoreBoard } from '../../middleware'; + +interface TopList { + listType: string; + amount: number; +} + +export const tmplToplist = async ({ listType, amount }: TopList) => { + const result = await getScoreBoard(listType, 'inc', true); + + const topList = result.slice(0, amount) + + const topListTxt = topList.map(({ name, score }) => { + return `*${score}* - ${name}`; + }).filter(y => y).join().replace(/,/g, "\n"); + return { + blocks: [ + { + type: "section", + text: { + type: 'mrkdwn', + text: `${topListTxt}` + } + } + ] + } +}; From ccfd21b63cdbd8cab2f4796315dbd3c69a75dccc Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Fri, 4 Feb 2022 17:30:46 +0100 Subject: [PATCH 34/51] adding .env. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 505b0b5..0411456 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,7 @@ tmp data/* .env +.env.testing +.env.development +.env.production .tern* From fc947008f5407f796591bc54dbae6807b5a8e46a Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:18:04 +0100 Subject: [PATCH 35/51] load conf depending on NODE_ENV --- src/server.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server.ts b/src/server.ts index 6c49789..14637f5 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,6 +1,8 @@ import dotenv from 'dotenv'; /* eslint-disable import/first */ -dotenv.config(); +const envPath = process.env.NODE_ENV ? `.env.${process.env.NODE_ENV}` : '.env'; +dotenv.config({ path: envPath }); + import log from 'loglevel'; import http from 'http'; import BurritoStore from './store/BurritoStore'; @@ -23,8 +25,8 @@ const init = async () => { init().then(() => { log.setLevel(config.misc.log_level); + log.debug(config) log.info('Staring heyburrito'); - console.log(config) // Configure BurritoStore BurritoStore.setDatabase(database); From 6a91dc45fb675f61a916d9b55ddd97ff6ae0fafa Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:20:39 +0100 Subject: [PATCH 36/51] change of sendDM args --- src/slack/Wbc.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/slack/Wbc.ts b/src/slack/Wbc.ts index ce3b912..4c4dc71 100644 --- a/src/slack/Wbc.ts +++ b/src/slack/Wbc.ts @@ -8,6 +8,13 @@ interface WbcParsed { memberType: string; } +export interface SendDM { + user?: string; + channel?: string; + blocks?: any; + text?: string; +} + class Wbc { wbc: any; @@ -34,17 +41,15 @@ class Wbc { return { users, bots }; } - async sendDM(username: string, text: any) { - console.log("text", text) + async sendDM(args: SendDM) { + const user = args.user ? args.user : args.channel; const res = await this.wbc.chat.postMessage({ - text: " ", - blocks: text.blocks, - channel: 'CF3RYAETU', + ...args, username: config.slack.bot_name, - icon_emoji: ':burrito:', + icon_emoji: config.slack.bot_emoji || ':burre:', }); if (res.ok) { - log.info(`Notified user ${username}`); + log.info(`Notified user ${user}`); } } } From 11f65ab778abe0c50b4eeb2363f36604a2d770a4 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:23:06 +0100 Subject: [PATCH 37/51] import interface from mapper --- src/lib/utils/sort.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib/utils/sort.ts b/src/lib/utils/sort.ts index 56a5337..52149ac 100644 --- a/src/lib/utils/sort.ts +++ b/src/lib/utils/sort.ts @@ -1,7 +1,6 @@ +import { User } from '../mapper'; -import UserInterface from '../../types/User.interface'; - -export const sort = (input: UserInterface[], sortType: string = 'desc'): UserInterface[] => { +export const sort = (input: User[], sortType: string = 'desc'): User[] => { const sorted = input.sort((a, b) => { if (a.score) { if (sortType === 'desc') return b.score - a.score; From 439c0df9096d360eb74c34bd60482125f2553f97 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:24:07 +0100 Subject: [PATCH 38/51] import slackMock from conf.slack --- src/slack/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slack/index.ts b/src/slack/index.ts index 8b9c270..ee8ee18 100644 --- a/src/slack/index.ts +++ b/src/slack/index.ts @@ -4,7 +4,7 @@ import { RTMClient } from '@slack/rtm-api'; import { RTMMock, WEBMock } from '../../test/lib/slack/slack-mock'; import config from '../config'; -const { slackMock } = config.misc; +const { slackMock } = config.slack; log.info('Slack mockApi loaded', slackMock); export default { From 897ecd9c41851b0c13826d666146ea39cc02fac2 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:26:05 +0100 Subject: [PATCH 39/51] loading from diffrent .env. --- src/config/index.ts | 174 +++++++++++--------------------------------- 1 file changed, 43 insertions(+), 131 deletions(-) diff --git a/src/config/index.ts b/src/config/index.ts index 23b2822..a3901cb 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,4 +1,3 @@ -import log from 'loglevel'; import { env, mustHave } from '../lib/utils/env'; import { getThemePath, getThemeName, themeRootPath, defaultTheme} from '../lib/utils/theme'; import { fixPath, root} from '../lib/utils/path'; @@ -29,137 +28,50 @@ export function getNum(inputKey: string, defaultValue: number): number { return !!integer ? integer : defaultValue; }; -const config = { - production: { - db: { - db_driver: process.env.DATABASE_DRIVER || 'file', - db_fileName: 'burrito-prod.db', - db_path: process.env.DATABASE_PATH || `${root}data/`, - db_url: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_URL') : '', - db_name: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_DATABASE') : '', - db_uri: process.env.DATABASE_URI || `${process.env.MONGODB_URL}/${process.env.MONGODB_DATABASE}`, - }, - slack: { - bot_name: process.env.BOT_NAME || 'heyburrito', - api_token: mustHave('SLACK_API_TOKEN'), - emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), - emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), - disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), - dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), - dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), - enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), - }, - http: { - http_port: process.env.PORT || process.env.HTTP_PORT || 3333, - wss_port: process.env.WSS_PORT || 3334, - web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', - api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', - }, - theme: { - root: themeRootPath, - url: process.env.THEME_URL || defaultTheme, - path: process.env.THEME_PATH, - latest: getBool(process.env.THEME_LATEST, false), - themeName: getThemeName(), - themePath: getThemePath(), - }, - level: { - enableLevel: getBool(process.env.ENABLE_LEVEL, false), - scoreRotation: getNum(process.env.SCORE_ROTATION, 500) - }, - misc: { - slackMock: false, - log_level: process.env.LOG_LEVEL || 'info' - }, +const config: any = { + db: { + db_driver: process.env.DATABASE_DRIVER || 'file', + db_fileName: `burrito-${process.env.NODE_ENV}.db`, + db_path: process.env.DATABASE_PATH || `${root}data/`, + db_url: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_URL') : '', + db_name: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_DATABASE') : '', + db_uri: process.env.DATABASE_URI || `${process.env.MONGODB_URL}/${process.env.MONGODB_DATABASE}`, }, - development: { - db: { - db_driver: process.env.DATABASE_DRIVER || 'file', - db_fileName: 'burrito-dev.db', - db_path: process.env.DATABASE_PATH || `${root}data/`, - db_url: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_URL') : '', - db_name: (process.env.DATABASE_DRIVER === 'mongodb') ? mustHave('MONGODB_DATABASE') : '', - db_uri: process.env.DATABASE_URI || `${process.env.MONGODB_URL}/${process.env.MONGODB_DATABASE}`, - }, - slack: { - bot_name: process.env.BOT_NAME || 'heyburrito', - api_token: mustHave('SLACK_API_TOKEN'), - emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), - emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), - disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), - dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), - dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), - overdrawCap: getBool(process.env.ENABLE_OVERDRAW, false) ? getNum(process.env.SLACK_OVERDRAW_CAP, 5) : 0, - enableOverDraw: getBool(process.env.ENABLE_OVERDRAW, false), - enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), - }, - http: { - http_port: getNum(process.env.HTTP_PORT, 3333), - wss_port: getNum(process.env.WSS_PORT, 3334), - web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', - api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', - }, - theme: { - root: themeRootPath, - url: process.env.THEME_URL || defaultTheme, - path: process.env.THEME_PATH, - latest: getBool(process.env.THEME_LATEST, false), - themeName: getThemeName(), - themePath: getThemePath(), - }, - level: { - enableLevel: getBool(process.env.ENABLE_LEVEL, true), - scoreRotation: getNum(process.env.SCORE_ROTATION, 500) - }, - misc: { - slackMock: false, - log_level: process.env.LOG_LEVEL || 'debug' - }, + slack: { + bot_name: process.env.BOT_NAME || 'heyburrito', + bot_emoji: process.env.BOT_EMOJI || ':burrito:', + api_token: mustHave('SLACK_API_TOKEN'), + emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), + emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), + disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), + enableOverDraw: getBool(process.env.ENABLE_OVERDRAW, false), + enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), + dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), + dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), + overdrawCap: getBool(process.env.ENABLE_OVERDRAW, false) ? getNum(process.env.SLACK_OVERDRAW_CAP, 5) : 0, + slackMock: getBool(process.env.SLACK_MOCK, false), }, - testing: { - db: { - db_driver: process.env.DATABASE_DRIVER || 'file', - db_fileName: 'burrito-test.db', - db_path: process.env.DATABASE_PATH || `${root}data/`, - db_url: '', - db_name: '', - }, - slack: { - bot_name: process.env.BOT_NAME || 'heyburrito', - api_token: process.env.SLACK_API_TOKEN || '', - emojiInc: fixEmoji(process.env.SLACK_EMOJI_INC || ':burrito:'), - emojiDec: fixEmoji(process.env.SLACK_EMOJI_DEC || ':rottenburrito:'), - disableEmojiDec: getBool(process.env.DISABLE_EMOJI_DEC, false), - dailyCap: getNum(process.env.SLACK_DAILY_CAP, 5), - dailyDecCap: getNum(process.env.SLACK_DAILY_DEC_CAP, 5), - enableDecrement: getBool(process.env.ENABLE_DECREMENT, true), - overdrawCap: getBool(process.env.ENABLE_OVERDRAW, false) ? getNum(process.env.SLACK_OVERDRAW_CAP, 5) : 0, - enableOverDraw: getBool(process.env.ENABLE_OVERDRAW, false), - - }, - http: { - http_port: process.env.HTTP_PORT || 3333, - wss_port: process.env.WSS_PORT || 3334, - web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', - api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', - }, - theme: { - root: themeRootPath, - url: process.env.THEME_URL || defaultTheme, - path: process.env.THEME_PATH, - latest: getBool(process.env.THEME_LATEST, true), - themeName: getThemeName(), - themePath: getThemePath(), - }, - level: { - enableLevel: getBool(process.env.ENABLE_LEVEL, false), - scoreRotation: getNum(process.env.SCORE_ROTATION, 500) - }, - misc: { - slackMock: true, - log_level: process.env.LOG_LEVEL || 'debug' - }, + http: { + http_port: process.env.PORT || process.env.HTTP_PORT || 3333, + wss_port: process.env.WSS_PORT || 3334, + web_path: process.env.WEB_PATH ? fixPath(process.env.WEB_PATH) : '/heyburrito/', + api_path: process.env.API_PATH ? fixPath(process.env.API_PATH) : '/api/', }, -}; + theme: { + root: themeRootPath, + url: process.env.THEME_URL || defaultTheme, + path: process.env.THEME_PATH, + latest: getBool(process.env.THEME_LATEST, false), + themeName: getThemeName(), + themePath: getThemePath(), + }, + level: { + enableLevel: getBool(process.env.ENABLE_LEVEL, false), + scoreRotation: getNum(process.env.SCORE_ROTATION, 500) + }, + misc: { + log_level: process.env.LOG_LEVEL || 'info' + } +} -export default config[env] ? config[env] : config.development; +export default config; From a34e44d7f3e905b7cdbdf395688f85ae6326edd7 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:29:05 +0100 Subject: [PATCH 40/51] update --- src/handleBurritos.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/handleBurritos.ts b/src/handleBurritos.ts index a162b44..17e91e8 100644 --- a/src/handleBurritos.ts +++ b/src/handleBurritos.ts @@ -54,22 +54,18 @@ const handleUpdates = async (giver: string, updates: Updates[], scoreType: strin // Send right total in message, so we dont send - if overdrawn was disabled the same day. const messTotal = enableOverDraw ? dailyDiffTotal : dailyDiff; - console.log(!(dailyDiffTotal >= updates.length)) - console.log("dailyDiffTotal", dailyDiffTotal) + // Check if user can send all updates. - if(!(dailyDiffTotal >= updates.length)) return notifyUser(giver, `You are trying to give away ${updates.length} ${burritoType}, but you only have ${messTotal} ${burritoType} left today!`); + if (!(dailyDiffTotal >= updates.length)) return notifyUser({ channel: giver, text: `You are trying to give away ${updates.length} ${burritoType}, but you only have ${messTotal} ${burritoType} left today!` }); // Check if update.length exceeds dailyDiff - if(!(dailyDiff >= updates.length)) { - console.log("AHA?") + if (!(dailyDiff >= updates.length)) { /** * When overdraw we want to do a credit check of giver first. * Giver needs to be able to pay the bill. * ( Lowest userScore can be 0 ) */ const giverScore = await BurritoStore.getUserScore(giver, 'to', scoreType); - if (!(giverScore >= updates.length)) return notifyUser(giver, `Trying to give more ${burritoType}s then u have`); - console.log("AHA?2") - + if (!(giverScore >= updates.length)) return notifyUser({ channel: giver, text: `Trying to give more ${burritoType}s then u have` }); } /** @@ -80,7 +76,7 @@ const handleUpdates = async (giver: string, updates: Updates[], scoreType: strin // Get the rest entries and count them as overDrawn const overDrawnUpdates = updates.slice(dailyDiff); - console.log("overDrawnUpdates", overDrawnUpdates) + // When overdraw we want to add type overdrawn const updatesOverDrawn = overDrawnUpdates.map(({ ...all }) => ({ ...all, overdrawn: true })); return await giveBurritos(updatesOverDrawn); @@ -96,11 +92,10 @@ export const handleBurritos = async (giver: string, updates: Updates[]) => { * Type inc => dailyCap * Type dec => dailyDecCap */ if (enableDecrement) { - const givenToday = await BurritoStore.givenToday(giver, 'from'); + const givenToday = await BurritoStore.givenToday(giver, 'from', 'inc'); const diff = dailyCap - givenToday; - if (updates.length > diff) return notifyUser(giver, `You are trying to give away ${updates.length} burritos, but you only have ${diff} burritos left today!`); + if (updates.length > diff) return notifyUser({ channel: giver, text: `You are trying to give away ${updates.length} burritos, but you only have ${diff} burritos left today!` }); if (givenToday >= dailyCap) return false; - await giveBurritos(updates); } else { From d802450b5bfe9d01d9372bcd3c591e4c6a5287c0 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:30:39 +0100 Subject: [PATCH 41/51] Adding today as paramter to getScoreBoard --- src/middleware.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/middleware.ts b/src/middleware.ts index 988f9d5..bc627c7 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -25,9 +25,9 @@ const { * @param {string} scoretype - inc / dec * @param {string} listType - to / from */ -const getScoreBoard = async (listType: string, scoreType: string) => { +const getScoreBoard = async (listType: string, scoreType: string, today?: boolean) => { - const data = await BurritoStore.getScoreBoard({ listType }); + const data = await BurritoStore.getScoreBoard({ listType, today }); // Get unique Usernames const uniqueUsername: string[] = [...new Set(data.map((x) => x[listType]))]; From 223b771d6c047839838c40c20763dedc6fe0d164 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 5 Feb 2022 02:31:29 +0100 Subject: [PATCH 42/51] update --- src/store/BurritoStore.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 398e0f7..0ea82e1 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -2,7 +2,8 @@ import log from 'loglevel'; import { EventEmitter } from 'events'; import config from '../config'; import { listTypeSwitch } from '../lib/utils/switch'; -import {calculateScore} from './calc'; +import { calculateScore } from './calc'; +import { Updates } from '../lib/parseMessage'; import Driver, { GetScoreBoard, DatabasePost, @@ -16,13 +17,6 @@ interface GetUserStats { givenToday: number; } -interface BurritoUpdate { - to: string; - from: string; - type: string; - overdrawn?: boolean; -} - class BurritoStore extends EventEmitter { database: Driver; @@ -32,7 +26,7 @@ class BurritoStore extends EventEmitter { this.database = database; }; - public async give({ to, from, type, overdrawn }: BurritoUpdate): Promise { + public async give({ to, from, type, overdrawn }: Updates): Promise { const score = { to, from, From 5c3aba9e9bfbe5a47899f29dccd7df27799cd7a4 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 30 Apr 2022 19:58:52 +0200 Subject: [PATCH 43/51] update --- .dockerignore | 3 + Dockerfile | 4 +- package.json | 1 + src/bot/interaction.ts | 47 ++-- src/config/index.ts | 4 +- src/database/drivers/MongoDBDriver.ts | 251 +++++++++++----------- src/lib/themeHandler.ts | 2 - src/middleware.ts | 9 +- src/server.ts | 6 +- src/slack/Wbc.ts | 5 +- src/store/BurritoStore.ts | 1 - test/.testing.env | 9 + test/bot.test.ts | 14 +- test/burritostore.ts | 8 +- test/calc.test.ts | 2 +- test/handleBurritos.test.ts | 36 +--- test/lib/database/index.ts | 2 - test/lib/database/init-database-driver.ts | 16 +- test/lib/slack/slack-mock.ts | 6 + test/setup.ts | 2 + 20 files changed, 214 insertions(+), 214 deletions(-) create mode 100644 test/.testing.env diff --git a/.dockerignore b/.dockerignore index b3cfbbb..2ce52f3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -29,3 +29,6 @@ conf-localhost.json .filedb .env + +# ignore all node_modules, no matter where, like when having a monorepo +**/node_modules diff --git a/Dockerfile b/Dockerfile index e56b990..dbf4191 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ FROM node:gallium -RUN apt-get update && apt-get install -y +RUN apt-get update && apt-get install libcurl4 -y RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY package.json /usr/src/app/ -RUN npm install --production +RUN npm install COPY . /usr/src/app CMD [ "npm", "start" ] diff --git a/package.json b/package.json index db94e25..97d3b36 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dev": "NODE_ENV=development nodemon --ignore '/test/*.ts' --watch '*.ts' --exec 'ts-node' ./src/server.ts", "mockDB": "ts-node ./test/lib/mockDatabase.ts", "test": "NODE_ENV=testing jest", + "test-docker": "docker build -t chralp/heyburrito . && docker run -e NODE_ENV=testing chralp/heyburrito npm run test", "lint": "eslint --ext .ts ./src/ || exit 0", "docker-build": "docker build -t chralp/heyburrito . && docker tag chralp/heyburrito chralp/heyburrito", "docker-push": "docker push chralp/heyburrito" diff --git a/src/bot/interaction.ts b/src/bot/interaction.ts index 0084781..761d56b 100644 --- a/src/bot/interaction.ts +++ b/src/bot/interaction.ts @@ -13,10 +13,9 @@ const parseCommands = (text) => { /** * Send message back to user or channel */ -export const notifyUser = (args: SendDM) => Wbc.sendDM(args); - -export const handleInteraction = ({ user, channel, text }) => { +export const notifyUser = async (args: SendDM) => Wbc.sendDM(args); +export const handleInteraction = async ({ user, channel, text }) => { const res = parseCommands(text); if (!res.length) { @@ -24,24 +23,28 @@ export const handleInteraction = ({ user, channel, text }) => { return notifyUser({ user, channel, blocks, text: ' ' }) } - res.forEach(async (cmd) => { - switch (cmd) { - case 'help': { - const { blocks } = tmplHelp(); - return notifyUser({ user, channel, blocks, text: ' ' }); - } - case 'emojis': { - const { blocks } = tmplEmoji(); - return notifyUser({ user, channel, blocks, text: ' ' }); - } - case 'top5': { - const { blocks } = await tmplToplist({ listType: 'to', amount: 5 }) - return notifyUser({ user, channel, blocks, text: ' ' }); - } - default: { - const { blocks } = tmplHelp(); - return notifyUser({ user, channel, blocks, text: ' ' }); + return res.reduce(async (prev: any, cmd: string) => { + return prev.then(async () => { + switch (cmd) { + case 'help': { + const { blocks } = tmplHelp(); + return notifyUser({ user, channel, blocks, text: ' ' }); + } + case 'emojis': { + const { blocks } = tmplEmoji(); + return notifyUser({ user, channel, blocks, text: ' ' }); + } + case 'top5': { + const { blocks } = await tmplToplist({ listType: 'to', amount: 5 }) + console.log("Blocks", blocks) + if(!(blocks[0]?.text?.text.length < 0)) return false; + return notifyUser({ user, channel, blocks, text: ' ' }); + } + default: { + const { blocks } = tmplHelp(); + return await notifyUser({ user, channel, blocks, text: ' ' }); + } } - } - }); + }); + }, Promise.resolve()); }; diff --git a/src/config/index.ts b/src/config/index.ts index a3901cb..067ff19 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,6 +1,6 @@ import { env, mustHave } from '../lib/utils/env'; -import { getThemePath, getThemeName, themeRootPath, defaultTheme} from '../lib/utils/theme'; -import { fixPath, root} from '../lib/utils/path'; +import { getThemePath, getThemeName, themeRootPath, defaultTheme } from '../lib/utils/theme'; +import { fixPath, root } from '../lib/utils/path'; const isFalse = (input: string) => (input === 'false' || input === 'no' || input === '0'); diff --git a/src/database/drivers/MongoDBDriver.ts b/src/database/drivers/MongoDBDriver.ts index e5510f2..867e979 100644 --- a/src/database/drivers/MongoDBDriver.ts +++ b/src/database/drivers/MongoDBDriver.ts @@ -1,144 +1,145 @@ import { time } from '../../lib/utils/time'; - +import Driver, { GivePost } from './Driver'; const mongoConf = { - useNewUrlParser: true, - useUnifiedTopology: true, + useNewUrlParser: true, + useUnifiedTopology: true, }; interface Find { - _id: string; - to: string; - from: string; - value: number; - given_at: Date; + _id: string; + to: string; + from: string; + value: number; + given_at: Date; } interface Sum { - _id?: string; // Username - score?: number; + _id?: string; // Username + score?: number; } -class MongoDBDriver { - constructor( - public MongoClient: any, - public conf: any = {}, - public client = null, - public db = null, - ) { } - - async connect() { - if (this.client && this.client.isConnected()) { - return this.client; - } - - try { - const client = await this.MongoClient.connect(`${this.conf.db_uri}`, mongoConf); - this.client = client; - this.db = client.db(this.conf.db_database); - return true; - } catch (e) { - throw new Error('Could not connect to Mongodb server'); - } - } - - async store(collection: string, data: Object) { - await this.connect(); - return this.db.collection(collection).insertOne(data); - } - - give(to: string, from: string, date: any) { - return this.store('burritos', { - to, - from, - value: 1, - given_at: date, - }); - } - - takeAway(to: string, from: string, date: any) { - return this.store('burritos', { - to, - from, - value: -1, - given_at: date, - }); - } - - /** - * @param { string } collection - like burrito - * @param { Object } query - searchObject to search for - * @return { Find[] } - */ - async find(collection: string, query: Object): Promise { - await this.connect(); - return this.db.collection(collection).find(query).toArray(); +class MongoDBDriver implements Driver { + constructor( + public MongoClient: any, + public conf: any = {}, + public client = null, + public db = null, + ) { } + + async connect() { + if (this.client) { + return this.client; } - /** - * @param { string } collection - burrito - * @param { string | null } match - matchObject to search for - * @param { string } listType - defaults to 'to' - * @return { Object } sum[] - data - */ - async sum(collection: string, match: Object = null, listType: string): Promise { - await this.connect(); - const aggregations: Array = [{ $match: { to: { $exists: true } } }]; - if (match) { - aggregations.push({ $match: match }); - } - aggregations.push({ $group: { _id: listType, score: { $sum: '$value' } } }); - aggregations.push({ $sort: { score: -1 } }); - return this.db.collection(collection).aggregate(aggregations).toArray(); + try { + const client = await this.MongoClient.connect(`${this.conf.db_uri}`, mongoConf); + this.client = client; + this.db = client.db(this.conf.db_database); + return true; + } catch (e) { + throw new Error('Could not connect to Mongodb server'); } - - /** - * Finds all entrys associated to user today - * @params { string } user => userid - * @params { string } listtype => to / from - * @returns {Find[]} - */ - findFromToday(user: string, listType: string): Promise { - return this.find('burritos', { - [listType]: user, - given_at: { - $gte: time().start, - $lt: time().end, - }, - }); + } + + async store(collection: string, data: Object) { + await this.connect(); + return this.db.collection(collection).insertOne(data); + } + + // give(to: string, from: string, date: any) { + // return this.store('burritos', { + // to, + // from, + // value: 1, + // given_at: date, + // }); + // } + + + async give({ ...score }: GivePost) { + return this.store('burritos', { + ...score + }); + } + takeAway(to: string, from: string, date: any) { + return this.store('burritos', { + to, + from, + value: -1, + given_at: date, + }); + } + + /** + * @param { string } collection - like burrito + * @param { Object } query - searchObject to search for + * @return { Find[] } + */ + async find(collection: string, query: Object): Promise { + await this.connect(); + return this.db.collection(collection).find(query).toArray(); + } + + /** + * @param { string } collection - burrito + * @param { string | null } match - matchObject to search for + * @param { string } listType - defaults to 'to' + * @return { Object } sum[] - data + */ + async sum(collection: string, match: Object = null, listType: string): Promise { + await this.connect(); + const aggregations: Array = [{ $match: { to: { $exists: true } } }]; + if (match) { + aggregations.push({ $match: match }); } - - /** - * Return specific userScore - * @param {string} user - userId - * @param {string} listType - to / from - * @return {Object} sum[] - */ - async getScore(user: string, listType: string, num = false) { - const match = { [listType]: user }; - - if (num) { - const data = await this.sum('burritos', match, listType); - return data.length ? data[0].score : 0; - } - return this.find('burritos', match); + aggregations.push({ $group: { _id: listType, score: { $sum: '$value' } } }); + aggregations.push({ $sort: { score: -1 } }); + return this.db.collection(collection).aggregate(aggregations).toArray(); + } + + /** + * Finds all entrys associated to user today + * @params { string } user => userid + * @params { string } listtype => to / from + * @returns {Find[]} + */ + findFromToday(user: string, listType: string): Promise { + return this.find('burritos', { + [listType]: user, + given_at: { + $gte: time().start, + $lt: time().end, + }, + }); + } + + /** + * Return specific userScore + * @param {string} user - userId + * @param {string} listType - to / from + * @return {Object} sum[] + */ + async getScore(user: string, listType: string) { + const match = { [listType]: user }; + return this.find('burritos', match); + } + + /** + * Returns scoreboard + * Should be able to return burrito List ( scoreType inc ) and + * listtype ( dec ) AKA rottenburritoList + */ + async getScoreBoard({ user, listType, today }) { + let match: any = {}; + + if (user) { + match = (listType === 'from') ? { to: user } : { from: user }; } - - /** - * Returns scoreboard - * Should be able to return burrito List ( scoreType inc ) and - * listtype ( dec ) AKA rottenburritoList - */ - async getScoreBoard({ user, listType, today }) { - let match: any = {}; - - if (user) { - match = (listType === 'from') ? { to: user } : { from: user }; - } - if (today) { - match.given_at = { $gte: time().start, $lt: time().end }; - } - return this.find('burritos', match); + if (today) { + match.given_at = { $gte: time().start, $lt: time().end }; } + return this.find('burritos', match); + } } export default MongoDBDriver; diff --git a/src/lib/themeHandler.ts b/src/lib/themeHandler.ts index 5b5599d..dd362cf 100644 --- a/src/lib/themeHandler.ts +++ b/src/lib/themeHandler.ts @@ -8,14 +8,12 @@ let times = 0; async function gitFunc(args, cwd: string) { const [option, url] = args; - console.log(args,cwd) if (option === 'clone') log.info('Cloning theme:', url); if (option === 'pull') log.info('Pulling latest theme:', url); return new Promise((resolve, reject) => { const process = spawn('git', args, { cwd }); process.on('close', (status: any) => { - console.log(status) if (status === 0) { resolve(true); } else { diff --git a/src/middleware.ts b/src/middleware.ts index bc627c7..f61aaf7 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -16,7 +16,6 @@ const { } = config; - /** * Middleware for API and Websocket */ @@ -31,16 +30,10 @@ const getScoreBoard = async (listType: string, scoreType: string, today?: boolea // Get unique Usernames const uniqueUsername: string[] = [...new Set(data.map((x) => x[listType]))]; - console.log(uniqueUsername) const scoreList = uniqueUsername .map((user) => ({ _id: user, score: calculateScore(data, data, { listType, scoreType, user}) })) .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); - - console.log("scoreList", scoreList) - const handledScore = enableLevel ? sort(mapper(levelScoreList(scoreList))) : sort(mapper(scoreList)); - console.log("enableLevel", enableLevel) - console.log("handledScore", handledScore) - return handledScore + return enableLevel ? sort(mapper(levelScoreList(scoreList))) : sort(mapper(scoreList)); }; const _getUserScoreBoard = async ({ ...args }) => { diff --git a/src/server.ts b/src/server.ts index 14637f5..03bb384 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,8 +1,8 @@ import dotenv from 'dotenv'; /* eslint-disable import/first */ -const envPath = process.env.NODE_ENV ? `.env.${process.env.NODE_ENV}` : '.env'; -dotenv.config({ path: envPath }); - +// const envPath = process.env.NODE_ENV ? `.env.${process.env.NODE_ENV}` : '.env'; +// dotenv.config({ path: envPath }); +dotenv.config() import log from 'loglevel'; import http from 'http'; import BurritoStore from './store/BurritoStore'; diff --git a/src/slack/Wbc.ts b/src/slack/Wbc.ts index 4c4dc71..32b2f0d 100644 --- a/src/slack/Wbc.ts +++ b/src/slack/Wbc.ts @@ -45,12 +45,15 @@ class Wbc { const user = args.user ? args.user : args.channel; const res = await this.wbc.chat.postMessage({ ...args, - username: config.slack.bot_name, + username: config.slack.bot_name || 'heyburrito', icon_emoji: config.slack.bot_emoji || ':burre:', }); if (res.ok) { log.info(`Notified user ${user}`); + } else { + log.info(`Could not notify ${user}`); } + return res; } } diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 0ea82e1..8ae97a5 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -81,7 +81,6 @@ class BurritoStore extends EventEmitter { const givenToday = await this.database.findFromToday(user, listType); if (scoreType && ['inc', 'dec'].includes(scoreType)) { const scoreTypeFilter = (scoreType === 'inc') ? 1 : -1; - //console.log(listType, scoreType,givenToday) const givenFilter = givenToday.filter((x) => { if (x.value === scoreTypeFilter) { if(overdrawn) return !!x.overdrawn diff --git a/test/.testing.env b/test/.testing.env new file mode 100644 index 0000000..e5c1e46 --- /dev/null +++ b/test/.testing.env @@ -0,0 +1,9 @@ +BOT_NAME=heyburrito +THEME=default +DATABASE_DRIVER=file +MONGODB_URL="mongodb://localhost:27017" +MONGODB_DATABASE=heyburrito +SLACK_DAILY_CAP=5 +SLACK_EMOJI_INC=:burrito:,:burre: +SLACK_EMOJI_DEC=:rottenburrito: +SLACK_MOCK=true diff --git a/test/bot.test.ts b/test/bot.test.ts index e7d8b29..b01924a 100644 --- a/test/bot.test.ts +++ b/test/bot.test.ts @@ -1,15 +1,19 @@ +import { initSlack } from './lib/slack'; import { handleInteraction } from '../src/bot/interaction'; -describe('bot', () => { +import * as config from '../src/config'; +initSlack() +describe('bot', () => { describe('handleInteraction', () => { it('should match help and return list of commands to user / channel', async () => { + config.default.slack = { slackMock: true } const message = { - text: " help" + text: "USER1 help", + user: "USER1", + channel: "" }; const res = await handleInteraction(message); - console.log("IN TEST", res); + expect(res).toEqual({"user":"USER1","channel":"","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"Available commands:"}},{"type":"section","text":{"type":"mrkdwn","text":"@heyburrito "}},{"type":"divider"},{"type":"section","text":{"type":"mrkdwn","text":"*help* - Show all available commands\n*emojis* - Show all available emojis\n*top5* - Show top5 list today \n - *to* - Return list of top5 receiver\n - *from* - Return list of top5 sender"}}],"text":" ","username":"heyburrito","icon_emoji":":burre:"}) }); - }); - }); diff --git a/test/burritostore.ts b/test/burritostore.ts index e5df61a..fef0510 100644 --- a/test/burritostore.ts +++ b/test/burritostore.ts @@ -5,10 +5,10 @@ let mongod: any, mongoDriver: any; describe('Burritostore-test', () => { [ - // { - // describe: 'file Driver', - // driver: 'file' - // }, + { + describe: 'file Driver', + driver: 'file' + }, { describe: 'Array Driver', driver: 'array' diff --git a/test/calc.test.ts b/test/calc.test.ts index 396957e..7721ed9 100644 --- a/test/calc.test.ts +++ b/test/calc.test.ts @@ -666,7 +666,7 @@ describe('calculateScore', () => { }); it('with ENVS: { enableOverDraw: true, enableDecrement: true }', async () => { - config.default.slack = { enableOverDraw: true, enableDecrement: true } + config.default.slack = { enableOverDraw: true, enableDecrement: true, slackMock: true} const scoreList = getScore({ listType, scoreType }) expect(scoreList).toEqual([ { _id: 'USER2', score: 2 }, diff --git a/test/handleBurritos.test.ts b/test/handleBurritos.test.ts index 2b1a90a..067ab39 100644 --- a/test/handleBurritos.test.ts +++ b/test/handleBurritos.test.ts @@ -15,14 +15,14 @@ describe('handleBurritos-test', () => { describe: 'file Driver', driver: 'file' }, -// { - // describe: 'Array Driver', - // driver: 'array' - // }, - // // { - // describe: 'Mongodb Driver', - // driver: 'mongodb' - // }, + { + describe: 'Array Driver', + driver: 'array' + }, + { + describe: 'Mongodb Driver', + driver: 'mongodb' + }, ].forEach((test) => { describe(test.describe, () => { @@ -159,26 +159,6 @@ describe('handleBurritos-test', () => { expect(giverDataDec).toEqual(0); }); }); - - - - - - - - - - - - - - - - - - - - }); }); }); diff --git a/test/lib/database/index.ts b/test/lib/database/index.ts index adea9d5..286eb86 100644 --- a/test/lib/database/index.ts +++ b/test/lib/database/index.ts @@ -1,5 +1,3 @@ -import * as dotenv from 'dotenv'; -dotenv.config(); import { initDatabase, seedDatabase } from './init-database-driver'; async function init({ driver }) { diff --git a/test/lib/database/init-database-driver.ts b/test/lib/database/init-database-driver.ts index 89d0061..9625d4e 100644 --- a/test/lib/database/init-database-driver.ts +++ b/test/lib/database/init-database-driver.ts @@ -1,5 +1,3 @@ -import * as dotenv from 'dotenv'; -dotenv.config(); import fs from 'fs'; import { MongoMemoryServer } from 'mongodb-memory-server'; import BurritoStore from '../../../src/store/BurritoStore'; @@ -13,7 +11,6 @@ import { randomDate } from '../time' // await give(toUser, fromUser, pickRandomDate(oneWeek, today)); export const initDatabase = async ({ driver }) => { - if (env === 'testing' && driver === 'file') { if (!pathExists(config.db.db_path)) { if (!createPath(config.db.db_path)) { @@ -28,11 +25,14 @@ export const initDatabase = async ({ driver }) => { }; if (env === 'testing' && driver === 'mongodb') { - // let mongod = new MongoMemoryServer(); - // const uri = await mongod.getConnectionString(); - // const database = await mongod.getDbName(); - // const mongoDriver = databaseDrivers[driver]({ db_uri: uri, db_name: database }); - // BurritoStore.setDatabase(mongoDriver); + + const mongo = await MongoMemoryServer.create(); + const uri = mongo.getUri(); + + const database = databaseDrivers[driver]({ db_uri: uri });// db_name: database + BurritoStore.setDatabase(database); + return Promise.resolve({ driver, database, mongod: mongo, mongoDriver: database }) + } else { const database = databaseDrivers[driver](); BurritoStore.setDatabase(database); diff --git a/test/lib/slack/slack-mock.ts b/test/lib/slack/slack-mock.ts index ff57ab4..15aa205 100644 --- a/test/lib/slack/slack-mock.ts +++ b/test/lib/slack/slack-mock.ts @@ -24,5 +24,11 @@ export class WEBMock { postMessage: (data) => { return Promise.resolve(data) } + } + sendDM = { + postMessage: (data) => { + return Promise.resolve(data) + } }; + } diff --git a/test/setup.ts b/test/setup.ts index 2439a10..10c5b7a 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,3 +1,5 @@ +import dotenv from 'dotenv'; +dotenv.config({ path: './test/.testing.env' }); global.console.warn = jest.fn(); global.console.debug = jest.fn(); From f24da54a2ae6aac5ddcc1cf8633866202081a846 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sat, 30 Apr 2022 21:19:42 +0200 Subject: [PATCH 44/51] update --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 37f7443..2ccbe9a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,7 @@ services: - MONGODB_DATABASE=heyburrito - SLACK_API_TOKEN=SeeDocumentation - "SLACK_EMOJI_INC=:burrito:" - - "SLACK_EMOJI_INC=:rottenburrito:" + - "SLACK_EMOJI_DEC=:rottenburrito:" - SLACK_DAILY_CAP=5 links: - mongodb From fbe07e036957761fff44abe3c0d934da07ae810f Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 1 May 2022 17:58:44 +0200 Subject: [PATCH 45/51] upgrade to gallium --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index e1fcd1e..53d838a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -lts/erbium +lts/gallium From e21ddf643507bd2054c15b3ed74d2711e00fe2af Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 1 May 2022 18:14:21 +0200 Subject: [PATCH 46/51] formatting --- src/bot/interaction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bot/interaction.ts b/src/bot/interaction.ts index 761d56b..a423421 100644 --- a/src/bot/interaction.ts +++ b/src/bot/interaction.ts @@ -37,7 +37,7 @@ export const handleInteraction = async ({ user, channel, text }) => { case 'top5': { const { blocks } = await tmplToplist({ listType: 'to', amount: 5 }) console.log("Blocks", blocks) - if(!(blocks[0]?.text?.text.length < 0)) return false; + if (!(blocks[0]?.text?.text.length < 0)) return false; return notifyUser({ user, channel, blocks, text: ' ' }); } default: { From f0251a147eba338bbb8e9b9a922eba3f92b9947c Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 1 May 2022 18:15:03 +0200 Subject: [PATCH 47/51] remove code to load diffrent .env files --- src/server.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/server.ts b/src/server.ts index 03bb384..4a700f1 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,7 +1,5 @@ import dotenv from 'dotenv'; /* eslint-disable import/first */ -// const envPath = process.env.NODE_ENV ? `.env.${process.env.NODE_ENV}` : '.env'; -// dotenv.config({ path: envPath }); dotenv.config() import log from 'loglevel'; import http from 'http'; From 42cba24f51476985b1a38881c43e410877a786c0 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 1 May 2022 18:15:19 +0200 Subject: [PATCH 48/51] formatting --- src/middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware.ts b/src/middleware.ts index f61aaf7..d39943c 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -31,7 +31,7 @@ const getScoreBoard = async (listType: string, scoreType: string, today?: boolea // Get unique Usernames const uniqueUsername: string[] = [...new Set(data.map((x) => x[listType]))]; const scoreList = uniqueUsername - .map((user) => ({ _id: user, score: calculateScore(data, data, { listType, scoreType, user}) })) + .map((user) => ({ _id: user, score: calculateScore(data, data, { listType, scoreType, user }) })) .map((entry) => (entry.score !== 0) ? entry : null).filter(y => y); return enableLevel ? sort(mapper(levelScoreList(scoreList))) : sort(mapper(scoreList)); }; From a68bed8b40adad822d73cbab34d6f93df95b3df0 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 1 May 2022 18:15:40 +0200 Subject: [PATCH 49/51] formatting --- src/store/BurritoStore.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/store/BurritoStore.ts b/src/store/BurritoStore.ts index 8ae97a5..8fa2253 100644 --- a/src/store/BurritoStore.ts +++ b/src/store/BurritoStore.ts @@ -67,8 +67,8 @@ class BurritoStore extends EventEmitter { receivedToday, givenToday, _id: user, - received: calculateScore(received, [],{}), - given: calculateScore(given, [],{}) + received: calculateScore(received, [], {}), + given: calculateScore(given, [], {}) }; }; @@ -83,7 +83,7 @@ class BurritoStore extends EventEmitter { const scoreTypeFilter = (scoreType === 'inc') ? 1 : -1; const givenFilter = givenToday.filter((x) => { if (x.value === scoreTypeFilter) { - if(overdrawn) return !!x.overdrawn + if (overdrawn) return !!x.overdrawn return !x.overdrawn }; }); From 9f241fd6d79c762e47eaa0839dddc725a390e543 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 1 May 2022 18:15:59 +0200 Subject: [PATCH 50/51] formatting --- src/database/drivers/GenericDriver.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/database/drivers/GenericDriver.ts b/src/database/drivers/GenericDriver.ts index 1ed429c..05afd6f 100644 --- a/src/database/drivers/GenericDriver.ts +++ b/src/database/drivers/GenericDriver.ts @@ -4,9 +4,9 @@ import Driver, { GivePost } from './Driver'; import { time } from '../../lib/utils/time'; function id() { - // Cred => https://gist.github.com/gordonbrander/2230317 - const str: string = Math.random().toString(36).substr(2, 9); - return `_${str}`; + // Cred => https://gist.github.com/gordonbrander/2230317 + const str: string = Math.random().toString(36).substr(2, 9); + return `_${str}`; } class GenericDriver extends Store implements Driver { From f89f8530803b25ac17adfe038f3aacba7b7f3813 Mon Sep 17 00:00:00 2001 From: Christian Lind Alpstad Date: Sun, 1 May 2022 18:16:32 +0200 Subject: [PATCH 51/51] remove old give function --- src/database/drivers/MongoDBDriver.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/database/drivers/MongoDBDriver.ts b/src/database/drivers/MongoDBDriver.ts index 867e979..9a39cf9 100644 --- a/src/database/drivers/MongoDBDriver.ts +++ b/src/database/drivers/MongoDBDriver.ts @@ -46,16 +46,6 @@ class MongoDBDriver implements Driver { return this.db.collection(collection).insertOne(data); } - // give(to: string, from: string, date: any) { - // return this.store('burritos', { - // to, - // from, - // value: 1, - // given_at: date, - // }); - // } - - async give({ ...score }: GivePost) { return this.store('burritos', { ...score