diff --git a/.gitignore b/.gitignore index bb68e9a3..576fdaee 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ dist src/package.json .eslintcache .DS_Store +upload-docs* \ No newline at end of file diff --git a/README.md b/README.md index 73f4975f..afdd4faa 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ Variable | Description | Sample `WORKER_PRIVATE_KEY` | A string used to two-way encryption sensitive data passed to workers. Recommend to be different from `COOKIE_PRIVATE_KEY`. Production values need to be a secret. Suggest `uuidgen` to generate | `2b57pd5e-f272-og90-8u97-89a7589a7f23` `INTERFACE` | Interface to bind to. Leave as '0.0.0.0' for prod, suggest '127.0.0.1' for development | `127.0.0.1` `CHT_DEV_URL_PORT` | CHT instance when in `NODE_ENV===dev`. Needs URL and port | `192-168-1-26.local-ip.medicmobile.org:10463` -`CHT_DEV_HTTP` | 'false' for http 'true' for https | `false` +`CHT_DEV_HTTP` | 'true' for http 'false' for https | `false` `REDIS_HOST` | Redis server hostname use 'redis' for docker | `redis` `REDIS_PORT` | Redis server port | `6379` `CHT_USER_MANAGEMENT_IMAGE` | docker image for cht-user-management service (local development), leave empty to use published one | `cht-user-management:local ` diff --git a/docker-local-setup.sh b/docker-local-setup.sh index ca5bba0c..5fffceca 100755 --- a/docker-local-setup.sh +++ b/docker-local-setup.sh @@ -22,6 +22,6 @@ to build missing images";echo; fi echo;echo "Starting Docker Compose...";echo -CHT_USER_MANAGEMENT_IMAGE=cht-user-management:local CHT_USER_MANAGEMENT_WORKER_IMAGE=cht-user-management-worker:local docker compose up -d +CHT_USER_MANAGEMENT_IMAGE=cht-user-management:local CHT_USER_MANAGEMENT_WORKER_IMAGE=cht-user-management-worker:local docker compose up echo;echo "Server is now running at http://127.0.0.1:$EXTERNAL_PORT/login";echo diff --git a/package-lock.json b/package-lock.json index 7ff335fb..cb95915d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cht-user-management", - "version": "1.4.2", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cht-user-management", - "version": "1.4.2", + "version": "2.0.0", "license": "ISC", "dependencies": { "@bull-board/api": "^5.17.0", @@ -24,11 +24,12 @@ "@types/lodash": "^4.14.201", "@types/luxon": "^3.4.2", "@types/node": "^20.8.8", + "@types/semver": "^7.5.8", "@types/uuid": "^9.0.6", "axios": "^1.5.1", "axios-retry": "^4.0.0", "bullmq": "^5.7.6", - "cht-conf": "^3.23.0", + "cht-conf": "github:medic/cht-conf#653-merge-primaries", "csv": "^6.3.5", "dotenv": "^16.3.1", "fastify": "^4.27.0", @@ -73,110 +74,11 @@ }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.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==", - "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==", - "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==", - "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": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "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": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@bull-board/api": { "version": "5.21.1", "resolved": "https://registry.npmjs.org/@bull-board/api/-/api-5.21.1.tgz", @@ -253,7 +155,6 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", - "dev": true, "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" @@ -267,7 +168,6 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.10.0", - "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -275,7 +175,6 @@ }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -297,7 +196,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/ajv": { "version": "6.12.6", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -312,7 +210,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -321,12 +218,10 @@ }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -337,12 +232,19 @@ }, "node_modules/@eslint/js": { "version": "8.57.0", - "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ewoudenberg/difflib": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@ewoudenberg/difflib/-/difflib-0.1.0.tgz", + "integrity": "sha512-OU5P5mJyD3OoWYMWY+yIgwvgNS9cFAU10f+DDuvtogcWQOoJIsQ4Hy2McSfUfhKjq8L0FuWVb4Rt7kgA+XK86A==", + "dependencies": { + "heap": ">= 0.2.0" + } + }, "node_modules/@fastify/accept-negotiator": { "version": "1.1.0", "license": "MIT", @@ -531,7 +433,6 @@ }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", - "dev": true, "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", @@ -544,7 +445,6 @@ }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { "version": "1.1.11", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -553,7 +453,6 @@ }, "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { "version": "3.1.2", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -564,7 +463,6 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -576,7 +474,6 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.2", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/@ioredis/commands": { @@ -666,6 +563,28 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -674,6 +593,32 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -795,7 +740,6 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -807,7 +751,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -815,7 +758,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -1157,6 +1099,14 @@ "dev": true, "license": "(Unlicense OR Apache-2.0)" }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -1206,6 +1156,29 @@ "commander": "*" } }, + "node_modules/@types/eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, "node_modules/@types/html-minifier": { "version": "4.0.5", "license": "MIT", @@ -1252,11 +1225,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/q": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", - "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" - }, "node_modules/@types/relateurl": { "version": "0.2.33", "license": "MIT" @@ -1268,8 +1236,8 @@ }, "node_modules/@types/semver": { "version": "7.5.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" }, "node_modules/@types/sinon": { "version": "17.0.3", @@ -1493,163 +1461,136 @@ }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", - "dev": true, "license": "ISC" }, "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" - }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dependencies": { - "@webassemblyjs/ast": "1.9.0" + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -1686,8 +1627,9 @@ "license": "MIT" }, "node_modules/acorn": { - "version": "8.11.3", - "license": "MIT", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "bin": { "acorn": "bin/acorn" }, @@ -1714,14 +1656,11 @@ } }, "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==", - "dependencies": { - "debug": "4" - }, + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -1738,14 +1677,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "peerDependencies": { - "ajv": ">=5.0.0" - } - }, "node_modules/ajv-formats": { "version": "2.1.1", "license": "MIT", @@ -1769,31 +1700,6 @@ "node": ">=6" } }, - "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==", - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "license": "MIT", @@ -1816,7 +1722,7 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "devOptional": true, + "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -1826,11 +1732,6 @@ "node": ">= 8" } }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, "node_modules/archy": { "version": "1.0.0", "license": "MIT" @@ -1842,7 +1743,6 @@ }, "node_modules/argparse": { "version": "2.0.1", - "dev": true, "license": "Python-2.0" }, "node_modules/argsarray": { @@ -1850,45 +1750,6 @@ "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", "integrity": "sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg==" }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array-union": { "version": "2.1.0", "dev": true, @@ -1897,55 +1758,6 @@ "node": ">=8" } }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.reduce": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz", - "integrity": "sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-array-method-boxes-properly": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -1962,30 +1774,6 @@ "safer-buffer": "~2.1.0" } }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/assert": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", - "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", - "dependencies": { - "object.assign": "^4.1.4", - "util": "^0.10.4" - } - }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -1994,19 +1782,6 @@ "node": ">=0.8" } }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dependencies": { - "inherits": "2.0.3" - } - }, "node_modules/assertion-error": { "version": "1.1.0", "dev": true, @@ -2015,38 +1790,10 @@ "node": "*" } }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "optional": true + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, "node_modules/async-retry": { "version": "1.3.3", @@ -2060,17 +1807,6 @@ "version": "0.4.0", "license": "MIT" }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/atomic-sleep": { "version": "1.0.0", "license": "MIT", @@ -2078,20 +1814,6 @@ "node": ">=8.0.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/avvio": { "version": "8.3.0", "license": "MIT", @@ -2138,46 +1860,6 @@ "version": "1.0.2", "license": "MIT" }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/base64-js": { "version": "1.5.1", "funding": [ @@ -2204,14 +1886,6 @@ "tweetnacl": "^0.14.3" } }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -2222,35 +1896,16 @@ }, "node_modules/binary-extensions": { "version": "2.2.0", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bintrees": { "version": "1.0.2", "license": "MIT" }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -2273,117 +1928,40 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, "node_modules/browser-stdout": { "version": "1.3.1", "dev": true, "license": "ISC" }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", - "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.5", - "hash-base": "~3.0", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.7", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">= 0.12" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream/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==" - }, - "node_modules/browserify-sign/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/browserify-sign/node_modules/string_decoder/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==" - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dependencies": { - "pako": "~1.0.5" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, "node_modules/buffer": { @@ -2416,16 +1994,6 @@ "version": "1.1.2", "license": "MIT" }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" - }, "node_modules/bullmq": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.12.0.tgz", @@ -2440,104 +2008,33 @@ "uuid": "^9.0.0" } }, - "node_modules/cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dependencies": { - "minimist": "^1.2.6" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/cacache/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" + "engines": { + "node": ">= 0.4" }, - "bin": { - "rimraf": "bin.js" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cacache/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "node_modules/cacache/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/cache-base": { + "node_modules/call-bind-apply-helpers": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", "dependencies": { - "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { @@ -2566,6 +2063,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/canonical-json": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/canonical-json/-/canonical-json-0.0.4.tgz", @@ -2639,11 +2155,6 @@ "node": ">=8" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, "node_modules/check-error": { "version": "1.0.3", "dev": true, @@ -2657,7 +2168,7 @@ }, "node_modules/chokidar": { "version": "3.5.3", - "devOptional": true, + "dev": true, "funding": [ { "type": "individual", @@ -2695,11 +2206,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -2709,45 +2215,45 @@ } }, "node_modules/cht-conf": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/cht-conf/-/cht-conf-3.23.0.tgz", - "integrity": "sha512-2ZuTo0hiunBwXhjLsWTPv7W7cAyEwz9Mwy3HqqI+BOOlCLD/cW7nyt5J1Elw58D5Q83hQ+RMB0hHa1qO+SDv/Q==", + "version": "4.4.0", + "resolved": "git+ssh://git@github.com/medic/cht-conf.git#3d957c5df40954cb3d86f091876d01d6089a8106", + "license": "AGPL-3.0-only", "dependencies": { - "@medic/translation-checker": "^1.0.1", - "@parcel/watcher": "^2.0.5", + "@medic/translation-checker": "^1.1.0", + "@parcel/watcher": "^2.1.0", "@xmldom/xmldom": "^0.8.10", "async-retry": "^1.3.3", "canonical-json": "0.0.4", - "csv-parse": "^4.16.0", + "csv-parse": "^5.5.6", "dom-compare": "^0.6.0", - "eslint": "^6.8.0", - "eslint-loader": "^3.0.4", - "googleapis": "^84.0.0", - "iso-639-1": "^3.1.0", - "joi": "^17.11.0", - "json-diff": "^0.5.4", + "eslint": "^8.57.0", + "eslint-webpack-plugin": "^2.7.0", + "googleapis": "^140.0.1", + "iso-639-1": "^3.1.2", + "joi": "^17.13.3", + "json-diff": "^1.0.6", "json-stringify-safe": "^5.0.1", "json2csv": "^4.5.4", "mime-types": "^2.1.35", "minimist": "^1.2.8", - "mkdirp": "^1.0.4", - "open": "^7.4.2", + "mkdirp": "^3.0.1", + "open": "^8.4.2", "pluralize": "^8.0.0", "pouchdb-adapter-http": "^7.2.2", "pouchdb-core": "^7.2.2", "pouchdb-mapreduce": "^7.2.2", - "pouchdb-session-authentication": "^1.3.0", + "pouchdb-session-authentication": "^1.4.0", "properties": "^1.2.1", "queue-promise": "^2.2.1", "readline-sync": "^1.4.10", "redact-basic-auth": "^1.0.1", "request": "^2.88.2", "request-promise-native": "^1.0.9", - "semver": "^6.1.1", - "svgo": "^1.3.2", - "terser-webpack-plugin": "^1.4.3", - "uuid": "^8.3.2", - "webpack": "^4.46.0", + "semver": "^7.6.3", + "svgo": "^3.3.2", + "terser-webpack-plugin": "^5.3.10", + "uuid": "^10.0.0", + "webpack": "^5.93.0", "xpath": "0.0.33" }, "bin": { @@ -2761,1737 +2267,1555 @@ "shell-completion-for-medic-conf": "src/bin/shell-completion.js" }, "engines": { - "node": ">=8.10.0" + "node": ">=18.0.0" } }, - "node_modules/cht-conf/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/cht-conf/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { - "acorn": "bin/acorn" + "uuid": "dist/bin/uuid" + } + }, + "node_modules/clean-css": { + "version": "4.2.4", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" }, "engines": { - "node": ">=0.4.0" + "node": ">= 4.0" } }, - "node_modules/cht-conf/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", "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" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/cht-conf/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", + "engines": { + "node": ">= 0.10" } }, - "node_modules/cht-conf/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/cht-conf/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==", + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=4" + "node": ">=7.0.0" } }, - "node_modules/cht-conf/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" }, - "node_modules/cht-conf/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==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/colorette": { + "version": "2.0.20", + "license": "MIT" + }, + "node_modules/colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha512-OsSVtHK8Ir8r3+Fxw/b4jS1ZLPXkV6ZxDRJQzeD7qo0SqMXWrHDM71DgYzPMHY8SFJ0Ao+nNU2p1MmwdzKqPrw==", + "engines": { + "node": ">=0.1.90" } }, - "node_modules/cht-conf/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==", + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/cht-conf/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==", - "dependencies": { - "color-name": "1.1.3" + "node_modules/commander": { + "version": "12.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" } }, - "node_modules/cht-conf/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" }, - "node_modules/cht-conf/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "node_modules/content-disposition": { + "version": "0.5.4", + "license": "MIT", "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "safe-buffer": "5.2.1" }, "engines": { - "node": ">=4.8" + "node": ">= 0.6" } }, - "node_modules/cht-conf/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" + "node_modules/cookie": { + "version": "0.5.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "node_modules/cht-conf/node_modules/csv-parse": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", - "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==" - }, - "node_modules/cht-conf/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/cookie-signature": { + "version": "1.2.1", + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=6.6.0" } }, - "node_modules/cht-conf/node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "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/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.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", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "luxon": "^3.2.1" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=12.0.0" } }, - "node_modules/cht-conf/node_modules/eslint-loader": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.4.tgz", - "integrity": "sha512-I496aBd+Hi23Y0Cx+sKvw+VwlJre4ScIRlkrvTO6Scq68X/UXbN6F3lAhN8b0Zv8atAyprkyrA42K5QBJtCyaw==", - "deprecated": "This loader has been deprecated. Please use eslint-webpack-plugin", + "node_modules/cross-spawn": { + "version": "7.0.3", + "license": "MIT", "dependencies": { - "fs-extra": "^8.1.0", - "loader-fs-cache": "^1.0.3", - "loader-utils": "^1.2.3", - "object-hash": "^2.0.3", - "schema-utils": "^2.6.5" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">= 8.9.0" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0", - "webpack": "^4.0.0 || ^5.0.0" + "node": ">= 8" } }, - "node_modules/cht-conf/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==", + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cht-conf/node_modules/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==", + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">=6" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/cht-conf/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "engines": { - "node": ">=4" + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cht-conf/node_modules/eslint/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dependencies": { - "minimist": "^1.2.6" + "css-tree": "~2.2.0" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, - "node_modules/cht-conf/node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">=6.0.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, - "node_modules/cht-conf/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" }, - "node_modules/cht-conf/node_modules/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==", + "node_modules/csv": { + "version": "6.3.6", + "license": "MIT", "dependencies": { - "flat-cache": "^2.0.1" + "csv-generate": "^4.3.1", + "csv-parse": "^5.5.3", + "csv-stringify": "^6.4.5", + "stream-transform": "^3.3.0" }, "engines": { - "node": ">=4" + "node": ">= 0.1.90" } }, - "node_modules/cht-conf/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "node_modules/csv-generate": { + "version": "4.3.1", + "license": "MIT" + }, + "node_modules/csv-parse": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.6.0.tgz", + "integrity": "sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==" + }, + "node_modules/csv-stringify": { + "version": "6.4.5", + "license": "MIT" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "assert-plus": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=0.10" } }, - "node_modules/cht-conf/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + "node_modules/dateformat": { + "version": "4.6.3", + "license": "MIT", + "engines": { + "node": "*" + } }, - "node_modules/cht-conf/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "node_modules/debug": { + "version": "4.3.4", + "license": "MIT", "dependencies": { - "type-fest": "^0.8.1" + "ms": "2.1.2" }, "engines": { - "node": ">=8" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cht-conf/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/cht-conf/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==", + "node_modules/decamelize": { + "version": "4.0.0", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cht-conf/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==", + "node_modules/deep-eql": { + "version": "4.1.3", + "dev": true, + "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "type-detect": "^4.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=6" } }, - "node_modules/cht-conf/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==" + "node_modules/deep-is": { + "version": "0.1.4", + "license": "MIT" }, - "node_modules/cht-conf/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cht-conf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/cht-conf/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "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" - }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", "engines": { - "node": ">= 0.8.0" + "node": ">=0.4.0" } }, - "node_modules/cht-conf/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", "engines": { - "node": ">=4" + "node": ">=0.10" } }, - "node_modules/cht-conf/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cht-conf/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/cht-conf/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/cht-conf/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": ">= 0.8" } }, - "node_modules/cht-conf/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/cht-conf/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dependencies": { - "shebang-regex": "^1.0.0" + "detect-libc": "bin/detect-libc.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.10" } }, - "node_modules/cht-conf/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "node_modules/diff": { + "version": "5.0.0", + "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">=0.10.0" + "node": ">=0.3.1" } }, - "node_modules/cht-conf/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^4.1.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/cht-conf/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==", + "node_modules/doctrine": { + "version": "3.0.0", + "license": "Apache-2.0", "dependencies": { - "has-flag": "^3.0.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/cht-conf/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "node_modules/dom-compare": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dom-compare/-/dom-compare-0.6.0.tgz", + "integrity": "sha512-sY9be5h8mhy4vr4vhUp0yUZZbf1HRa6Bxy7gYcLTKabGylFbi9VPn/pADO5oTEj7Lj3dMakae3f6sovqwfsy3Q==", "dependencies": { - "prelude-ls": "~1.1.2" + "argparse": "^1.0.10", + "colors": "0.6.2", + "xmldom": "0.1.19" }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cht-conf/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cht-conf/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==", "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/cht-conf/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" + "domcompare": "bin/domcompare" }, - "bin": { - "which": "bin/which" + "engines": { + "node": "*" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "node_modules/dom-compare/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "sprintf-js": "~1.0.2" } }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/clean-css": { - "version": "4.2.4", - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] }, - "node_modules/cli-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-0.1.7.tgz", - "integrity": "sha512-xNaQxWYgI6DD4xIJLn8GY2zDZVbrN0vsU1fEbDNAHZRyceWhpj7A08mYcG1AY92q1Aw0geYkVfiAcEYIZtuTSg==", + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { - "es5-ext": "0.8.x" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=0.1.103" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/cli-cursor": { + "node_modules/domutils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dependencies": { - "restore-cursor": "^3.1.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", + "node_modules/dotenv": { + "version": "16.3.1", + "license": "BSD-2-Clause", "engines": { - "node": ">= 0.10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, - "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "node_modules/dotenv-expand": { + "version": "10.0.0", + "license": "BSD-2-Clause", "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "node_modules/dreamopt": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.8.0.tgz", + "integrity": "sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==", "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" + "wordwrap": ">=0.0.2" }, "engines": { - "node": ">= 4.0" + "node": ">=0.4.0" } }, - "node_modules/coa/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==", + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", "dependencies": { - "color-convert": "^1.9.0" + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/coa/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==", + "node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/duplexify": { + "version": "3.7.1", + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" } }, - "node_modules/coa/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==", + "node_modules/duplexify/node_modules/readable-stream": { + "version": "2.3.8", + "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "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" } }, - "node_modules/coa/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "node_modules/duplexify/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" }, - "node_modules/coa/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" + "node_modules/duplexify/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "node_modules/coa/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" + "node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/coa/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==", + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "license": "Apache-2.0", "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "safe-buffer": "^5.0.1" } }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", + "node_modules/electron-to-chromium": { + "version": "1.5.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", + "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=10.13.0" } }, - "node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "license": "MIT" - }, - "node_modules/colors": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha512-OsSVtHK8Ir8r3+Fxw/b4jS1ZLPXkV6ZxDRJQzeD7qo0SqMXWrHDM71DgYzPMHY8SFJ0Ao+nNU2p1MmwdzKqPrw==", + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { - "node": ">=0.1.90" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/combined-stream": { - "version": "1.0.8", + "node_modules/env-schema": { + "version": "5.2.1", "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" + "ajv": "^8.0.0", + "dotenv": "^16.0.0", + "dotenv-expand": "^10.0.0" } }, - "node_modules/commander": { - "version": "12.0.0", - "dev": true, - "license": "MIT", + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "engines": { - "node": ">=18" + "node": ">= 0.4" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" - }, - "node_modules/component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" } }, - "node_modules/concat-stream/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==" + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" }, - "node_modules/concat-stream/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==" - }, - "node_modules/content-disposition": { - "version": "0.5.4", + "node_modules/eslint": { + "version": "8.57.0", "license": "MIT", "dependencies": { - "safe-buffer": "5.2.1" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "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.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">= 0.6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/cookie": { - "version": "0.5.0", + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "dev": true, "license": "MIT", + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" } }, - "node_modules/cookie-signature": { - "version": "1.2.1", + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "dev": true, "license": "MIT", + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, "engines": { - "node": ">=6.6.0" + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" } }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "deprecated": "This package is no longer supported.", + "node_modules/eslint-plugin-node/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/copy-concurrently/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/eslint-plugin-node/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", "dependencies": { - "minimist": "^1.2.6" + "brace-expansion": "^1.1.7" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": "*" } }, - "node_modules/copy-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", "bin": { - "rimraf": "bin.js" + "semver": "bin/semver.js" } }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "dev": true, + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "license": "MIT" - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "license": "BSD-2-Clause", "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "node_modules/eslint-utils": { + "version": "2.1.0", + "dev": true, + "license": "MIT", "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "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/cron-parser": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", - "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", - "dependencies": { - "luxon": "^3.2.1" - }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=12.0.0" + "node": ">=4" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "license": "Apache-2.0", "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "engines": { - "node": "*" - } - }, - "node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "node_modules/eslint-webpack-plugin": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.7.0.tgz", + "integrity": "sha512-bNaVVUvU4srexGhVcayn/F4pJAz19CWBkKoMx7aSQ4wtTbZQCnG5O9LHCE42mM+JSKOUp7n6vd5CIwzj7lOVGA==", "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" + "@types/eslint": "^7.29.0", + "arrify": "^2.0.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^3.1.1" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "engines": { - "node": ">= 6" + "node": ">= 10.13.0" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", "dependencies": { - "css-tree": "^1.1.2" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/csv": { - "version": "6.3.6", - "license": "MIT", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "license": "ISC", "dependencies": { - "csv-generate": "^4.3.1", - "csv-parse": "^5.5.3", - "csv-stringify": "^6.4.5", - "stream-transform": "^3.3.0" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 0.1.90" + "node": ">=10.13.0" } }, - "node_modules/csv-generate": { - "version": "4.3.1", - "license": "MIT" - }, - "node_modules/csv-parse": { - "version": "5.5.3", - "license": "MIT" - }, - "node_modules/csv-stringify": { - "version": "6.4.5", + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", "license": "MIT" }, - "node_modules/cyclist": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz", - "integrity": "sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==" - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", "dependencies": { - "assert-plus": "^1.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.10" + "node": "*" } }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "node_modules/espree": { + "version": "9.6.1", + "license": "BSD-2-Clause", "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "node_modules/esquery": { + "version": "1.5.0", + "license": "BSD-3-Clause", "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "estraverse": "^5.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "node_modules/esrecurse": { + "version": "4.3.0", + "license": "BSD-2-Clause", "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4.0" } }, - "node_modules/dateformat": { - "version": "4.6.3", - "license": "MIT", + "node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", "engines": { - "node": "*" + "node": ">=4.0" } }, - "node_modules/debug": { - "version": "4.3.4", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, + "node_modules/esutils": { + "version": "2.0.3", + "license": "BSD-2-Clause", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/decamelize": { - "version": "4.0.0", + "node_modules/event-stream": { + "version": "3.3.4", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" } }, - "node_modules/deep-eql": { - "version": "4.1.3", - "dev": true, + "node_modules/event-target-shim": { + "version": "5.0.1", "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, "engines": { "node": ">=6" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "license": "MIT" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, + "node_modules/events": { + "version": "3.3.0", + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.8.x" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] }, - "node_modules/delayed-stream": { - "version": "1.0.0", + "node_modules/fast-content-type-parse": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/fast-copy": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "dev": true, "license": "MIT", + "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": ">=0.4.0" + "node": ">=8.6.0" } }, - "node_modules/denque": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "engines": { - "node": ">=0.10" - } + "license": "MIT" }, - "node_modules/depd": { - "version": "2.0.0", + "node_modules/fast-json-stringify": { + "version": "5.10.0", "license": "MIT", - "engines": { - "node": ">= 0.8" + "dependencies": { + "@fastify/deepmerge": "^1.0.0", + "ajv": "^8.10.0", + "ajv-formats": "^2.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.1.0", + "json-schema-ref-resolver": "^1.0.1", + "rfdc": "^1.2.0" } }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "license": "MIT" + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "fast-decode-uri-component": "^1.0.1" } }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, + "node_modules/fast-redact": { + "version": "3.5.0", + "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=6" } }, - "node_modules/diff": { - "version": "5.0.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "license": "MIT" }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "node_modules/fast-uri": { + "version": "2.3.0", + "license": "MIT" + }, + "node_modules/fastify": { + "version": "4.27.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "@fastify/ajv-compiler": "^3.5.0", + "@fastify/error": "^3.4.0", + "@fastify/fast-json-stringify-compiler": "^4.3.0", + "abstract-logging": "^2.0.1", + "avvio": "^8.3.0", + "fast-content-type-parse": "^1.1.0", + "fast-json-stringify": "^5.8.0", + "find-my-way": "^8.0.0", + "light-my-request": "^5.11.0", + "pino": "^9.0.0", + "process-warning": "^3.0.0", + "proxy-addr": "^2.0.7", + "rfdc": "^1.3.0", + "secure-json-parse": "^2.7.0", + "semver": "^7.5.4", + "toad-cache": "^3.3.0" } }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "node_modules/fastify-metrics": { + "version": "11.0.0", + "license": "MIT", "dependencies": { - "heap": ">= 0.2.0" + "fastify-plugin": "^4.3.0", + "prom-client": "^15.1.0" }, - "engines": { - "node": "*" + "peerDependencies": { + "fastify": ">=4" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, + "node_modules/fastify-plugin": { + "version": "4.5.1", + "license": "MIT" + }, + "node_modules/fastify-sse-v2": { + "version": "3.1.2", "license": "MIT", "dependencies": { - "path-type": "^4.0.0" + "fastify-plugin": "^4.3.0", + "it-pushable": "^1.4.2", + "it-to-stream": "^1.0.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "fastify": ">=4" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "license": "Apache-2.0", + "node_modules/fastq": { + "version": "1.17.1", + "license": "ISC", "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" + "reusify": "^1.0.4" } }, - "node_modules/dom-compare": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/dom-compare/-/dom-compare-0.6.0.tgz", - "integrity": "sha512-sY9be5h8mhy4vr4vhUp0yUZZbf1HRa6Bxy7gYcLTKabGylFbi9VPn/pADO5oTEj7Lj3dMakae3f6sovqwfsy3Q==", + "node_modules/fclone": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/fetch-cookie": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.11.0.tgz", + "integrity": "sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA==", "dependencies": { - "argparse": "^1.0.10", - "colors": "0.6.2", - "xmldom": "0.1.19" - }, - "bin": { - "domcompare": "bin/domcompare" + "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/dom-compare/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "license": "MIT", "dependencies": { - "sprintf-js": "~1.0.2" + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" + "minimatch": "^5.0.1" } }, - "node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "node_modules/fill-range": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { - "node": ">=0.4", - "npm": ">=1.2" + "node": ">=8" } }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "node_modules/find-my-way": { + "version": "8.2.0", + "license": "MIT", "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^3.1.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/dotenv": { - "version": "16.3.1", - "license": "BSD-2-Clause", + "node_modules/find-up": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dotenv-expand": { - "version": "10.0.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" + "node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" } }, - "node_modules/dreamopt": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.6.0.tgz", - "integrity": "sha512-KRJa47iBEK0y6ZtgCgy2ykuvMT8c9gj3ua9Dv7vCkclFJJeH2FjhGY2xO5qBoWGahsjCGMlk4Cq9wJYeWxuYhQ==", + "node_modules/flat-cache": { + "version": "3.2.0", + "license": "MIT", "dependencies": { - "wordwrap": ">=0.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=0.4.0" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "dev": true, - "license": "MIT" + "node_modules/flatted": { + "version": "3.2.9", + "license": "ISC" }, - "node_modules/duplexify": { - "version": "3.7.1", + "node_modules/follow-redirects": { + "version": "1.15.4", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "license": "MIT", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/duplexify/node_modules/readable-stream": { - "version": "2.3.8", - "license": "MIT", + "node_modules/foreground-child": { + "version": "3.1.1", + "license": "ISC", "dependencies": { - "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" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/duplexify/node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" + } }, - "node_modules/duplexify/node_modules/string_decoder": { - "version": "1.1.1", + "node_modules/form-data": { + "version": "4.0.0", "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/eastasianwidth": { + "node_modules/forwarded": { "version": "0.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "dev": true, "license": "MIT" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=14" } }, - "node_modules/elliptic": { - "version": "6.5.6", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.6.tgz", - "integrity": "sha512-mpzdtpeCLuS3BmE3pO3Cpp5bbjlOPY2Q0PgoF+Od1XZrHLYI28Xe3ossCmYCQt11FQKEYd9+PF8jymTvtWJSHQ==", + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 4" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", + "node_modules/get-func-name": { + "version": "2.0.2", + "dev": true, "license": "MIT", - "dependencies": { - "once": "^1.4.0" + "engines": { + "node": "*" } }, - "node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "node_modules/get-intrinsic": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/enhanced-resolve/node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "node_modules/get-iterator": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" + "assert-plus": "^1.0.0" } }, - "node_modules/enhanced-resolve/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/glob": { + "version": "7.2.0", + "license": "ISC", "dependencies": { - "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" + "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/enhanced-resolve/node_modules/safe-buffer": { + "node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/enhanced-resolve/node_modules/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==", + "dev": true, + "license": "ISC", "dependencies": { - "safe-buffer": "~5.1.0" + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "node_modules/env-schema": { - "version": "5.2.1", + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", "license": "MIT", "dependencies": { - "ajv": "^8.0.0", - "dotenv": "^16.0.0", - "dotenv-expand": "^10.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", "dependencies": { - "prr": "~1.0.1" + "brace-expansion": "^1.1.7" }, - "bin": { - "errno": "cli.js" + "engines": { + "node": "*" } }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "node_modules/globals": { + "version": "13.24.0", + "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "type-fest": "^0.20.2" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "node_modules/globby": { + "version": "11.1.0", + "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4" + "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": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/google-auth-library": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", + "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=14" } }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "node_modules/google-auth-library/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "node_modules/google-auth-library/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/googleapis": { + "version": "140.0.1", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-140.0.1.tgz", + "integrity": "sha512-ZGvBX4mQcFXO9ACnVNg6Aqy3KtBPB5zTuue43YVLxwn8HSv8jB7w+uDKoIPSoWuxGROgnj2kbng6acXncOQRNA==", + "dependencies": { + "google-auth-library": "^9.0.0", + "googleapis-common": "^7.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=14.0.0" } }, - "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==", + "node_modules/googleapis-common": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.2.0.tgz", + "integrity": "sha512-/fhDZEJZvOV3X5jmD+fKxMqma5q2Q9nZNSF3kn1F18tpxmA86BcTxAGBQdM0N89Z3bEaIs+HVznSmFJEAmMTjA==", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "extend": "^3.0.2", + "gaxios": "^6.0.3", + "google-auth-library": "^9.7.0", + "qs": "^6.7.0", + "url-template": "^2.0.8", + "uuid": "^9.0.0" }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "engines": { "node": ">= 0.4" }, @@ -4499,1453 +3823,1281 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es5-ext": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.8.2.tgz", - "integrity": "sha512-H19ompyhnKiBdjHR1DPHvf5RHgHPmJaY9JNzFGbMbPgdsUkvnUCN1Ke8J4Y0IMyTwFM2M9l4h2GoHwzwpSmXbA==", - "engines": { - "node": ">=0.4" - } + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/escalade": { - "version": "3.1.1", - "dev": true, - "license": "MIT", + "node_modules/graphemer": { + "version": "1.4.0", + "license": "MIT" + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, "engines": { - "node": ">=6" + "node": ">=14.0.0" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "license": "MIT" + "node_modules/gtoken/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } }, - "node_modules/escape-string-regexp": { + "node_modules/gtoken/node_modules/jws": { "version": "4.0.0", - "dev": true, - "license": "MIT", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/eslint": { - "version": "8.57.0", - "dev": true, - "license": "MIT", + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "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.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "ajv": "^6.12.3", + "har-schema": "^2.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=6" + } + }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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": { - "url": "https://opencollective.com/eslint" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "dev": true, + "node_modules/har-validator/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==" + }, + "node_modules/has-flag": { + "version": "4.0.0", "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "es-define-property": "^1.0.0" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "engines": { - "node": ">=8.10.0" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "dev": true, - "license": "MIT", + "node_modules/hashlru": { + "version": "2.3.0", + "license": "MIT" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-node/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, + "node_modules/he": { + "version": "1.2.0", "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "bin": { + "he": "bin/he" + } }, - "node_modules/eslint-plugin-node/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" + }, + "node_modules/help-me": { + "version": "5.0.0", + "license": "MIT" + }, + "node_modules/html-minifier": { + "version": "4.0.0", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "camel-case": "^3.0.0", + "clean-css": "^4.2.1", + "commander": "^2.19.0", + "he": "^1.2.0", + "param-case": "^2.1.1", + "relateurl": "^0.2.7", + "uglify-js": "^3.5.1" + }, + "bin": { + "html-minifier": "cli.js" }, "engines": { - "node": "*" + "node": ">=6" } }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } + "node_modules/html-minifier/node_modules/commander": { + "version": "2.20.3", + "license": "MIT" }, - "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "engines": { + "node": ">= 0.8" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" }, - "funding": { - "url": "https://opencollective.com/eslint" + "engines": { + "node": ">= 14" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "dev": true, + "node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.0", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "dev": true, - "license": "Apache-2.0", + "node_modules/imurmurhash": { + "version": "0.1.4", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=0.8.19" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "dev": true, - "license": "MIT", + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/ioredis": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz", + "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==", "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" + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "type": "opencollective", + "url": "https://opencollective.com/ioredis" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, + "node_modules/ipaddr.js": { + "version": "1.9.1", "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">= 0.10" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", + "node_modules/is-binary-path": { + "version": "2.1.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.3" + "binary-extensions": "^2.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=8" } }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", + "node_modules/is-core-module": { + "version": "2.13.1", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "hasown": "^2.0.0" }, - "engines": { - "node": "*" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/espree": { - "version": "9.6.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/esquery": { - "version": "1.5.0", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=8" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "license": "BSD-2-Clause", + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=4.0" + "node": ">=0.10.0" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "license": "BSD-2-Clause", + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">=0.12.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "license": "BSD-2-Clause", + "node_modules/is-path-inside": { + "version": "3.0.3", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/event-stream": { - "version": "3.3.4", + "node_modules/is-plain-obj": { + "version": "2.1.0", "dev": true, "license": "MIT", - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" + "engines": { + "node": ">=8" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", + "node_modules/is-retry-allowed": { + "version": "2.2.0", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/events": { - "version": "3.3.0", - "license": "MIT", + "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==", "engines": { - "node": ">=0.8.x" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "is-docker": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } + "node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" }, - "node_modules/expand-brackets/node_modules/ms": { + "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "ISC" }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "node_modules/iso-639-1": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.2.tgz", + "integrity": "sha512-Le7BRl3Jt9URvaiEHJCDEdvPZCfhiQoXnFgLAWNRhzFMwRFdWO7/5tLRQbiPzE394I9xd7KdRCM7S6qdOhwG5A==", + "engines": { + "node": ">=6.0" + } }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/it-pushable": { + "version": "1.4.2", + "license": "MIT", "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "fast-fifo": "^1.0.0" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/it-to-stream": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "fast-fifo": "^1.0.0", + "get-iterator": "^1.0.2", + "p-defer": "^3.0.0", + "p-fifo": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "license": "BlueOak-1.0.0", "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">=4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "node_modules/jake/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==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { - "is-descriptor": "^1.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 10.13.0" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ] + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } }, - "node_modules/fast-content-type-parse": { - "version": "1.1.0", - "license": "MIT" + "node_modules/joycon": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=10" + } }, - "node_modules/fast-copy": { - "version": "3.0.1", - "license": "MIT" + "node_modules/js-yaml": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, - "node_modules/fast-decode-uri-component": { - "version": "1.0.1", - "license": "MIT" + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "license": "MIT" + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } }, - "node_modules/fast-fifo": { - "version": "1.3.2", + "node_modules/json-buffer": { + "version": "3.0.1", "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.2", - "dev": true, - "license": "MIT", + "node_modules/json-diff": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-1.0.6.tgz", + "integrity": "sha512-tcFIPRdlc35YkYdGxcamJjllUhXWv4n2rK9oJ2RsAzV4FBkuV4ojKEDgcZ+kpKxDmJKv+PFK65+1tVVOnSeEqA==", "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" + "@ewoudenberg/difflib": "0.1.0", + "colors": "^1.4.0", + "dreamopt": "~0.8.0" + }, + "bin": { + "json-diff": "bin/json-diff.js" }, "engines": { - "node": ">=8.6.0" + "node": "*" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "license": "MIT" + "node_modules/json-diff/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } }, - "node_modules/fast-json-stringify": { - "version": "5.10.0", - "license": "MIT", - "dependencies": { - "@fastify/deepmerge": "^1.0.0", - "ajv": "^8.10.0", - "ajv-formats": "^2.1.1", - "fast-deep-equal": "^3.1.3", - "fast-uri": "^2.1.0", - "json-schema-ref-resolver": "^1.0.1", - "rfdc": "^1.2.0" - } + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "license": "MIT" + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, - "node_modules/fast-querystring": { - "version": "1.1.2", + "node_modules/json-schema-ref-resolver": { + "version": "1.0.1", "license": "MIT", "dependencies": { - "fast-decode-uri-component": "^1.0.1" - } - }, - "node_modules/fast-redact": { - "version": "3.5.0", - "license": "MIT", - "engines": { - "node": ">=6" + "fast-deep-equal": "^3.1.3" } }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", + "node_modules/json-schema-traverse": { + "version": "1.0.0", "license": "MIT" }, - "node_modules/fast-text-encoding": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", - "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==" - }, - "node_modules/fast-uri": { - "version": "2.3.0", + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", "license": "MIT" }, - "node_modules/fastify": { - "version": "4.27.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT", - "dependencies": { - "@fastify/ajv-compiler": "^3.5.0", - "@fastify/error": "^3.4.0", - "@fastify/fast-json-stringify-compiler": "^4.3.0", - "abstract-logging": "^2.0.1", - "avvio": "^8.3.0", - "fast-content-type-parse": "^1.1.0", - "fast-json-stringify": "^5.8.0", - "find-my-way": "^8.0.0", - "light-my-request": "^5.11.0", - "pino": "^9.0.0", - "process-warning": "^3.0.0", - "proxy-addr": "^2.0.7", - "rfdc": "^1.3.0", - "secure-json-parse": "^2.7.0", - "semver": "^7.5.4", - "toad-cache": "^3.3.0" - } + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, - "node_modules/fastify-metrics": { - "version": "11.0.0", - "license": "MIT", + "node_modules/json2csv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-4.5.4.tgz", + "integrity": "sha512-YxBhY4Lmn8IvVZ36nqg5omxneLy9JlorkqW1j/EDCeqvmi+CQ4uM+wsvXlcIqvGDewIPXMC/O/oF8DX9EH5aoA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dependencies": { - "fastify-plugin": "^4.3.0", - "prom-client": "^15.1.0" + "commander": "^2.15.1", + "jsonparse": "^1.3.1", + "lodash.get": "^4.4.2" }, - "peerDependencies": { - "fastify": ">=4" + "bin": { + "json2csv": "bin/json2csv.js" } }, - "node_modules/fastify-plugin": { - "version": "4.5.1", - "license": "MIT" + "node_modules/json2csv/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/fastify-sse-v2": { - "version": "3.1.2", + "node_modules/json5": { + "version": "1.0.2", + "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "fastify-plugin": "^4.3.0", - "it-pushable": "^1.4.2", - "it-to-stream": "^1.0.0" + "minimist": "^1.2.0" }, - "peerDependencies": { - "fastify": ">=4" - } - }, - "node_modules/fastq": { - "version": "1.17.1", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" + "bin": { + "json5": "lib/cli.js" } }, - "node_modules/fclone": { - "version": "1.0.11", - "dev": true, - "license": "MIT" + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] }, - "node_modules/fetch-cookie": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.11.0.tgz", - "integrity": "sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA==", + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "license": "MIT", "dependencies": { - "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" }, "engines": { - "node": ">=8" + "node": ">=12", + "npm": ">=6" } }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "deprecated": "This module is no longer supported." - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dependencies": { - "escape-string-regexp": "^1.0.5" + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.6.0" } }, - "node_modules/figures/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" + "node_modules/jszip": { + "version": "3.10.1", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "dev": true, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "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" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", "dependencies": { - "minimatch": "^5.0.1" + "safe-buffer": "~5.1.0" } }, - "node_modules/fill-range": { - "version": "7.0.1", + "node_modules/just-extend": { + "version": "6.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/jwa": { + "version": "1.4.1", "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" } }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "node_modules/jws": { + "version": "3.2.2", + "license": "MIT", "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/find-my-way": { - "version": "8.2.0", + "node_modules/keyv": { + "version": "4.5.4", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-querystring": "^1.0.0", - "safe-regex2": "^3.1.0" - }, - "engines": { - "node": ">=14" + "json-buffer": "3.0.1" } }, - "node_modules/find-up": { - "version": "5.0.0", - "dev": true, + "node_modules/levn": { + "version": "0.4.1", "license": "MIT", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.8.0" } }, - "node_modules/flatted": { - "version": "3.2.9", - "dev": true, - "license": "ISC" + "node_modules/libphonenumber-js": { + "version": "1.10.53", + "license": "MIT" }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "node_modules/lie": { + "version": "3.3.0", + "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" + "immediate": "~3.0.5" } }, - "node_modules/flush-write-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/light-my-request": { + "version": "5.11.0", + "license": "BSD-3-Clause", "dependencies": { - "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" + "cookie": "^0.5.0", + "process-warning": "^2.0.0", + "set-cookie-parser": "^2.4.1" } }, - "node_modules/flush-write-stream/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==" - }, - "node_modules/flush-write-stream/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "node_modules/light-my-request/node_modules/process-warning": { + "version": "2.3.2", + "license": "MIT" }, - "node_modules/follow-redirects": { - "version": "1.15.4", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], + "node_modules/liquidjs": { + "version": "10.10.0", "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" + "commander": "^10.0.0" + }, + "bin": { + "liquid": "bin/liquid.js", + "liquidjs": "bin/liquid.js" }, "engines": { "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "engines": { - "node": "*" + "type": "opencollective", + "url": "https://opencollective.com/liquidjs" } }, - "node_modules/form-data": { - "version": "4.0.0", + "node_modules/liquidjs/node_modules/commander": { + "version": "10.0.1", "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, "engines": { - "node": ">= 6" + "node": ">=14" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "license": "MIT", + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "engines": { - "node": ">= 0.6" + "node": ">=6.11.5" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "node_modules/locate-path": { + "version": "6.0.0", + "license": "MIT", "dependencies": { - "map-cache": "^0.2.2" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/from": { - "version": "0.1.7", - "dev": true, + "node_modules/lodash": { + "version": "4.17.21", "license": "MIT" }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "node_modules/from2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" }, - "node_modules/from2/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==" + "node_modules/lodash.get": { + "version": "4.4.2", + "license": "MIT" }, - "node_modules/from2/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "node_modules/lodash.includes": { + "version": "4.3.0", + "license": "MIT" }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" }, - "node_modules/fs-extra/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==", - "engines": { - "node": ">= 4.0.0" - } + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "license": "MIT" }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", - "deprecated": "This package is no longer supported.", - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "license": "MIT" }, - "node_modules/fs-write-stream-atomic/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "license": "MIT" }, - "node_modules/fs-write-stream-atomic/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==" + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "license": "MIT" }, - "node_modules/fs-write-stream-atomic/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "node_modules/lodash.isstring": { + "version": "4.0.1", + "license": "MIT" }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "license": "ISC" + "node_modules/lodash.merge": { + "version": "4.6.2", + "license": "MIT" }, - "node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } + "node_modules/lodash.once": { + "version": "4.1.1", + "license": "MIT" }, - "node_modules/function-bind": { - "version": "1.1.2", + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "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": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/loupe": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" } }, - "node_modules/gaxios": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz", - "integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==", - "dependencies": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.7" - }, + "node_modules/lower-case": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/luxon": { + "version": "3.4.4", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/gcp-metadata": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", - "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", - "dependencies": { - "gaxios": "^4.0.0", - "json-bigint": "^1.0.0" + "node_modules/make-error": { + "version": "1.3.6", + "license": "ISC" + }, + "node_modules/make-plural": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", + "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", + "bin": { + "make-plural": "bin/make-plural" }, - "engines": { - "node": ">=10" + "optionalDependencies": { + "minimist": "^1.2.0" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } + "node_modules/map-stream": { + "version": "0.1.0", + "dev": true }, - "node_modules/get-func-name": { - "version": "2.0.2", + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "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==" + }, + "node_modules/merge2": { + "version": "1.4.1", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">= 8" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "node_modules/messageformat": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", + "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", + "deprecated": "Package renamed as '@messageformat/core', see messageformat.github.io for more details. 'messageformat@4' will eventually provide a polyfill for Intl.MessageFormat, once it's been defined by Unicode & ECMA.", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "make-plural": "^4.3.0", + "messageformat-formatters": "^2.0.1", + "messageformat-parser": "^4.1.2" } }, - "node_modules/get-iterator": { - "version": "1.0.2", - "license": "MIT" + "node_modules/messageformat-formatters": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", + "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==" }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "node_modules/messageformat-parser": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz", + "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==" + }, + "node_modules/micromatch": { + "version": "4.0.5", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.6" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "node_modules/mime": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dependencies": { - "assert-plus": "^1.0.0" + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "node_modules/glob": { - "version": "7.2.0", - "license": "ISC", + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", "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" + "mime-db": "1.52.0" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 0.6" } }, - "node_modules/glob-parent": { - "version": "5.1.2", + "node_modules/minimatch": { + "version": "5.0.1", "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", + "node_modules/minimist": { + "version": "1.2.8", "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", + "node_modules/minipass": { + "version": "7.0.4", "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globby": { - "version": "11.1.0", + "node_modules/mocha": { + "version": "10.2.0", "dev": true, "license": "MIT", "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" + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" }, "engines": { - "node": ">=10" + "node": ">= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, - "node_modules/google-auth-library": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz", - "integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==", - "dependencies": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^4.0.0", - "gcp-metadata": "^4.2.0", - "gtoken": "^5.0.4", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz", + "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" } }, - "node_modules/google-auth-library/node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/google-auth-library/node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/google-p12-pem": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz", - "integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==", - "deprecated": "Package is no longer maintained", + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "hasInstallScript": true, + "optional": true, "dependencies": { - "node-forge": "^1.3.1" + "node-gyp-build-optional-packages": "5.2.2" }, "bin": { - "gp12-pem": "build/src/bin/gp12-pem.js" + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" }, - "engines": { - "node": ">=10" + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" } }, - "node_modules/googleapis": { - "version": "84.0.0", - "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-84.0.0.tgz", - "integrity": "sha512-5WWLwmraulw3p55lu0gNpLz2FME1gcuR7QxgmUdAVHMiVN4LEasYjJV9p36gxcf2TMe6bn6+PgQ/63+CvBEgoQ==", - "dependencies": { - "google-auth-library": "^7.0.2", - "googleapis-common": "^5.0.2" + "node_modules/nanoid": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=10" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/googleapis-common": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-5.1.0.tgz", - "integrity": "sha512-RXrif+Gzhq1QAzfjxulbGvAY3FPj8zq/CYcvgjzDbaBNCD6bUl+86I7mUs4DKWHGruuK26ijjR/eDpWIDgNROA==", - "dependencies": { - "extend": "^3.0.2", - "gaxios": "^4.0.0", - "google-auth-library": "^7.14.0", - "qs": "^6.7.0", - "url-template": "^2.0.8", - "uuid": "^8.0.0" - }, - "engines": { - "node": ">=10.10.0" - } + "node_modules/natural-compare": { + "version": "1.4.0", + "license": "MIT" }, - "node_modules/googleapis-common/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==", - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/nise": { + "version": "5.1.7", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/no-case": { + "version": "2.3.2", + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "lower-case": "^1.1.1" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" }, - "node_modules/graphemer": { - "version": "1.4.0", + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" + }, + "node_modules/node-cleanup": { + "version": "2.1.2", "dev": true, "license": "MIT" }, - "node_modules/gtoken": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz", - "integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==", + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { - "gaxios": "^4.0.0", - "google-p12-pem": "^3.1.3", - "jws": "^4.0.0" + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/gtoken/node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "node_modules/gtoken/node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "optional": true, "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "node_modules/node-gyp-build-optional-packages/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "optional": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/har-validator/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "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" + "boolbase": "^1.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/har-validator/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==" - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "*" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "engines": { "node": ">= 0.4" }, @@ -5953,5308 +5105,1457 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=14.0.0" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dependencies": { - "has-symbols": "^1.0.3" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "node_modules/optionator": { + "version": "0.9.3", + "license": "MIT", "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "@aashutoshrathi/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" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, + "node_modules/p-defer": { + "version": "3.0.0", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "node_modules/p-fifo": { + "version": "1.0.0", + "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "fast-fifo": "^1.0.0", + "p-defer": "^3.0.0" } }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "node_modules/p-limit": { + "version": "3.1.0", + "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "node_modules/p-locate": { + "version": "5.0.0", + "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "node_modules/pako": { + "version": "1.0.11", + "license": "(MIT AND Zlib)" + }, + "node_modules/param-case": { + "version": "2.1.1", + "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "no-case": "^2.2.0" } }, - "node_modules/hashlru": { - "version": "2.3.0", - "license": "MIT" - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/parent-module": { + "version": "1.0.1", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "callsites": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/he": { - "version": "1.2.0", + "node_modules/path-exists": { + "version": "4.0.0", "license": "MIT", - "bin": { - "he": "bin/he" + "engines": { + "node": ">=8" } }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" - }, - "node_modules/help-me": { - "version": "5.0.0", - "license": "MIT" - }, - "node_modules/hmac-drbg": { + "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/html-minifier": { - "version": "4.0.0", + "node_modules/path-key": { + "version": "3.1.1", "license": "MIT", - "dependencies": { - "camel-case": "^3.0.0", - "clean-css": "^4.2.1", - "commander": "^2.19.0", - "he": "^1.2.0", - "param-case": "^2.1.1", - "relateurl": "^0.2.7", - "uglify-js": "^3.5.1" - }, - "bin": { - "html-minifier": "cli.js" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/html-minifier/node_modules/commander": { - "version": "2.20.3", + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, "license": "MIT" }, - "node_modules/http-errors": { - "version": "2.0.0", - "license": "MIT", + "node_modules/path-scurry": { + "version": "1.10.1", + "license": "BlueOak-1.0.0", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "license": "ISC", "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": "14 || >=16.14" } }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" + "node_modules/path-to-regexp": { + "version": "6.2.1", + "dev": true, + "license": "MIT" }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=8" } }, - "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==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, + "node_modules/pathval": { + "version": "1.1.1", + "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "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/pause-stream": { + "version": "0.0.11", + "dev": true, + "license": [ + "MIT", + "Apache2" ], - "license": "BSD-3-Clause" - }, - "node_modules/iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==" + "dependencies": { + "through": "~2.3" + } }, - "node_modules/ignore": { - "version": "5.3.0", - "dev": true, + "node_modules/peek-stream": { + "version": "1.1.3", "license": "MIT", - "engines": { - "node": ">= 4" + "dependencies": { + "buffer-from": "^1.0.0", + "duplexify": "^3.5.0", + "through2": "^2.0.3" } }, - "node_modules/immediate": { - "version": "3.0.6", - "license": "MIT" + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, - "node_modules/import-fresh": { - "version": "3.3.0", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "2.3.1", "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, "engines": { - "node": ">=6" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", + "node_modules/pino": { + "version": "9.0.0", "license": "MIT", - "engines": { - "node": ">=0.8.19" + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.6.0" + }, + "bin": { + "pino": "bin.js" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "node_modules/inflight": { - "version": "1.0.6", - "license": "ISC", + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "readable-stream": "^4.0.0", + "split2": "^4.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "license": "ISC" - }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.5.2", + "license": "MIT", "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">=8.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "node_modules/pino-pretty": { + "version": "10.3.1", + "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.0", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^3.0.0", + "strip-json-comments": "^3.1.1" }, - "engines": { - "node": ">= 0.4" + "bin": { + "pino-pretty": "bin.js" } }, - "node_modules/ioredis": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz", - "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==", + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.5.2", + "license": "MIT", "dependencies": { - "@ioredis/commands": "^1.1.1", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "license": "MIT" }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", - "dependencies": { - "hasown": "^2.0.0" - }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "engines": { - "node": ">= 0.10" + "node": ">=4" } }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "node_modules/pouchdb-abstract-mapreduce": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-7.3.1.tgz", + "integrity": "sha512-0zKXVFBvrfc1KnN0ggrB762JDmZnUpePHywo9Bq3Jy+L1FnoG7fXM5luFfvv5/T0gEw+ZTIwoocZECMnESBI9w==", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "pouchdb-binary-utils": "7.3.1", + "pouchdb-collate": "7.3.1", + "pouchdb-collections": "7.3.1", + "pouchdb-errors": "7.3.1", + "pouchdb-fetch": "7.3.1", + "pouchdb-mapreduce-utils": "7.3.1", + "pouchdb-md5": "7.3.1", + "pouchdb-utils": "7.3.1" } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/pouchdb-adapter-http": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-adapter-http/-/pouchdb-adapter-http-7.3.1.tgz", + "integrity": "sha512-09spFXxAvDsa8Q987FAFrqeKDvt8hiCuDjciLCR/uYEO8qwXg05o5CXEVVsHycpGdna1b0+i6i3ZWH+69lxmbg==", "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "argsarray": "0.0.1", + "pouchdb-binary-utils": "7.3.1", + "pouchdb-errors": "7.3.1", + "pouchdb-fetch": "7.3.1", + "pouchdb-utils": "7.3.1" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "devOptional": true, - "license": "MIT", + "node_modules/pouchdb-binary-utils": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-7.3.1.tgz", + "integrity": "sha512-crZJNfAEOnUoRk977Qtmk4cxEv6sNKllQ6vDDKgQrQLFjMUXma35EHzNyIJr1s76J77Q4sqKQAmxz9Y40yHGtw==", "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" + "buffer-from": "1.1.2" } }, - "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==", + "node_modules/pouchdb-changes-filter": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-changes-filter/-/pouchdb-changes-filter-7.3.1.tgz", + "integrity": "sha512-C31zsslhlxyFdlKPdZ0013Z4GIsWjoSTgptfamrPnXEtOS6EX4jLtcmiGURCIXmZlcDGKRm8qWHL3vikwITalA==", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "pouchdb-errors": "7.3.1", + "pouchdb-selector-core": "7.3.1", + "pouchdb-utils": "7.3.1" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "node_modules/pouchdb-collate": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-7.3.1.tgz", + "integrity": "sha512-o4gyGqDMLMSNzf6EDTr3eHaH/JRMoqRhdc+eV+oA8u00nTBtr9wD+jypVe2LbgKLJ4NWqx2qVkXiTiQdUFtsLQ==" + }, + "node_modules/pouchdb-collections": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-7.3.1.tgz", + "integrity": "sha512-yUyDqR+OJmtwgExOSJegpBJXDLAEC84TWnbAYycyh+DZoA51Yw0+XVQF5Vh8Ii90/Ut2xo88fmrmp0t6kqom8w==" }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/pouchdb-core": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-core/-/pouchdb-core-7.3.1.tgz", + "integrity": "sha512-9jRZ70+4wrDohJQQ2OA8T9zzanefWf03ugGis5NJL24cpar8LjvQnceRo8X4KCQfVJr9su9LFe4L6YBqneE1VA==", + "dependencies": { + "argsarray": "0.0.1", + "inherits": "2.0.4", + "pouchdb-changes-filter": "7.3.1", + "pouchdb-collections": "7.3.1", + "pouchdb-errors": "7.3.1", + "pouchdb-fetch": "7.3.1", + "pouchdb-merge": "7.3.1", + "pouchdb-utils": "7.3.1" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "license": "MIT", + "node_modules/pouchdb-errors": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-7.3.1.tgz", + "integrity": "sha512-Zktz4gnXEUcZcty8FmyvtYUYsHskoST05m6H5/E2gg/0mCfEXq/XeyyLkZHaZmqD0ZPS9yNmASB1VaFWEKEaDw==", "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "inherits": "2.0.4" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "node_modules/pouchdb-fetch": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-7.3.1.tgz", + "integrity": "sha512-205xAtvdHRPQ4fp1h9+RmT9oQabo9gafuPmWsS9aEl3ER54WbY8Vaj1JHZGbU4KtMTYvW7H5088zLS7Nrusuag==", "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" + "abort-controller": "3.0.0", + "fetch-cookie": "0.11.0", + "node-fetch": "2.6.7" } }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "node_modules/pouchdb-fetch/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dependencies": { - "is-typed-array": "^1.1.13" + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": "4.x || >=6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "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==", + "node_modules/pouchdb-mapreduce": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-mapreduce/-/pouchdb-mapreduce-7.3.1.tgz", + "integrity": "sha512-dm4YG8P1fNk85YGpEg79vpsV9xxqkumDqCof7+sykDfIZwqa1X5NLgUuw7Adsc+RFsHU23Vsk2ho/HzgRBkFvw==", "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "pouchdb-abstract-mapreduce": "7.3.1", + "pouchdb-mapreduce-utils": "7.3.1", + "pouchdb-utils": "7.3.1" } }, - "node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "node_modules/pouchdb-mapreduce-utils": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-7.3.1.tgz", + "integrity": "sha512-oUMcq82+4pTGQ6dtrhgORHOVHZSr6w/5tFIUGlv7RABIDvJarL4snMawADjlpiEwPdiQ/ESG8Fqt8cxqvqsIgg==", "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "argsarray": "0.0.1", + "inherits": "2.0.4", + "pouchdb-collections": "7.3.1", + "pouchdb-utils": "7.3.1" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/pouchdb-md5": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-7.3.1.tgz", + "integrity": "sha512-aDV8ui/mprnL3xmt0gT/81DFtTtJiKyn+OxIAbwKPMfz/rDFdPYvF0BmDC9QxMMzGfkV+JJUjU6at0PPs2mRLg==", + "dependencies": { + "pouchdb-binary-utils": "7.3.1", + "spark-md5": "3.0.2" } }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } + "node_modules/pouchdb-merge": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-merge/-/pouchdb-merge-7.3.1.tgz", + "integrity": "sha512-FeK3r35mKimokf2PQ2tUI523QWyZ4lYZ0Yd75FfSch/SPY6wIokz5XBZZ6PHdu5aOJsEKzoLUxr8CpSg9DhcAw==" }, - "node_modules/is-glob": { - "version": "4.0.3", - "license": "MIT", + "node_modules/pouchdb-selector-core": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-selector-core/-/pouchdb-selector-core-7.3.1.tgz", + "integrity": "sha512-HBX+nNGXcaL9z0uNpwSMRq2GNZd3EZXW+fe9rJHS0hvJohjZL7aRJLoaXfEdHPRTNW+CpjM3Rny60eGekQdI/w==", "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" + "pouchdb-collate": "7.3.1", + "pouchdb-utils": "7.3.1" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "engines": { - "node": ">= 0.4" + "node_modules/pouchdb-session-authentication": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pouchdb-session-authentication/-/pouchdb-session-authentication-1.4.0.tgz", + "integrity": "sha512-77hisEECvPOuy3Efh5IGCi5EyAAmIcwWja14GSaMQLXm0Prcw76cLV1XOBQ/8EATvp7CgqnqcSJ5ZQv7kQpnWQ==", + "dependencies": { + "pouchdb-fetch": "^8.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">=8.10.0", + "npm": ">=8.3.1" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/pouchdb-session-authentication/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dependencies": { - "has-tostringtag": "^1.0.0" + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">= 0.4" + "node": "4.x || >=6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "node_modules/pouchdb-session-authentication/node_modules/pouchdb-fetch": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-8.0.1.tgz", + "integrity": "sha512-Px5HLT8MxqTujc8bpPRKoouznDTJa9XBGqCbhl95q6rhjWRfwZEvXjV92z0B5BALAM6D6avMyG0DjuNfUWnMuA==", + "dependencies": { + "abort-controller": "3.0.0", + "fetch-cookie": "0.11.0", + "node-fetch": "2.6.7" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/pouchdb-utils": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-7.3.1.tgz", + "integrity": "sha512-R3hHBo1zTdTu/NFs3iqkcaQAPwhIH0gMIdfVKd5lbDYlmP26rCG5pdS+v7NuoSSFLJ4xxnaGV+Gjf4duYsJ8wQ==", "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "argsarray": "0.0.1", + "clone-buffer": "1.0.0", + "immediate": "3.3.0", + "inherits": "2.0.4", + "pouchdb-collections": "7.3.1", + "pouchdb-errors": "7.3.1", + "pouchdb-md5": "7.3.1", + "uuid": "8.3.2" } }, - "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==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/pouchdb-utils/node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + }, + "node_modules/pouchdb-utils/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==", + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/is-retry-allowed": { - "version": "2.2.0", + "node_modules/prelude-ls": { + "version": "1.2.1", "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dependencies": { - "call-bind": "^1.0.7" - }, + "node_modules/process": { + "version": "0.11.10", + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6.0" } }, - "node_modules/is-stream": { + "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/process-warning": { + "version": "3.0.0", + "license": "MIT" }, - "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==", + "node_modules/prom-client": { + "version": "15.1.2", + "license": "Apache-2.0", "dependencies": { - "has-symbols": "^1.0.2" + "@opentelemetry/api": "^1.4.0", + "tdigest": "^0.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^16 || ^18 || >=20" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, + "node_modules/properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/properties/-/properties-1.2.1.tgz", + "integrity": "sha512-qYNxyMj1JeW54i/EWEFsM1cVwxJbtgPp8+0Wg9XjNaK6VE/c4oRi6PNu5p7w1mNXEIQIjV5Wwn8v8Gz82/QzdQ==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "dev": true, + "node_modules/proxy-addr": { + "version": "2.0.7", "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dependencies": { - "is-docker": "^2.0.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/iso-639-1": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.2.tgz", - "integrity": "sha512-Le7BRl3Jt9URvaiEHJCDEdvPZCfhiQoXnFgLAWNRhzFMwRFdWO7/5tLRQbiPzE394I9xd7KdRCM7S6qdOhwG5A==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, - "node_modules/it-pushable": { - "version": "1.4.2", - "license": "MIT", - "dependencies": { - "fast-fifo": "^1.0.0" - } - }, - "node_modules/it-to-stream": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3", - "fast-fifo": "^1.0.0", - "get-iterator": "^1.0.2", - "p-defer": "^3.0.0", - "p-fifo": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/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==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jake/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/joycon": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "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==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-diff": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.5.5.tgz", - "integrity": "sha512-B2RSfPv8Y5iqm6/9aKC3cOhXPzjYupKDpGuqT5py9NRulL8J0UoB/zKXUo70xBsuxPcIFgtsGgEdXLrNp0GL7w==", - "dependencies": { - "cli-color": "~0.1.6", - "difflib": "~0.2.1", - "dreamopt": "~0.6.0" - }, - "bin": { - "json-diff": "bin/json-diff.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-ref-resolver": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "node_modules/json2csv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-4.5.4.tgz", - "integrity": "sha512-YxBhY4Lmn8IvVZ36nqg5omxneLy9JlorkqW1j/EDCeqvmi+CQ4uM+wsvXlcIqvGDewIPXMC/O/oF8DX9EH5aoA==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dependencies": { - "commander": "^2.15.1", - "jsonparse": "^1.3.1", - "lodash.get": "^4.4.2" - }, - "bin": { - "json2csv": "bin/json2csv.js" - } - }, - "node_modules/json2csv/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/json5": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "license": "MIT", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jszip": { - "version": "3.10.1", - "license": "(MIT OR GPL-3.0-or-later)", - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "node_modules/jszip/node_modules/readable-stream": { - "version": "2.3.8", - "license": "MIT", - "dependencies": { - "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" - } - }, - "node_modules/jszip/node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" - }, - "node_modules/jszip/node_modules/string_decoder": { - "version": "1.1.1", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/just-extend": { - "version": "6.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/jwa": { - "version": "1.4.1", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/libphonenumber-js": { - "version": "1.10.53", - "license": "MIT" - }, - "node_modules/lie": { - "version": "3.3.0", - "license": "MIT", - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/light-my-request": { - "version": "5.11.0", - "license": "BSD-3-Clause", - "dependencies": { - "cookie": "^0.5.0", - "process-warning": "^2.0.0", - "set-cookie-parser": "^2.4.1" - } - }, - "node_modules/light-my-request/node_modules/process-warning": { - "version": "2.3.2", - "license": "MIT" - }, - "node_modules/liquidjs": { - "version": "10.10.0", - "license": "MIT", - "dependencies": { - "commander": "^10.0.0" - }, - "bin": { - "liquid": "bin/liquid.js", - "liquidjs": "bin/liquid.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/liquidjs" - } - }, - "node_modules/liquidjs/node_modules/commander": { - "version": "10.0.1", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/loader-fs-cache": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz", - "integrity": "sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==", - "dependencies": { - "find-cache-dir": "^0.1.1", - "mkdirp": "^0.5.1" - } - }, - "node_modules/loader-fs-cache/node_modules/find-cache-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", - "integrity": "sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==", - "dependencies": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-fs-cache/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-fs-cache/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/loader-fs-cache/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-fs-cache/node_modules/pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==", - "dependencies": { - "find-up": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "license": "MIT" - }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "license": "MIT" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "license": "MIT" - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "license": "MIT" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "license": "MIT" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "license": "MIT" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lower-case": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/luxon": { - "version": "3.4.4", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "license": "ISC" - }, - "node_modules/make-plural": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", - "bin": { - "make-plural": "bin/make-plural" - }, - "optionalDependencies": { - "minimist": "^1.2.0" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-stream": { - "version": "0.1.0", - "dev": true - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "node_modules/memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/memory-fs/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } - }, - "node_modules/memory-fs/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==" - }, - "node_modules/memory-fs/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/messageformat": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", - "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "deprecated": "Package renamed as '@messageformat/core', see messageformat.github.io for more details. 'messageformat@4' will eventually provide a polyfill for Intl.MessageFormat, once it's been defined by Unicode & ECMA.", - "dependencies": { - "make-plural": "^4.3.0", - "messageformat-formatters": "^2.0.1", - "messageformat-parser": "^4.1.2" - } - }, - "node_modules/messageformat-formatters": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", - "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==" - }, - "node_modules/messageformat-parser": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz", - "integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==" - }, - "node_modules/micromatch": { - "version": "4.0.5", - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/mime": { - "version": "3.0.0", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "node_modules/minimatch": { - "version": "5.0.1", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.0.4", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mississippi/node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/mississippi/node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha": { - "version": "10.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", - "deprecated": "This package is no longer supported.", - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/move-concurrently/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/move-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "license": "MIT" - }, - "node_modules/msgpackr": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz", - "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==", - "optionalDependencies": { - "msgpackr-extract": "^3.0.2" - } - }, - "node_modules/msgpackr-extract": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", - "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build-optional-packages": "5.2.2" - }, - "bin": { - "download-msgpackr-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" - } - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "node_modules/nan": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", - "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", - "optional": true - }, - "node_modules/nanoid": { - "version": "3.3.3", - "dev": true, - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/nise": { - "version": "5.1.7", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", - "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "node_modules/no-case": { - "version": "2.3.2", - "license": "MIT", - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" - }, - "node_modules/node-cleanup": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", - "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, - "node_modules/node-gyp-build-optional-packages/node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/node-libs-browser/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } - }, - "node_modules/node-libs-browser/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==" - }, - "node_modules/node-libs-browser/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "engines": { - "node": ">= 0.4" - }, - "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==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", - "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", - "dependencies": { - "array.prototype.reduce": "^1.0.6", - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "gopd": "^1.0.1", - "safe-array-concat": "^1.1.2" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-exit-leak-free": { - "version": "2.1.2", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "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==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@aashutoshrathi/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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-defer": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-fifo": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "fast-fifo": "^1.0.0", - "p-defer": "^3.0.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "license": "(MIT AND Zlib)" - }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/parallel-transform/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } - }, - "node_modules/parallel-transform/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==" - }, - "node_modules/parallel-transform/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/param-case": { - "version": "2.1.1", - "license": "MIT", - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", - "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "hash-base": "~3.0", - "pbkdf2": "^3.1.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "optional": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.10.1", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-to-regexp": { - "version": "6.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/pause-stream": { - "version": "0.0.11", - "dev": true, - "license": [ - "MIT", - "Apache2" - ], - "dependencies": { - "through": "~2.3" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/peek-stream": { - "version": "1.1.3", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "duplexify": "^3.5.0", - "through2": "^2.0.3" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pino": { - "version": "9.0.0", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.2.0", - "pino-std-serializers": "^6.0.0", - "process-warning": "^3.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.7.0", - "thread-stream": "^2.6.0" - }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/pino-abstract-transport": { - "version": "1.2.0", - "license": "MIT", - "dependencies": { - "readable-stream": "^4.0.0", - "split2": "^4.0.0" - } - }, - "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.5.2", - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-pretty": { - "version": "10.3.1", - "license": "MIT", - "dependencies": { - "colorette": "^2.0.7", - "dateformat": "^4.6.3", - "fast-copy": "^3.0.0", - "fast-safe-stringify": "^2.1.1", - "help-me": "^5.0.0", - "joycon": "^3.1.1", - "minimist": "^1.2.6", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.0.0", - "pump": "^3.0.0", - "readable-stream": "^4.0.0", - "secure-json-parse": "^2.4.0", - "sonic-boom": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "pino-pretty": "bin.js" - } - }, - "node_modules/pino-pretty/node_modules/readable-stream": { - "version": "4.5.2", - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/pino-std-serializers": { - "version": "6.2.2", - "license": "MIT" - }, - "node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "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": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/pouchdb-abstract-mapreduce": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-7.3.1.tgz", - "integrity": "sha512-0zKXVFBvrfc1KnN0ggrB762JDmZnUpePHywo9Bq3Jy+L1FnoG7fXM5luFfvv5/T0gEw+ZTIwoocZECMnESBI9w==", - "dependencies": { - "pouchdb-binary-utils": "7.3.1", - "pouchdb-collate": "7.3.1", - "pouchdb-collections": "7.3.1", - "pouchdb-errors": "7.3.1", - "pouchdb-fetch": "7.3.1", - "pouchdb-mapreduce-utils": "7.3.1", - "pouchdb-md5": "7.3.1", - "pouchdb-utils": "7.3.1" - } - }, - "node_modules/pouchdb-adapter-http": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-adapter-http/-/pouchdb-adapter-http-7.3.1.tgz", - "integrity": "sha512-09spFXxAvDsa8Q987FAFrqeKDvt8hiCuDjciLCR/uYEO8qwXg05o5CXEVVsHycpGdna1b0+i6i3ZWH+69lxmbg==", - "dependencies": { - "argsarray": "0.0.1", - "pouchdb-binary-utils": "7.3.1", - "pouchdb-errors": "7.3.1", - "pouchdb-fetch": "7.3.1", - "pouchdb-utils": "7.3.1" - } - }, - "node_modules/pouchdb-binary-utils": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-7.3.1.tgz", - "integrity": "sha512-crZJNfAEOnUoRk977Qtmk4cxEv6sNKllQ6vDDKgQrQLFjMUXma35EHzNyIJr1s76J77Q4sqKQAmxz9Y40yHGtw==", - "dependencies": { - "buffer-from": "1.1.2" - } - }, - "node_modules/pouchdb-changes-filter": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-changes-filter/-/pouchdb-changes-filter-7.3.1.tgz", - "integrity": "sha512-C31zsslhlxyFdlKPdZ0013Z4GIsWjoSTgptfamrPnXEtOS6EX4jLtcmiGURCIXmZlcDGKRm8qWHL3vikwITalA==", - "dependencies": { - "pouchdb-errors": "7.3.1", - "pouchdb-selector-core": "7.3.1", - "pouchdb-utils": "7.3.1" - } - }, - "node_modules/pouchdb-collate": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-7.3.1.tgz", - "integrity": "sha512-o4gyGqDMLMSNzf6EDTr3eHaH/JRMoqRhdc+eV+oA8u00nTBtr9wD+jypVe2LbgKLJ4NWqx2qVkXiTiQdUFtsLQ==" - }, - "node_modules/pouchdb-collections": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-7.3.1.tgz", - "integrity": "sha512-yUyDqR+OJmtwgExOSJegpBJXDLAEC84TWnbAYycyh+DZoA51Yw0+XVQF5Vh8Ii90/Ut2xo88fmrmp0t6kqom8w==" - }, - "node_modules/pouchdb-core": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-core/-/pouchdb-core-7.3.1.tgz", - "integrity": "sha512-9jRZ70+4wrDohJQQ2OA8T9zzanefWf03ugGis5NJL24cpar8LjvQnceRo8X4KCQfVJr9su9LFe4L6YBqneE1VA==", - "dependencies": { - "argsarray": "0.0.1", - "inherits": "2.0.4", - "pouchdb-changes-filter": "7.3.1", - "pouchdb-collections": "7.3.1", - "pouchdb-errors": "7.3.1", - "pouchdb-fetch": "7.3.1", - "pouchdb-merge": "7.3.1", - "pouchdb-utils": "7.3.1" - } - }, - "node_modules/pouchdb-errors": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-7.3.1.tgz", - "integrity": "sha512-Zktz4gnXEUcZcty8FmyvtYUYsHskoST05m6H5/E2gg/0mCfEXq/XeyyLkZHaZmqD0ZPS9yNmASB1VaFWEKEaDw==", - "dependencies": { - "inherits": "2.0.4" - } - }, - "node_modules/pouchdb-fetch": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-7.3.1.tgz", - "integrity": "sha512-205xAtvdHRPQ4fp1h9+RmT9oQabo9gafuPmWsS9aEl3ER54WbY8Vaj1JHZGbU4KtMTYvW7H5088zLS7Nrusuag==", - "dependencies": { - "abort-controller": "3.0.0", - "fetch-cookie": "0.11.0", - "node-fetch": "2.6.7" - } - }, - "node_modules/pouchdb-fetch/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/pouchdb-mapreduce": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-mapreduce/-/pouchdb-mapreduce-7.3.1.tgz", - "integrity": "sha512-dm4YG8P1fNk85YGpEg79vpsV9xxqkumDqCof7+sykDfIZwqa1X5NLgUuw7Adsc+RFsHU23Vsk2ho/HzgRBkFvw==", - "dependencies": { - "pouchdb-abstract-mapreduce": "7.3.1", - "pouchdb-mapreduce-utils": "7.3.1", - "pouchdb-utils": "7.3.1" - } - }, - "node_modules/pouchdb-mapreduce-utils": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-7.3.1.tgz", - "integrity": "sha512-oUMcq82+4pTGQ6dtrhgORHOVHZSr6w/5tFIUGlv7RABIDvJarL4snMawADjlpiEwPdiQ/ESG8Fqt8cxqvqsIgg==", - "dependencies": { - "argsarray": "0.0.1", - "inherits": "2.0.4", - "pouchdb-collections": "7.3.1", - "pouchdb-utils": "7.3.1" - } - }, - "node_modules/pouchdb-md5": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-7.3.1.tgz", - "integrity": "sha512-aDV8ui/mprnL3xmt0gT/81DFtTtJiKyn+OxIAbwKPMfz/rDFdPYvF0BmDC9QxMMzGfkV+JJUjU6at0PPs2mRLg==", - "dependencies": { - "pouchdb-binary-utils": "7.3.1", - "spark-md5": "3.0.2" - } - }, - "node_modules/pouchdb-merge": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-merge/-/pouchdb-merge-7.3.1.tgz", - "integrity": "sha512-FeK3r35mKimokf2PQ2tUI523QWyZ4lYZ0Yd75FfSch/SPY6wIokz5XBZZ6PHdu5aOJsEKzoLUxr8CpSg9DhcAw==" - }, - "node_modules/pouchdb-selector-core": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-selector-core/-/pouchdb-selector-core-7.3.1.tgz", - "integrity": "sha512-HBX+nNGXcaL9z0uNpwSMRq2GNZd3EZXW+fe9rJHS0hvJohjZL7aRJLoaXfEdHPRTNW+CpjM3Rny60eGekQdI/w==", - "dependencies": { - "pouchdb-collate": "7.3.1", - "pouchdb-utils": "7.3.1" - } - }, - "node_modules/pouchdb-session-authentication": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/pouchdb-session-authentication/-/pouchdb-session-authentication-1.4.0.tgz", - "integrity": "sha512-77hisEECvPOuy3Efh5IGCi5EyAAmIcwWja14GSaMQLXm0Prcw76cLV1XOBQ/8EATvp7CgqnqcSJ5ZQv7kQpnWQ==", - "dependencies": { - "pouchdb-fetch": "^8.0.1" - }, - "engines": { - "node": ">=8.10.0", - "npm": ">=8.3.1" - } - }, - "node_modules/pouchdb-session-authentication/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/pouchdb-session-authentication/node_modules/pouchdb-fetch": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-8.0.1.tgz", - "integrity": "sha512-Px5HLT8MxqTujc8bpPRKoouznDTJa9XBGqCbhl95q6rhjWRfwZEvXjV92z0B5BALAM6D6avMyG0DjuNfUWnMuA==", - "dependencies": { - "abort-controller": "3.0.0", - "fetch-cookie": "0.11.0", - "node-fetch": "2.6.7" - } - }, - "node_modules/pouchdb-utils": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-7.3.1.tgz", - "integrity": "sha512-R3hHBo1zTdTu/NFs3iqkcaQAPwhIH0gMIdfVKd5lbDYlmP26rCG5pdS+v7NuoSSFLJ4xxnaGV+Gjf4duYsJ8wQ==", - "dependencies": { - "argsarray": "0.0.1", - "clone-buffer": "1.0.0", - "immediate": "3.3.0", - "inherits": "2.0.4", - "pouchdb-collections": "7.3.1", - "pouchdb-errors": "7.3.1", - "pouchdb-md5": "7.3.1", - "uuid": "8.3.2" - } - }, - "node_modules/pouchdb-utils/node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" - }, - "node_modules/pouchdb-utils/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==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process": { - "version": "0.11.10", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "license": "MIT" - }, - "node_modules/process-warning": { - "version": "3.0.0", - "license": "MIT" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/prom-client": { - "version": "15.1.2", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.4.0", - "tdigest": "^0.1.1" - }, - "engines": { - "node": "^16 || ^18 || >=20" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" - }, - "node_modules/properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/properties/-/properties-1.2.1.tgz", - "integrity": "sha512-qYNxyMj1JeW54i/EWEFsM1cVwxJbtgPp8+0Wg9XjNaK6VE/c4oRi6PNu5p7w1mNXEIQIjV5Wwn8v8Gz82/QzdQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" - }, - "node_modules/ps-tree": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "event-stream": "=3.3.4" - }, - "bin": { - "ps-tree": "bin/ps-tree.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/pump": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - } - }, - "node_modules/pumpify/node_modules/duplexify": { - "version": "4.1.3", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "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" - } - ], - "license": "MIT" - }, - "node_modules/queue-promise": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/queue-promise/-/queue-promise-2.2.1.tgz", - "integrity": "sha512-C3eyRwLF9m6dPV4MtqMVFX+Xmc7keZ9Ievm3jJ/wWM5t3uVbFnGsJXwpYzZ4LaIEcX9bss/mdaKzyrO6xheRuA==", - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/quick-format-unescaped": { - "version": "4.0.4", - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "license": "MIT", - "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", - "devOptional": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readline-sync": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", - "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/real-require": { - "version": "0.2.0", - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/redact-basic-auth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/redact-basic-auth/-/redact-basic-auth-1.0.1.tgz", - "integrity": "sha512-IWiuzGU0LERKFBQNO+TpDvos4ucLWepwdgAAXug9kMrpM/i/ndmouQpZee/AyyGyUfkwfqYHrKy5tJz+ZbsIJA==" - }, - "node_modules/redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-info": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/redis-info/-/redis-info-3.1.0.tgz", - "integrity": "sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg==", - "dependencies": { - "lodash": "^4.17.11" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "optional": true - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/resolve": { - "version": "1.22.8", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "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-from": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated" - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/ret": { - "version": "0.4.3", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "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", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rewire": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint": "^8.47.0" - } - }, - "node_modules/rfdc": { - "version": "1.3.0", - "license": "MIT" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "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" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex/node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/safe-regex2": { - "version": "3.1.0", - "license": "MIT", - "dependencies": { - "ret": "~0.4.0" - } - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/schema-utils/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/schema-utils/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==" - }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "license": "BSD-3-Clause" - }, - "node_modules/semver": { - "version": "7.5.4", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.6.0", - "license": "MIT" - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "license": "MIT" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "license": "ISC" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sinon": { - "version": "17.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "node_modules/sinon/node_modules/diff": { - "version": "5.1.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/sinon/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slice-ansi/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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/slice-ansi/node_modules/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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sonic-boom": { - "version": "3.8.0", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "node_modules/source-map": { - "version": "0.6.1", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.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==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated" - }, - "node_modules/spark-md5": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", - "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==" - }, - "node_modules/split": { - "version": "0.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split2": { - "version": "4.2.0", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" - }, - "node_modules/standard-as-callback": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } - }, - "node_modules/stream-browserify/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==" - }, - "node_modules/stream-browserify/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-combiner": { - "version": "0.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "~0.1.1" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "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" - } - }, - "node_modules/stream-http/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==" - }, - "node_modules/stream-http/node_modules/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==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.3", - "license": "MIT" + "node": ">= 0.10" + } }, - "node_modules/stream-transform": { - "version": "3.3.0", + "node_modules/proxy-from-env": { + "version": "1.1.0", "license": "MIT" }, - "node_modules/stream-wormhole": { - "version": "1.1.0", + "node_modules/ps-tree": { + "version": "1.2.0", + "dev": true, "license": "MIT", + "dependencies": { + "event-stream": "=3.3.4" + }, + "bin": { + "ps-tree": "bin/ps-tree.js" + }, "engines": { - "node": ">=4.0.0" + "node": ">= 0.10" } }, - "node_modules/string_decoder": { - "version": "1.3.0", + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/pump": { + "version": "3.0.0", "license": "MIT", "dependencies": { - "safe-buffer": "~5.2.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/string-argv": { - "version": "0.3.2", - "dev": true, + "node_modules/pumpify": { + "version": "2.0.1", "license": "MIT", - "engines": { - "node": ">=0.6.19" + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" } }, - "node_modules/string-width": { - "version": "4.2.3", + "node_modules/pumpify/node_modules/duplexify": { + "version": "4.1.3", "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", + "node_modules/punycode": { + "version": "2.3.1", "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/qs": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "side-channel": "^1.0.6" }, "engines": { - "node": ">= 0.4" + "node": ">=0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/queue-promise": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/queue-promise/-/queue-promise-2.2.1.tgz", + "integrity": "sha512-C3eyRwLF9m6dPV4MtqMVFX+Xmc7keZ9Ievm3jJ/wWM5t3uVbFnGsJXwpYzZ4LaIEcX9bss/mdaKzyrO6xheRuA==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.12.0" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "safe-buffer": "^5.1.0" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", + "node_modules/readable-stream": { + "version": "3.6.2", "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6" } }, - "node_modules/supports-color": { - "version": "8.1.1", + "node_modules/readdirp": { + "version": "3.6.0", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "picomatch": "^2.2.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=8.10.0" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", + "node_modules/readline-sync": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", + "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8.0" } }, - "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, + "node_modules/real-require": { + "version": "0.2.0", + "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": ">= 12.13.0" } }, - "node_modules/svgo/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==", - "dependencies": { - "color-convert": "^1.9.0" - }, + "node_modules/redact-basic-auth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/redact-basic-auth/-/redact-basic-auth-1.0.1.tgz", + "integrity": "sha512-IWiuzGU0LERKFBQNO+TpDvos4ucLWepwdgAAXug9kMrpM/i/ndmouQpZee/AyyGyUfkwfqYHrKy5tJz+ZbsIJA==" + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", "engines": { "node": ">=4" } }, - "node_modules/svgo/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/redis-info": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redis-info/-/redis-info-3.1.0.tgz", + "integrity": "sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg==", "dependencies": { - "sprintf-js": "~1.0.2" + "lodash": "^4.17.11" } }, - "node_modules/svgo/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==", + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "redis-errors": "^1.0.0" }, "engines": { "node": ">=4" } }, - "node_modules/svgo/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==", - "dependencies": { - "color-name": "1.1.3" + "node_modules/regexpp": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/svgo/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/svgo/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/relateurl": { + "version": "0.2.7", + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">= 0.10" } }, - "node_modules/svgo/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/svgo/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==", + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "lodash": "^4.17.19" }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/svgo/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" + "engines": { + "node": ">=0.10.0" }, - "bin": { - "mkdirp": "bin/cmd.js" + "peerDependencies": { + "request": "^2.34" } }, - "node_modules/svgo/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==", + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", "dependencies": { - "has-flag": "^3.0.0" + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" }, "engines": { - "node": ">=4" + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" } }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "psl": "^1.1.28", + "punycode": "^2.1.1" }, "engines": { - "node": ">=6.0.0" + "node": ">=0.8" } }, - "node_modules/table/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "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" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "engines": { - "node": ">=6" + "node": ">= 0.12" } }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "node_modules/table/node_modules/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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "engines": { - "node": ">=4" + "node": ">=0.6" } }, - "node_modules/table/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==" - }, - "node_modules/table/node_modules/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==", + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "psl": "^1.1.28", + "punycode": "^2.1.1" }, "engines": { - "node": ">=6" + "node": ">=0.8" } }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" } }, - "node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/tdigest": { - "version": "0.1.2", + "node_modules/require-from-string": { + "version": "2.0.2", "license": "MIT", - "dependencies": { - "bintrees": "1.0.2" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/terser": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", - "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { - "terser": "bin/terser" + "resolve": "bin/resolve" }, - "engines": { - "node": ">=6.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/terser-webpack-plugin": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.6.tgz", - "integrity": "sha512-2lBVf/VMVIddjSn3GqbT90GvIJ/eYXJkt8cTzU7NbjKqK8fwv18Ftr4PlbF46b/e88743iZFL5Dtr/rC4hjIeA==", - "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, + "node_modules/resolve-from": { + "version": "4.0.0", + "license": "MIT", "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" + "node": ">=4" } }, - "node_modules/terser-webpack-plugin/node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "node_modules/ret": { + "version": "0.4.3", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dependencies": { - "randombytes": "^2.1.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/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/text-decoding": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/text-table": { - "version": "0.2.0", - "license": "MIT" + "node_modules/reusify": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, - "node_modules/thread-stream": { - "version": "2.7.0", + "node_modules/rewire": { + "version": "7.0.0", + "dev": true, "license": "MIT", "dependencies": { - "real-require": "^0.2.0" + "eslint": "^8.47.0" } }, - "node_modules/through": { - "version": "2.3.8", + "node_modules/rfdc": { + "version": "1.3.0", "license": "MIT" }, - "node_modules/through2": { - "version": "2.0.5", - "license": "MIT", + "node_modules/rimraf": { + "version": "3.0.2", + "license": "ISC", "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", + "node_modules/run-parallel": { + "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", "dependencies": { - "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" + "queue-microtask": "^1.2.2" } }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT" }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", + "node_modules/safe-regex2": { + "version": "3.1.0", "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "ret": "~0.4.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "license": "MIT", + "engines": { + "node": ">=10" } }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dependencies": { - "setimmediate": "^1.0.4" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" }, "engines": { - "node": ">=0.6.0" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/schema-utils/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dependencies": { - "os-tmpdir": "~1.0.2" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=0.6.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==" + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dependencies": { - "kind-of": "^3.0.2" + "node_modules/schema-utils/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==" + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "node_modules/serialize-javascript": { + "version": "6.0.0", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "randombytes": "^2.1.0" } }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "license": "MIT" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", + "node_modules/setimmediate": { + "version": "1.0.5", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", "license": "MIT", "dependencies": { - "is-number": "^7.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=8.0" + "node": ">=8" } }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/to-regex/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, + "node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", "engines": { - "node": ">= 0.4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "node_modules/sinon": { + "version": "17.0.1", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "is-plain-object": "^2.0.4" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" } }, - "node_modules/toad-cache": { - "version": "3.7.0", - "license": "MIT", + "node_modules/sinon/node_modules/diff": { + "version": "5.1.0", + "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">=12" + "node": ">=0.3.1" } }, - "node_modules/toidentifier": { - "version": "1.0.1", + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/ts-api-utils": { - "version": "1.0.3", + "node_modules/slash": { + "version": "3.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" + "node": ">=8" } }, - "node_modules/ts-mocha": { - "version": "10.0.0", - "dev": true, + "node_modules/sonic-boom": { + "version": "3.8.0", "license": "MIT", "dependencies": { - "ts-node": "7.0.1" - }, - "bin": { - "ts-mocha": "bin/ts-mocha" - }, - "engines": { - "node": ">= 6.X.X" - }, - "optionalDependencies": { - "tsconfig-paths": "^3.5.0" - }, - "peerDependencies": { - "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" + "atomic-sleep": "^1.0.0" } }, - "node_modules/ts-mocha/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, + "node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/ts-mocha/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { - "node": ">=0.3.1" + "node": ">=0.10.0" } }, - "node_modules/ts-mocha/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, + "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==", "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/ts-mocha/node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "node_modules/spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==" + }, + "node_modules/split": { + "version": "0.3.3", "dev": true, + "license": "MIT", "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" + "through": "2" }, "engines": { - "node": ">=4.2.0" + "node": "*" } }, - "node_modules/ts-mocha/node_modules/yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", - "dev": true, + "node_modules/split2": { + "version": "4.2.0", + "license": "ISC", "engines": { - "node": ">=4" + "node": ">= 10.x" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "dependencies": { - "@cspotcode/source-map-support": "^0.8.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", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" }, "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.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" + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + }, + "node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", "engines": { - "node": ">=0.3.1" + "node": ">= 0.8" } }, - "node_modules/tsc-watch": { - "version": "6.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "node-cleanup": "^2.1.2", - "ps-tree": "^1.2.0", - "string-argv": "^0.3.1" - }, - "bin": { - "tsc-watch": "dist/lib/tsc-watch.js" - }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", "engines": { - "node": ">=12.12.0" - }, - "peerDependencies": { - "typescript": "*" + "node": ">=0.10.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", + "node_modules/stream-combiner": { + "version": "0.0.4", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "duplexer": "~0.1.1" } }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "node_modules/stream-shift": { + "version": "1.0.3", + "license": "MIT" }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==" + "node_modules/stream-transform": { + "version": "3.3.0", + "license": "MIT" }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, + "node_modules/stream-wormhole": { + "version": "1.1.0", + "license": "MIT", "engines": { - "node": "*" + "node": ">=4.0.0" } }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "dev": true, + "node_modules/string_decoder": { + "version": "1.3.0", "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" + "safe-buffer": "~5.2.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", + "node_modules/string-argv": { + "version": "0.3.2", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=0.6.19" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" + "node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "node_modules/supports-color": { + "version": "8.1.1", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "has-flag": "^4.0.0" }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -11262,587 +6563,578 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "node_modules/typescript": { - "version": "5.3.3", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "license": "BSD-2-Clause", "bin": { - "uglifyjs": "bin/uglifyjs" + "svgo": "bin/svgo" }, "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "node": ">=14.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/svgo" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "license": "MIT" - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "engines": { - "node": ">=0.10.0" + "node": ">= 10" } }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dependencies": { - "unique-slug": "^2.0.0" + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" } }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "node_modules/tdigest": { + "version": "0.1.2", + "license": "MIT", "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" + "bintrees": "1.0.2" } }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "node_modules/terser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } } }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "engines": { - "node": ">=0.10.0" + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" } }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "optional": true, - "engines": { - "node": ">=4", - "yarn": "*" - } + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/upper-case": { - "version": "1.1.3", + "node_modules/text-decoding": { + "version": "1.0.0", "license": "MIT" }, - "node_modules/uri-js": { - "version": "4.4.1", - "license": "BSD-2-Clause", + "node_modules/text-table": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/thread-stream": { + "version": "2.7.0", + "license": "MIT", "dependencies": { - "punycode": "^2.1.0" + "real-require": "^0.2.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated" + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" }, - "node_modules/url": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", - "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", + "node_modules/through2": { + "version": "2.0.5", + "license": "MIT", "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - }, - "engines": { - "node": ">= 0.4" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "license": "MIT", "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" + "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" } }, - "node_modules/url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" - }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", "dependencies": { - "inherits": "2.0.3" + "safe-buffer": "~5.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "license": "MIT" - }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" + "is-number": "^7.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8.0" } }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/uuid": { - "version": "9.0.1", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "node_modules/toad-cache": { + "version": "3.7.0", "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "engines": { + "node": ">=12" } }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==" - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" } }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + "node_modules/ts-api-utils": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } }, - "node_modules/watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "node_modules/ts-mocha": { + "version": "10.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "ts-node": "7.0.1" + }, + "bin": { + "ts-mocha": "bin/ts-mocha" + }, + "engines": { + "node": ">= 6.X.X" }, "optionalDependencies": { - "chokidar": "^3.4.1", - "watchpack-chokidar2": "^2.0.1" + "tsconfig-paths": "^3.5.0" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" } }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" + "node_modules/ts-mocha/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/watchpack-chokidar2/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "optional": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "node_modules/ts-mocha/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" } }, - "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "optional": true, + "node_modules/ts-mocha/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, "dependencies": { - "remove-trailing-separator": "^1.0.1" + "minimist": "^1.2.6" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "mkdirp": "bin/cmd.js" } }, - "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "optional": true, + "node_modules/ts-mocha/node_modules/ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "dependencies": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4.2.0" } }, - "node_modules/watchpack-chokidar2/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "optional": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, + "node_modules/ts-mocha/node_modules/yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/watchpack-chokidar2/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "optional": true, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "@cspotcode/source-map-support": "^0.8.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", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" }, - "optionalDependencies": { - "fsevents": "^1.2.7" + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.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/watchpack-chokidar2/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "optional": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, + "node_modules/ts-node/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.10.0" + "node": ">=0.3.1" } }, - "node_modules/watchpack-chokidar2/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "optional": true, + "node_modules/tsc-watch": { + "version": "6.0.4", + "dev": true, + "license": "MIT", "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "cross-spawn": "^7.0.3", + "node-cleanup": "^2.1.2", + "ps-tree": "^1.2.0", + "string-argv": "^0.3.1" + }, + "bin": { + "tsc-watch": "dist/lib/tsc-watch.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=12.12.0" + }, + "peerDependencies": { + "typescript": "*" } }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "optional": true, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dependencies": { - "is-extglob": "^2.1.0" + "safe-buffer": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "optional": true, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "license": "MIT", "dependencies": { - "binary-extensions": "^1.0.0" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/watchpack-chokidar2/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "optional": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=4" } }, - "node_modules/watchpack-chokidar2/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "optional": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, + "node_modules/type-fest": { + "version": "0.20.2", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/watchpack-chokidar2/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "optional": true, - "dependencies": { - "kind-of": "^3.0.2" + "node_modules/typescript": { + "version": "5.3.3", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=0.10.0" + "node": ">=14.17" } }, - "node_modules/watchpack-chokidar2/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "optional": true, - "dependencies": { - "is-buffer": "^1.1.5" + "node_modules/uglify-js": { + "version": "3.17.4", + "license": "BSD-2-Clause", + "bin": { + "uglifyjs": "bin/uglifyjs" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/watchpack-chokidar2/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "optional": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, + "node_modules/undici-types": { + "version": "5.26.5", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "engines": { - "node": ">=0.10.0" + "node": ">= 4.0.0" } }, - "node_modules/watchpack-chokidar2/node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "optional": true, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/watchpack-chokidar2/node_modules/micromatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/upper-case": { + "version": "1.1.3", + "license": "MIT" }, - "node_modules/watchpack-chokidar2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "optional": true, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", "dependencies": { - "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" + "punycode": "^2.1.0" } }, - "node_modules/watchpack-chokidar2/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "optional": true, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" } }, - "node_modules/watchpack-chokidar2/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==", - "optional": true + "node_modules/url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" }, - "node_modules/watchpack-chokidar2/node_modules/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==", - "optional": true, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "9.0.1", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], "dependencies": { - "safe-buffer": "~5.1.0" + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" } }, - "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "optional": true, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, "node_modules/webidl-conversions": { @@ -11851,39 +7143,39 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { - "version": "4.47.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz", - "integrity": "sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" }, "bin": { "webpack": "bin/webpack.js" }, "engines": { - "node": ">=6.11.5" + "node": ">=10.13.0" }, "funding": { "type": "opencollective", @@ -11892,97 +7184,27 @@ "peerDependenciesMeta": { "webpack-cli": { "optional": true - }, - "webpack-command": { - "optional": true } } }, "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, "node_modules/webpack/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dependencies": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" }, "engines": { - "node": ">=4.0.0" + "node": ">=8.0.0" } }, "node_modules/webpack/node_modules/estraverse": { @@ -11993,136 +7215,6 @@ "node": ">=4.0" } }, - "node_modules/webpack/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/webpack/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/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==" - }, - "node_modules/webpack/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/webpack/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -12145,60 +7237,11 @@ "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==", - "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/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, - "node_modules/worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dependencies": { - "errno": "~0.1.7" - } - }, "node_modules/workerpool": { "version": "6.2.1", "dev": true, @@ -12240,28 +7283,6 @@ "version": "1.0.2", "license": "ISC" }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/xmldom": { "version": "0.1.19", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.19.tgz", @@ -12294,10 +7315,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, "node_modules/yargs": { "version": "16.2.0", "dev": true, diff --git a/package.json b/package.json index 413728f8..b836fe6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cht-user-management", - "version": "1.4.2", + "version": "2.0.0", "main": "dist/index.js", "dependencies": { "@bull-board/api": "^5.17.0", @@ -18,11 +18,12 @@ "@types/lodash": "^4.14.201", "@types/luxon": "^3.4.2", "@types/node": "^20.8.8", + "@types/semver": "^7.5.8", "@types/uuid": "^9.0.6", "axios": "^1.5.1", "axios-retry": "^4.0.0", "bullmq": "^5.7.6", - "cht-conf": "^3.23.0", + "cht-conf": "github:medic/cht-conf#653-merge-primaries", "csv": "^6.3.5", "dotenv": "^16.3.1", "fastify": "^4.27.0", diff --git a/scripts/create-user-managers/create-user-managers.ts b/scripts/create-user-managers/create-user-managers.ts index e9231d74..43f1c6ae 100644 --- a/scripts/create-user-managers/create-user-managers.ts +++ b/scripts/create-user-managers/create-user-managers.ts @@ -3,8 +3,10 @@ import { Command } from 'commander'; import { AuthenticationInfo, ContactType } from '../../src/config'; import { createUserWithRetries } from '../../src/lib/retry-logic'; import Place from '../../src/services/place'; -import { UserPayload } from '../../src/services/user-payload'; +import RemotePlaceCache, { RemotePlace } from '../../src/lib/remote-place-cache'; +import { PropertyValues, UnvalidatedPropertyValue } from '../../src/property-value'; import UserManager from './ke_user_manager.json'; +import { UserPayload } from '../../src/services/user-payload'; const { ChtApi } = require('../../src/lib/cht-api'); // require is needed for rewire const ChtSession = require('../../src/lib/cht-session').default; // require is needed for rewire @@ -53,8 +55,8 @@ export default async function createUserManagers(argv: string[]) { async function createUserManager(username: string, placeDocId: string, chtApi: typeof ChtApi, adminUsername: string, passwordOverride?: string) { const place = new Place(UserManagerContactType); - place.contact.properties.name = `${username} (User Manager)`; - place.userRoleProperties.role = UserManagerContactType.user_role.join(' '); + place.contact.properties.name = new UnvalidatedPropertyValue(`${username} (User Manager)`, 'name'); + place.userRoleProperties.role = new UnvalidatedPropertyValue(UserManagerContactType.user_role.join(' '), 'role'); const chtPayload = place.asChtPayload(adminUsername); chtPayload.contact.role = 'user_manager'; @@ -96,8 +98,8 @@ function parseCommandlineArguments(argv: string[]): CommandLineArgs { } async function getPlaceDocId(county: string | undefined, chtApi: typeof ChtApi) { - const counties = await chtApi.getPlacesWithType('a_county'); - const countyMatches = counties.filter((c: any) => !county || c.name === county.toLowerCase()); + const counties = await RemotePlaceCache.getPlacesWithType(chtApi, UserManagerContactType, UserManagerContactType.hierarchy[0]); + const countyMatches = counties.filter((c: RemotePlace) => !county || PropertyValues.isMatch(county, c.name)); if (countyMatches.length < 1) { throw Error(`Could not find county "${county}"`); } diff --git a/scripts/create-user-managers/ke_user_manager.json b/scripts/create-user-managers/ke_user_manager.json index 3fe7cf67..4c1b3615 100644 --- a/scripts/create-user-managers/ke_user_manager.json +++ b/scripts/create-user-managers/ke_user_manager.json @@ -4,7 +4,15 @@ "contact_type": "person", "user_role": ["user_manager", "mm-online"], "username_from_place": false, - "hierarchy": [], + "hierarchy": [{ + "type": "name", + "friendly_name": "County", + "property_name": "name", + "required": false, + "parameter": ["\\sCounty"], + "contact_type": "a_county", + "level": 0 + }], "deactivate_users_on_replace": false, "replacement_property": { "friendly_name": "Unused", diff --git a/src/config/config-factory.ts b/src/config/config-factory.ts index dc6a7169..243b865b 100644 --- a/src/config/config-factory.ts +++ b/src/config/config-factory.ts @@ -4,7 +4,7 @@ import kenyaConfig from './chis-ke'; import togoConfig from './chis-tg'; import civConfig from './chis-civ'; -const CONFIG_MAP: { [key: string]: PartnerConfig } = { +export const CONFIG_MAP: { [key: string]: PartnerConfig } = { 'CHIS-KE': kenyaConfig, 'CHIS-UG': ugandaConfig, 'CHIS-TG': togoConfig, diff --git a/src/config/config-worker.ts b/src/config/config-worker.ts index 693451e0..81313f85 100644 --- a/src/config/config-worker.ts +++ b/src/config/config-worker.ts @@ -11,7 +11,13 @@ export const WorkerConfig = { host: environment.REDIS_HOST, port: Number(environment.REDIS_PORT), }, - moveContactQueue: 'MOVE_CONTACT_QUEUE', + chtConfQueueName: 'MOVE_CONTACT_QUEUE', + defaultJobOptions: { + attempts: 3, // Max retries for a failed job + backoff: { + type: 'custom', + }, + } }; const assertRedisConfig = () => { diff --git a/src/config/index.ts b/src/config/index.ts index 69b32141..70f4df25 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,6 +1,7 @@ import _ from 'lodash'; import { ChtApi, PlacePayload } from '../lib/cht-api'; import getConfigByKey from './config-factory'; +import Validation from '../validation'; export type ConfigSystem = { domains: AuthenticationInfo[]; @@ -28,10 +29,13 @@ export type ContactType = { hint?: string; }; +const KnownContactPropertyTypes = [...Validation.getKnownContactPropertyTypes()] as const; +export type ContactPropertyType = typeof KnownContactPropertyTypes[number]; + export type HierarchyConstraint = { friendly_name: string; property_name: string; - type: string; + type: ContactPropertyType; required: boolean; parameter? : string | string[] | object; errorDescription? : string; @@ -43,7 +47,7 @@ export type HierarchyConstraint = { export type ContactProperty = { friendly_name: string; property_name: string; - type: string; + type: ContactPropertyType; required: boolean; parameter? : string | string[] | object; errorDescription? : string; @@ -55,6 +59,7 @@ export type AuthenticationInfo = { useHttp?: boolean; }; + const { CONFIG_NAME, NODE_ENV, @@ -187,6 +192,33 @@ export class Config { return _.sortBy(domains, 'friendly'); } + // TODO: Joi? Chai? + public static assertValid({ config }: PartnerConfig = partnerConfig) { + for (const contactType of config.contact_types) { + const allHierarchyProperties = [...contactType.hierarchy, contactType.replacement_property]; + const allProperties = [ + ...contactType.place_properties, + ...contactType.contact_properties, + ...allHierarchyProperties, + Config.getUserRoleConfig(contactType), + ]; + + Config.getPropertyWithName(contactType.place_properties, 'name'); + Config.getPropertyWithName(contactType.contact_properties, 'name'); + + allProperties.forEach(property => { + if (!KnownContactPropertyTypes.includes(property.type)) { + throw Error(`Unknown property type "${property.type}"`); + } + }); + + const generatedHierarchyProperties = allHierarchyProperties.filter(hierarchy => hierarchy.type === 'generated'); + if (generatedHierarchyProperties.length) { + throw Error('Hierarchy properties cannot be of type "generated"'); + } + } + } + public static getCsvTemplateColumns(placeType: string) { const placeTypeConfig = Config.getContactType(placeType); const hierarchy = Config.getHierarchyWithReplacement(placeTypeConfig); @@ -205,3 +237,4 @@ export class Config { return columns; } } + diff --git a/src/index.ts b/src/index.ts index 95a599b7..e78be9f6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ require('dotenv').config(); +import { Config } from './config'; import build from './server'; import { env } from 'process'; const { @@ -6,15 +7,11 @@ const { } = process.env; const port: number = env.PORT ? parseInt(env.PORT) : 3500; +Config.assertValid(); (async () => { - const loggerConfig = { - transport: { - target: 'pino-pretty', - }, - }; const server = build({ - logger: loggerConfig, + logger: true, }); // in 1.1.0 we allowed INTERFACE to be declared in .env, but let's be diff --git a/src/lib/authentication.ts b/src/lib/authentication.ts index 720df9d7..c32c770a 100644 --- a/src/lib/authentication.ts +++ b/src/lib/authentication.ts @@ -2,10 +2,10 @@ import process from 'process'; import jwt from 'jsonwebtoken'; import ChtSession from './cht-session'; -const LOGIN_EXPIRES_AFTER_MS = 2 * 24 * 60 * 60 * 1000; -const QUEUE_SESSION_EXPIRATION = '48h'; +const LOGIN_EXPIRES_AFTER_MS = 4 * 24 * 60 * 60 * 1000; +const QUEUE_SESSION_EXPIRATION = '96h'; const { COOKIE_PRIVATE_KEY, WORKER_PRIVATE_KEY } = process.env; -const PRIVATE_KEY_SALT = '_'; // change to logout all users +const PRIVATE_KEY_SALT = '$'; // change to logout all users const COOKIE_SIGNING_KEY = COOKIE_PRIVATE_KEY + PRIVATE_KEY_SALT; export default class Auth { @@ -23,37 +23,38 @@ export default class Auth { } } - private static encodeToken(session: ChtSession, signingKey: string, expiresIn: string) { - const data = JSON.stringify(session); - return jwt.sign({ data }, signingKey, { expiresIn }); - } - - private static decodeToken(token: string, signingKey: string): ChtSession { - if (!token) { - throw new Error('invalid authentication token'); - } - - const { data } = jwt.verify(token, signingKey) as any; - return ChtSession.createFromDataString(data); - } - public static encodeTokenForCookie(session: ChtSession) { return this.encodeToken(session, COOKIE_SIGNING_KEY, '1 day'); } - public static decodeTokenForCookie(token: string): ChtSession { - return this.decodeToken(token, COOKIE_SIGNING_KEY); + public static createCookieSession(token: string): ChtSession { + return this.createSessionFromToken(token, COOKIE_SIGNING_KEY); } public static encodeTokenForWorker(session: ChtSession) { return this.encodeToken(session, `${WORKER_PRIVATE_KEY}`, QUEUE_SESSION_EXPIRATION); } - public static decodeTokenForWorker(token: string): ChtSession { - return this.decodeToken(token, `${WORKER_PRIVATE_KEY}`); + public static createWorkerSession(token: string): ChtSession { + return this.createSessionFromToken(token, `${WORKER_PRIVATE_KEY}`); } public static cookieExpiry() { return new Date(new Date().getTime() + LOGIN_EXPIRES_AFTER_MS); } + + + private static encodeToken(session: ChtSession, signingKey: string, expiresIn: string) { + const data = JSON.stringify(session); + return jwt.sign({ data }, signingKey, { expiresIn }); + } + + private static createSessionFromToken(token: string, signingKey: string): ChtSession { + if (!token) { + throw new Error('invalid authentication token'); + } + + const { data } = jwt.verify(token, signingKey) as any; + return ChtSession.createFromDataString(data); + } } diff --git a/src/lib/cht-api.ts b/src/lib/cht-api.ts index eb183b8f..7b6a244a 100644 --- a/src/lib/cht-api.ts +++ b/src/lib/cht-api.ts @@ -1,8 +1,9 @@ import _ from 'lodash'; +import { AxiosInstance } from 'axios'; import ChtSession from './cht-session'; import { Config, ContactType } from '../config'; +import { DateTime } from 'luxon'; import { UserPayload } from '../services/user-payload'; -import { AxiosInstance } from 'axios'; export type PlacePayload = { name: string; @@ -18,15 +19,19 @@ export type PlacePayload = { [key: string]: any; }; -export type RemotePlace = { - id: string; - name: string; - lineage: string[]; - ambiguities?: RemotePlace[]; +export type CreatedPlaceResult = { + placeId: string; + contactId?: string; +}; + +export type CouchDoc = { + _id: string; +}; - // sadly, sometimes invalid or uncreated objects "pretend" to be remote - // should reconsider this naming - type: 'remote' | 'local' | 'invalid'; +export type UserInfo = { + username: string; + place?: CouchDoc[] | CouchDoc | string[] | string; + roles?: string[]; }; export class ChtApi { @@ -38,47 +43,30 @@ export class ChtApi { this.axiosInstance = session.axiosInstance; } - // workaround https://github.com/medic/cht-core/issues/8674 - updateContactParent = async (parentId: string): Promise => { - const parentDoc = await this.getDoc(parentId); - const contactId = parentDoc?.contact?._id; - if (!contactId) { - throw Error('cannot find id of contact'); - } - - const contactDoc = await this.getDoc(contactId); - if (!contactDoc || !parentDoc) { - throw Error('cannot find parent or contact docs'); - } - - contactDoc.parent = minify(parentDoc); - - const putUrl = `medic/${contactId}`; - console.log('axios.put', putUrl); - const putResp = await this.axiosInstance.put(putUrl, contactDoc); - if (putResp.status !== 201) { - throw new Error(putResp.data); - } - - return contactDoc._id; - }; - - createPlace = async (payload: PlacePayload): Promise => { + async createPlace(payload: PlacePayload): Promise { const url = `api/v1/places`; console.log('axios.post', url); const resp = await this.axiosInstance.post(url, payload); - return resp.data.id; - }; + return { + placeId: resp.data.id, + contactId: resp.data.contact?.id, + }; + } // because there is no PUT for /api/v1/places - createContact = async (payload: PlacePayload): Promise => { + async createContact(payload: PlacePayload): Promise { + const payloadWithPlace = { + ...payload.contact, + place: payload._id, + }; + const url = `api/v1/people`; console.log('axios.post', url); - const resp = await this.axiosInstance.post(url, payload.contact); + const resp = await this.axiosInstance.post(url, payloadWithPlace); return resp.data.id; - }; + } - updatePlace = async (payload: PlacePayload, contactId: string): Promise => { + async updatePlace(payload: PlacePayload, contactId: string): Promise { const doc: any = await this.getDoc(payload._id); const payloadClone:any = _.cloneDeep(payload); @@ -101,9 +89,9 @@ export class ChtApi { } return doc; - }; + } - deleteDoc = async (docId: string): Promise => { + async deleteDoc(docId: string): Promise { const doc: any = await this.getDoc(docId); const deleteContactUrl = `medic/${doc._id}?rev=${doc._rev}`; @@ -112,49 +100,44 @@ export class ChtApi { if (!resp.data.ok) { throw Error('response from chtApi.deleteDoc was not OK'); } - }; - - disableUsersWithPlace = async (placeId: string): Promise => { - const usersToDisable: string[] = await this.getUsersAtPlace(placeId); - for (const userDocId of usersToDisable) { - await this.disableUser(userDocId); - } - return usersToDisable; - }; + } - disableUser = async (docId: string): Promise => { - const username = docId.substring('org.couchdb.user:'.length); + async disableUser(username: string): Promise { const url = `api/v1/users/${username}`; console.log('axios.delete', url); return this.axiosInstance.delete(url); - }; - - deactivateUsersWithPlace = async (placeId: string): Promise => { - const usersToDeactivate: string[] = await this.getUsersAtPlace(placeId); - for (const userDocId of usersToDeactivate) { - await this.deactivateUser(userDocId); - } - return usersToDeactivate; - }; + } - deactivateUser = async (docId: string): Promise => { - const username = docId.substring('org.couchdb.user:'.length); - const url = `api/v1/users/${username}`; + async updateUser(userInfo: UserInfo): Promise { + const url = `api/v1/users/${userInfo.username}`; console.log('axios.post', url); - const deactivationPayload = { roles: ['deactivated' ]}; - return this.axiosInstance.post(url, deactivationPayload); - }; + return this.axiosInstance.post(url, userInfo); + } + + async countContactsUnderPlace(docId: string): Promise { + const url = `medic/_design/medic/_view/contacts_by_depth`; + console.log('axios.get', url); + const resp = await this.axiosInstance.get(url, { + params: { + startkey: JSON.stringify([docId, 0]), + endkey: JSON.stringify([docId, 20]), + include_docs: false, + }, + }); - createUser = async (user: UserPayload): Promise => { + return resp.data?.rows?.length || 0; + } + + async createUser(user: UserPayload): Promise { const url = `api/v1/users`; console.log('axios.post', url); const axiosRequestionConfig = { 'axios-retry': { retries: 0 }, // upload-manager handles retries for this }; await this.axiosInstance.post(url, user, axiosRequestionConfig); - }; + } - getParentAndSibling = async (parentId: string, contactType: ContactType): Promise<{ parent: any; sibling: any }> => { + async getParentAndSibling(parentId: string, contactType: ContactType): Promise<{ parent: any; sibling: any }> { const url = `medic/_design/medic/_view/contacts_by_depth`; console.log('axios.get', url); const resp = await this.axiosInstance.get(url, { @@ -171,67 +154,64 @@ export class ChtApi { const parent = docs.find((d: any) => d.contact_type === parentType); const sibling = docs.find((d: any) => d.contact_type === contactType.name); return { parent, sibling }; - }; + } - getPlacesWithType = async (placeType: string) - : Promise => { - const url = `medic/_design/medic-client/_view/contacts_by_type_freetext`; + async getPlacesWithType(placeType: string): Promise { + const url = `medic/_design/medic-client/_view/contacts_by_type`; const params = { - startkey: JSON.stringify([ placeType, 'name:']), - endkey: JSON.stringify([ placeType, 'name:\ufff0']), + key: JSON.stringify([placeType]), include_docs: true, }; console.log('axios.get', url, params); const resp = await this.axiosInstance.get(url, { params }); + return resp.data.rows.map((row: any) => row.doc); + } - return resp.data.rows - .map((row: any): RemotePlace => { - const nameData = row.key[1]; - return { - id: row.id, - name: nameData.substring('name:'.length), - lineage: extractLineage(row.doc), - type: 'remote', - }; - }); - }; - - getDoc = async (id: string): Promise => { + async getDoc(id: string): Promise { const url = `medic/${id}`; console.log('axios.get', url); const resp = await this.axiosInstance.get(url); return resp.data; - }; + } + + async getUsersAtPlace(placeId: string): Promise { + const url = `api/v2/users?facility_id=${placeId}`; + console.log('axios.get', url); + const resp = await this.axiosInstance.get(url); + return resp.data?.map((doc: any): UserInfo => ({ + username: doc.username, + place: doc.place, + })); + } - private async getUsersAtPlace(placeId: string): Promise { - const url = `_users/_find`; + async lastSyncAtPlace(placeId: string): Promise { + const userIds = await this.getUsersAtPlace(placeId); + const usernames = userIds.map(userId => userId.username); + const result = await this.getLastSyncForUsers(usernames); + return result || DateTime.invalid('unknown'); + } + + private getLastSyncForUsers = async (usernames: string[]): Promise => { + if (!usernames?.length) { + return undefined; + } + + const url = '/medic-logs/_all_docs'; + const keys = usernames.map(username => `connected-user-${username}`); const payload = { - selector: { - facility_id: placeId, - }, + keys, + include_docs: true, }; console.log('axios.post', url); const resp = await this.axiosInstance.post(url, payload); - return resp.data?.docs?.map((d: any) => d._id); - } -} + const timestamps = resp.data?.rows?.map((row: any) => row.doc?.timestamp); -function minify(doc: any): any { - if (!doc) { - return; - } + if (!timestamps?.length) { + return undefined; + } - return { - _id: doc._id, - parent: minify(doc.parent), + const maxTimestamp = Math.max(timestamps); + return DateTime.fromMillis(maxTimestamp); }; } - -function extractLineage(doc: any): string[] { - if (doc?.parent?._id) { - return [doc.parent._id, ...extractLineage(doc.parent)]; - } - - return []; -} diff --git a/src/lib/cht-session.ts b/src/lib/cht-session.ts index 586ff7f1..ae98e694 100644 --- a/src/lib/cht-session.ts +++ b/src/lib/cht-session.ts @@ -1,33 +1,45 @@ import _ from 'lodash'; const axios = require('axios'); // require is needed for rewire - -import { AuthenticationInfo } from '../config'; import { AxiosHeaders, AxiosInstance } from 'axios'; import axiosRetry from 'axios-retry'; +import * as semver from 'semver'; + +import { AuthenticationInfo } from '../config'; import { axiosRetryConfig } from './retry-logic'; -import { RemotePlace } from './cht-api'; +import { RemotePlace } from './remote-place-cache'; const COUCH_AUTH_COOKIE_NAME = 'AuthSession='; const ADMIN_FACILITY_ID = '*'; +const ADMIN_ROLES = ['admin', '_admin']; axiosRetry(axios, axiosRetryConfig); +type SessionCreationDetails = { + authInfo: AuthenticationInfo; + username: string; + sessionToken: string; + facilityIds: string[]; + chtCoreVersion: string; +}; + export default class ChtSession { public readonly authInfo: AuthenticationInfo; public readonly username: string; public readonly facilityIds: string[]; public readonly axiosInstance: AxiosInstance; public readonly sessionToken: string; + public readonly chtCoreVersion: string; - private constructor(authInfo: AuthenticationInfo, sessionToken: string, username: string, facilityIds: string[]) { - this.authInfo = authInfo; - this.username = username; - this.facilityIds = facilityIds; - this.sessionToken = sessionToken; + private constructor(creationDetails: SessionCreationDetails) { + this.authInfo = creationDetails.authInfo; + this.username = creationDetails.username; + this.facilityIds = creationDetails.facilityIds; + this.sessionToken = creationDetails.sessionToken; + this.chtCoreVersion = creationDetails.chtCoreVersion; this.axiosInstance = axios.create({ - baseURL: ChtSession.createUrl(authInfo, ''), - headers: { Cookie: sessionToken }, + baseURL: ChtSession.createUrl(creationDetails.authInfo, ''), + headers: { Cookie: creationDetails.sessionToken }, }); axiosRetry(this.axiosInstance, axiosRetryConfig); if (!this.sessionToken || !this.authInfo.domain || !this.username || this.facilityIds.length === 0) { @@ -35,6 +47,10 @@ export default class ChtSession { } } + public get isAdmin(): boolean { + return this.facilityIds.includes(ADMIN_FACILITY_ID); + } + public static async create(authInfo: AuthenticationInfo, username : string, password: string): Promise { const sessionToken = await ChtSession.createSessionToken(authInfo, username, password); @@ -42,29 +58,19 @@ export default class ChtSession { throw new Error(`failed to obtain token for ${username} at ${authInfo.domain}`); } - const userDetails = await ChtSession.fetchUserDetails(authInfo, username, sessionToken); - const facilityIds = userDetails.isAdmin ? [ADMIN_FACILITY_ID] : userDetails.facilityId; - if (!facilityIds || facilityIds?.length === 0) { - throw Error(`User ${username} does not have a facility_id connected to their user doc`); - } - - return new ChtSession(authInfo, sessionToken, username, facilityIds); + const creationDetails = await ChtSession.fetchCreationDetails(authInfo, username, sessionToken); + return new ChtSession(creationDetails); } public static createFromDataString(data: string): ChtSession { - const parsed: { - authInfo: AuthenticationInfo; - sessionToken: string; - username: string; - facilityIds: string[]; - } = JSON.parse(data); - return new ChtSession(parsed.authInfo, parsed.sessionToken, parsed.username, parsed.facilityIds); + const parsed: any = JSON.parse(data); + return new ChtSession(parsed); } isPlaceAuthorized(remotePlace: RemotePlace): boolean { return this.facilityIds?.length > 0 && ( - this.facilityIds.includes(ADMIN_FACILITY_ID) + this.isAdmin || _.intersection(remotePlace?.lineage, this.facilityIds).length > 0 || this.facilityIds.includes(remotePlace?.id) ); @@ -90,29 +96,50 @@ export default class ChtSession { .find((header: string) => header.startsWith(COUCH_AUTH_COOKIE_NAME)); } - private static async fetchUserDetails(authInfo: AuthenticationInfo, username: string, sessionToken: string): - Promise<{isAdmin: boolean; facilityId?: string[]}> { - // would prefer to use the _users/org.couchdb.user:username doc - // only admins have access + GET api/v2/users returns all users and cant return just one - const sessionUrl = ChtSession.createUrl(authInfo, `medic/org.couchdb.user:${username}`); - const resp = await axios.get( - sessionUrl, - { - headers: { Cookie: sessionToken }, - }, - ); - - const adminRoles = ['admin', '_admin']; - const isAdmin = _.intersection(adminRoles, resp.data?.roles).length > 0; - let facilityId; - if (typeof resp.data?.facility_id === 'string') { - facilityId = [resp.data.facility_id]; - } else if (Array.isArray(resp.data?.facility_id)) { - facilityId = resp.data.facility_id; + private static async fetchCreationDetails(authInfo: AuthenticationInfo, username: string, sessionToken: string): Promise { + // api/v2/users returns all users prior to 4.6 even with ?facility_id + const paths = [`medic/org.couchdb.user:${username}`, 'api/v2/monitoring']; + const fetches = paths.map(path => { + const url = ChtSession.createUrl(authInfo, path); + return axios.get( + url, + { headers: { Cookie: sessionToken } }, + ); + }); + const [ + { data: userDoc }, + { data: { version: { app: chtCoreVersion } } } + ] = await Promise.all(fetches); + + const isAdmin = _.intersection(ADMIN_ROLES, userDoc?.roles).length > 0; + + const facilityIds = isAdmin ? [ADMIN_FACILITY_ID] : _.flatten([userDoc?.facility_id]).filter(Boolean); + if (!facilityIds?.length) { + throw Error(`User ${username} does not have a facility_id connected to their user doc`); } - return { isAdmin, facilityId }; + + ChtSession.assertCoreVersion(chtCoreVersion, authInfo.domain); + + return { + authInfo, + username, + sessionToken, + chtCoreVersion, + facilityIds, + }; } + private static assertCoreVersion(chtCoreVersion: any, domain: string) { + const coercedVersion = semver.valid(semver.coerce(chtCoreVersion)); + if (!coercedVersion) { + throw Error(`Cannot parse cht core version ${chtCoreVersion} for instance "${domain}"`); + } + + if (semver.lt(coercedVersion, '4.7.0')) { + throw Error(`CHT Core Version must be 4.7.0 or higher. "${domain}" is running ${chtCoreVersion}.`); + } + } + private static createUrl(authInfo: AuthenticationInfo, path: string) { const protocol = authInfo.useHttp ? 'http' : 'https'; return `${protocol}://${authInfo.domain}${path ? '/' : ''}${path}`; diff --git a/src/lib/credentials-file.ts b/src/lib/credentials-file.ts new file mode 100644 index 00000000..815282bd --- /dev/null +++ b/src/lib/credentials-file.ts @@ -0,0 +1,52 @@ +import { Config, ContactType } from '../config'; +import SessionCache from '../services/session-cache'; +import { stringify } from 'csv/sync'; + +type File = { + filename: string; + content: string; +}; + +export default function getCredentialsFiles(sessionCache: SessionCache, contactTypes: ContactType[]): File[] { + const files: File[] = []; + for (const contactType of contactTypes) { + const places = sessionCache.getPlaces({ type: contactType.name }); + if (!places.length) { + continue; + } + + const rows = places.map((place) => [ + ...Object.values(place.hierarchyProperties).map(prop => prop.formatted), + place.name, + place.contact.properties.name?.formatted, + place.contact.properties.phone?.formatted, + place.userRoles.join(' '), + place.creationDetails.username, + place.creationDetails.password, + ]); + + const constraints = Config.getHierarchyWithReplacement(contactType); + const props = Object.keys(places[0].hierarchyProperties) + .map(prop => constraints.find(c => c.property_name === prop)!.friendly_name); + const columns = [ + ...props, + contactType.friendly, + 'name', + 'phone', + 'role', + 'username', + 'password', + ]; + + const content = stringify(rows, { + columns, + header: true, + }); + files.push({ + filename: `${contactType.name}.csv`, + content, + }); + } + + return files; +} diff --git a/src/lib/disable-users.ts b/src/lib/disable-users.ts new file mode 100644 index 00000000..f3d50694 --- /dev/null +++ b/src/lib/disable-users.ts @@ -0,0 +1,89 @@ +import { ChtApi, UserInfo } from './cht-api'; + +const DEACTIVATION_ROLE = 'deactivated'; + +type UserApiPayload = { + username: string; + place?: string[]; +}; + +export class DisableUsers { + public static async disableUsersAt(placeId: string, chtApi: ChtApi): Promise { + return this.processUsersAt(placeId, chtApi, false); + } + + public static async deactivateUsersAt(placeId: string, chtApi: ChtApi): Promise { + return this.processUsersAt(placeId, chtApi, true); + } + + private static async processUsersAt(placeId: string, chtApi: ChtApi, deactivate: boolean): Promise { + const affectedUsers = await this.getAffectedUsers(placeId, chtApi); + if (affectedUsers.length === 0) { + return []; + } + + await this.updateAffectedUsers(affectedUsers, deactivate, chtApi); + return affectedUsers.map(user => user.username); + } + + private static async getAffectedUsers(facilityId: string, chtApi: ChtApi): Promise { + const result: UserApiPayload[] = []; + const userInfos = await chtApi.getUsersAtPlace(facilityId); + for (const userInfo of userInfos) { + const userPayload = this.toPostApiPayload(userInfo); + this.removeUserFromPlace(userPayload, facilityId); + result.push(userPayload); + } + + return result; + } + + private static toPostApiPayload(apiResponse: UserInfo): UserApiPayload { + const places = Array.isArray(apiResponse.place) ? apiResponse.place : [apiResponse.place]; + const placeIds: string[] = places.map(place => { + if (typeof place === 'string') { + return place; + } + + return place?._id; + }).filter(Boolean) as string[]; + + return { + username: apiResponse.username, + place: placeIds, + }; + } + + private static async updateAffectedUsers(userDocs: UserApiPayload[], deactivate: boolean, chtApi: ChtApi) { + for (const userDoc of userDocs) { + const places = userDoc.place && !Array.isArray(userDoc.place) ? [userDoc.place] : userDoc.place; + const noPlacesRemaining = !userDoc.place || places?.length === 0; + if (!noPlacesRemaining) { + await chtApi.updateUser(userDoc); + } else { + await this.disableUser(userDoc.username, deactivate, chtApi); + } + } + } + + private static async disableUser(username: string, deactivate: boolean, chtApi: ChtApi) { + if (deactivate) { + const userInfo: UserInfo = { + username, + roles: [DEACTIVATION_ROLE], + }; + + return chtApi.updateUser(userInfo); + } + + return chtApi.disableUser(username); + } + + private static removeUserFromPlace(userDoc: UserApiPayload, placeId: string) { + if (Array.isArray(userDoc.place)) { + userDoc.place = userDoc.place.filter(place => place !== placeId); + } else { + delete userDoc.place; + } + } +} diff --git a/src/lib/manage-hierarchy.ts b/src/lib/manage-hierarchy.ts new file mode 100644 index 00000000..7dd0c148 --- /dev/null +++ b/src/lib/manage-hierarchy.ts @@ -0,0 +1,167 @@ +import _ from 'lodash'; +import { DateTime } from 'luxon'; + +import Auth from './authentication'; +import { ChtApi } from './cht-api'; +import { ChtConfJobData } from '../worker/cht-conf-worker'; +import { ContactType } from '../config'; +import { JobParams, IQueue, getChtConfQueue } from './queues'; +import Place from '../services/place'; +import RemotePlaceResolver from './remote-place-resolver'; +import SessionCache from '../services/session-cache'; +import { RemotePlace } from './remote-place-cache'; + +export const HIERARCHY_ACTIONS = ['move', 'merge', 'delete']; +export type HierarchyAction = typeof HIERARCHY_ACTIONS[number]; + +const ACTIVE_USER_THRESHOLD_DAYS = 60; +const LARGE_PLACE_THRESHOLD_PLACE_COUNT = 100; + +export type WarningInformation = { + affectedPlaceCount: number; + lastSyncDescription: string; + userIsActive: boolean; + lotsOfPlaces: boolean; +}; + +export default class ManageHierarchyLib { + private constructor() { } + + public static async scheduleJob(job: JobParams, queueName: IQueue = getChtConfQueue()) { + await queueName.add(job); + } + + public static parseHierarchyAction(action: string = ''): HierarchyAction { + if (!HIERARCHY_ACTIONS.includes(action)) { + throw Error(`invalid action: "${action}"`); + } + + return action as HierarchyAction; + } + + public static async getJobDetails(formData: any, contactType: ContactType, sessionCache: SessionCache, chtApi: ChtApi): Promise { + const hierarchyAction = ManageHierarchyLib.parseHierarchyAction(formData.op); + const sourceLineage = await resolve('source_', formData, contactType, sessionCache, chtApi); + const destinationLineage = hierarchyAction === 'delete' ? [] : await resolve('destination_', formData, contactType, sessionCache, chtApi); + + const { sourceId, destinationId } = getSourceAndDestinationIds(hierarchyAction, sourceLineage, destinationLineage); + const jobData = getJobData(hierarchyAction, sourceId, destinationId, chtApi); + const jobName = getJobName(jobData.action, sourceLineage, destinationLineage); + const jobParam: JobParams = { + jobName, + jobData, + }; + + return jobParam; + } + + public static async getWarningInfo(job: JobParams, chtApi: ChtApi): Promise { + const { jobData: { sourceId } } = job; + const affectedPlaceCount = await chtApi.countContactsUnderPlace(sourceId); + const lastSyncTime = chtApi.chtSession.isAdmin ? await chtApi.lastSyncAtPlace(sourceId) : DateTime.invalid('must be admin'); + const syncBelowThreshold = diffNowInDays(lastSyncTime) < ACTIVE_USER_THRESHOLD_DAYS; + const lastSyncDescription = describeDateTime(lastSyncTime); + return { + affectedPlaceCount, + lastSyncDescription, + userIsActive: syncBelowThreshold && lastSyncDescription !== '-', + lotsOfPlaces: affectedPlaceCount > LARGE_PLACE_THRESHOLD_PLACE_COUNT, + }; + } +} + +function diffNowInDays(dateTime: DateTime): number { + return -(dateTime?.diffNow('days')?.days || 0); +} + +function describeDateTime(dateTime: DateTime): string { + if (!dateTime || !dateTime.isValid) { + return '-'; + } + + const diffNow = diffNowInDays(dateTime); + if (diffNow > 365) { + return 'over a year'; + } + + if (diffNow < 0) { + return '-'; + } + + return dateTime.toRelativeCalendar() || '-'; +} + +function getSourceAndDestinationIds( + hierarchyAction: HierarchyAction, + sourceLineage: (RemotePlace | undefined)[], + destinationLineage: (RemotePlace | undefined)[] +) { + const sourceId = sourceLineage[0]?.id; + if (!sourceId) { + throw Error('Unexpected error: Hierarchy operation failed due to missing source information'); + } + + if (hierarchyAction === 'delete') { + return { sourceId, destinationId: '' }; + } + + const destinationIndex = hierarchyAction === 'move' ? 1 : 0; + const destinationId = destinationLineage[destinationIndex]?.id; + if (!destinationId) { + throw Error('Unexpected error: Hierarchy operation failed due to missing destination information'); + } + + + if (hierarchyAction === 'move') { + if (destinationId === sourceLineage[1]?.id) { + throw Error(`Place "${sourceLineage[0]?.name.original}" already has "${destinationLineage[1]?.name.original}" as parent`); + } + } + + if (hierarchyAction === 'merge') { + if (destinationId === sourceId) { + throw Error(`Cannot merge place with self`); + } + } + + return { sourceId, destinationId }; +} + +function getJobName(action: string, sourceLineage: (RemotePlace | undefined)[], destinationLineage: (RemotePlace | undefined)[]): string { + const sourceDescription = describeLineage(sourceLineage); + const destinationDescription = describeLineage(destinationLineage); + const formattedDestinationDescription = destinationDescription && `_to_[${destinationDescription}]`; + return `${action}_[${sourceDescription}]${formattedDestinationDescription}`; + + function describeLineage(lineage: (RemotePlace | undefined)[]) : string | undefined { + return _.reverse([...lineage]) + .map(element => element?.name) + .filter(Boolean) + .join('.'); + } +} + +function getJobData(action: HierarchyAction, sourceId: string, destinationId: string, chtApi: ChtApi): ChtConfJobData { + const { authInfo } = chtApi.chtSession; + return { + action, + instanceUrl: `http${authInfo.useHttp ? '' : 's'}://${authInfo.domain}`, + sessionToken: Auth.encodeTokenForWorker(chtApi.chtSession), + sourceId, + destinationId, + }; +} + +async function resolve(prefix: string, formData: any, contactType: ContactType, sessionCache: SessionCache, chtApi: ChtApi) { + const place = new Place(contactType); + place.setPropertiesFromFormData(formData, prefix); + await RemotePlaceResolver.resolveOne(place, sessionCache, chtApi, { fuzz: true }); + place.validate(); + + const validationError = place.validationErrors && Object.keys(place.validationErrors).find(err => err.startsWith(prefix)); + if (validationError) { + throw Error(place.validationErrors?.[validationError]); + } + + return place.resolvedHierarchy; +} diff --git a/src/lib/move.ts b/src/lib/move.ts deleted file mode 100644 index 4613e457..00000000 --- a/src/lib/move.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { ContactType } from '../config'; -import SessionCache from '../services/session-cache'; -import { ChtApi } from './cht-api'; -import RemotePlaceResolver from './remote-place-resolver'; -import Place from '../services/place'; - -import { JobParams, IQueue, getMoveContactQueue } from '../lib/queues'; -import Auth from './authentication'; -import { MoveContactData } from '../worker/move-contact-worker'; - -export default class MoveLib { - constructor() { } - - public static async move( - formData: any, contactType: ContactType, sessionCache: SessionCache, chtApi: ChtApi, moveContactQueue: IQueue = getMoveContactQueue() - ) { - const fromLineage = await resolve('from_', formData, contactType, sessionCache, chtApi); - const toLineage = await resolve('to_', formData, contactType, sessionCache, chtApi); - - const toId = toLineage[1]?.id; - const fromId = fromLineage[0]?.id; - if (!toId || !fromId) { - throw Error('Unexpected error: Move failed'); - } - - if (toId === fromLineage[1]?.id) { - throw Error(`Place "${fromLineage[0]?.name}" already has "${toLineage[1]?.name}" as parent`); - } - - const jobName = this.getJobName(fromLineage, toLineage); - const jobData = this.getJobData(fromId, toId, chtApi); - const jobParam: JobParams = { - jobName, - jobData, - }; - await moveContactQueue.add(jobParam); - - return { - toLineage, - fromLineage, - success: true - }; - } - - private static getJobName(fromLineage: any, toLineage: any): string { - return `move_[${fromLineage[0]?.name}]_from_[${fromLineage[1]?.name}]_to_[${toLineage[1]?.name}]`; - } - - private static getJobData(fromId: string, toId: string, chtApi: ChtApi):MoveContactData { - const { authInfo } = chtApi.chtSession; - return { - contactId: fromId, - parentId: toId, - instanceUrl: `http${authInfo.useHttp ? '' : 's'}://${authInfo.domain}`, - sessionToken: Auth.encodeTokenForWorker(chtApi.chtSession), - }; - } -} - -async function resolve(prefix: string, formData: any, contactType: ContactType, sessionCache: SessionCache, chtApi: ChtApi) { - const place = new Place(contactType); - place.setPropertiesFromFormData(formData, prefix); - await RemotePlaceResolver.resolveOne(place, sessionCache, chtApi, { fuzz: true }); - place.validate(); - - const validationError = place.validationErrors && Object.keys(place.validationErrors).find(err => err.startsWith('hierarchy_')); - if (validationError) { - throw Error(place.validationErrors?.[validationError]); - } - - return place.resolvedHierarchy; -} diff --git a/src/lib/queues.ts b/src/lib/queues.ts index 2b68de2a..029c1219 100644 --- a/src/lib/queues.ts +++ b/src/lib/queues.ts @@ -1,5 +1,5 @@ import { v4 } from 'uuid'; -import { JobsOptions, Queue, ConnectionOptions } from 'bullmq'; +import { JobsOptions, Queue, ConnectionOptions, DefaultJobOptions } from 'bullmq'; import { WorkerConfig } from '../config/config-worker'; export interface IQueue { @@ -17,9 +17,9 @@ export class BullQueue implements IQueue { public readonly name: string; public readonly bullQueue: Queue; - constructor(queueName: string, connection: ConnectionOptions) { + constructor(queueName: string, connection: ConnectionOptions, defaultJobOptions?: DefaultJobOptions) { this.name = queueName; - this.bullQueue = new Queue(queueName, { connection }); + this.bullQueue = new Queue(queueName, { connection, defaultJobOptions }); } public async add(jobParams: JobParams): Promise { @@ -35,7 +35,8 @@ export class BullQueue implements IQueue { } } -export const getMoveContactQueue = () => new BullQueue( - WorkerConfig.moveContactQueue, - WorkerConfig.redisConnection +export const getChtConfQueue = () => new BullQueue( + WorkerConfig.chtConfQueueName, + WorkerConfig.redisConnection, + WorkerConfig.defaultJobOptions ); diff --git a/src/lib/remote-place-cache.ts b/src/lib/remote-place-cache.ts index deb11f35..3bffc991 100644 --- a/src/lib/remote-place-cache.ts +++ b/src/lib/remote-place-cache.ts @@ -1,5 +1,8 @@ import Place from '../services/place'; -import { ChtApi, RemotePlace } from './cht-api'; +import { ChtApi } from './cht-api'; +import { IPropertyValue } from '../property-value'; +import { ContactType, HierarchyConstraint } from '../config'; +import { NamePropertyValue } from '../property-value/name-property-value'; type RemotePlacesByType = { [key: string]: RemotePlace[]; @@ -9,18 +12,36 @@ type RemotePlaceDatastore = { [key: string]: RemotePlacesByType; }; +export type RemotePlace = { + id: string; + name: IPropertyValue; + lineage: string[]; + ambiguities?: RemotePlace[]; + + // sadly, sometimes invalid or uncreated objects "pretend" to be remote + // should reconsider this naming + type: 'remote' | 'local' | 'invalid'; +}; + export default class RemotePlaceCache { private static cache: RemotePlaceDatastore = {}; - public static async getPlacesWithType(chtApi: ChtApi, placeType: string) + public static async getPlacesWithType(chtApi: ChtApi, contactType: ContactType, hierarchyLevel: HierarchyConstraint) : Promise { - const domainStore = await RemotePlaceCache.getDomainStore(chtApi, placeType); + const domainStore = await RemotePlaceCache.getDomainStore(chtApi, contactType, hierarchyLevel); return domainStore; } - public static async add(place: Place, chtApi: ChtApi): Promise { - const domainStore = await RemotePlaceCache.getDomainStore(chtApi, place.type.name); - domainStore.push(place.asRemotePlace()); + public static add(place: Place, chtApi: ChtApi): void { + const { domain } = chtApi.chtSession.authInfo; + const placeType = place.type.name; + + const places = RemotePlaceCache.cache[domain]?.[placeType]; + // if there is no cache existing, discard the value + // it will be fetched if needed when the cache is built + if (places) { + places.push(place.asRemotePlace()); + } } public static clear(chtApi: ChtApi, contactTypeName?: string): void { @@ -29,19 +50,19 @@ export default class RemotePlaceCache { RemotePlaceCache.cache = {}; } else if (!contactTypeName) { delete RemotePlaceCache.cache[domain]; - } else { + } else if (RemotePlaceCache.cache[domain]) { delete RemotePlaceCache.cache[domain][contactTypeName]; } } - private static async getDomainStore(chtApi: ChtApi, placeType: string) + private static async getDomainStore(chtApi: ChtApi, contactType: ContactType, hierarchyLevel: HierarchyConstraint) : Promise { const { domain } = chtApi.chtSession.authInfo; + const placeType = hierarchyLevel.contact_type; const { cache: domainCache } = RemotePlaceCache; - const places = domainCache[domain]?.[placeType]; if (!places) { - const fetchPlacesWithType = chtApi.getPlacesWithType(placeType); + const fetchPlacesWithType = RemotePlaceCache.fetchRemotePlaces(chtApi, contactType, hierarchyLevel); domainCache[domain] = { ...domainCache[domain], [placeType]: await fetchPlacesWithType, @@ -50,4 +71,22 @@ export default class RemotePlaceCache { return domainCache[domain][placeType]; } + + private static async fetchRemotePlaces(chtApi: ChtApi, contactType: ContactType, hierarchyLevel: HierarchyConstraint): Promise { + function extractLineage(doc: any): string[] { + if (doc?.parent) { + return [doc.parent._id, ...extractLineage(doc.parent)]; + } + + return []; + } + + const docs = await chtApi.getPlacesWithType(hierarchyLevel.contact_type); + return docs.map((doc: any): RemotePlace => ({ + id: doc._id, + name: new NamePropertyValue(doc.name, hierarchyLevel), + lineage: extractLineage(doc), + type: 'remote', + })); + } } diff --git a/src/lib/remote-place-resolver.ts b/src/lib/remote-place-resolver.ts index e7d10a57..ce383d56 100644 --- a/src/lib/remote-place-resolver.ts +++ b/src/lib/remote-place-resolver.ts @@ -1,10 +1,11 @@ import _ from 'lodash'; import Place from '../services/place'; +import { IPropertyValue } from '../property-value'; import SessionCache from '../services/session-cache'; -import { RemotePlace, ChtApi } from './cht-api'; -import { Config, ContactType, HierarchyConstraint } from '../config'; -import { Validation } from './validation'; -import RemotePlaceCache from './remote-place-cache'; +import { ChtApi } from './cht-api'; +import { Config, HierarchyConstraint } from '../config'; +import RemotePlaceCache, { RemotePlace } from './remote-place-cache'; +import { UnvalidatedPropertyValue } from '../property-value'; type RemotePlaceMap = { [key: string]: RemotePlace }; @@ -13,8 +14,11 @@ export type PlaceResolverOptions = { }; export default class RemotePlaceResolver { - public static readonly NoResult: RemotePlace = { id: 'na', name: 'Place Not Found', type: 'invalid', lineage: [] }; - public static readonly Multiple: RemotePlace = { id: 'multiple', name: 'multiple places', type: 'invalid', lineage: [] }; + public static readonly NoResult: RemotePlace = + { id: 'na', name: new UnvalidatedPropertyValue('Place Not Found'), type: 'invalid', lineage: [] }; + + public static readonly Multiple: RemotePlace = + { id: 'multiple', name: new UnvalidatedPropertyValue('multiple places'), type: 'invalid', lineage: [] }; public static resolve = async ( places: Place[], @@ -38,36 +42,34 @@ export default class RemotePlaceResolver { // #91 - for editing: forget previous resolution delete place.resolvedHierarchy[hierarchyLevel.level]; - if (!place.hierarchyProperties[hierarchyLevel.property_name]) { + if (!place.hierarchyProperties[hierarchyLevel.property_name]?.original) { continue; } - const fuzzFunction = getFuzzFunction(place, hierarchyLevel, place.type); const mapIdToDetails = {}; if (hierarchyLevel.level > 0) { // no replacing local places - const searchKeys = getSearchKeys(place, hierarchyLevel.property_name, fuzzFunction, false); + const searchKeys = getSearchKeys(place, hierarchyLevel.property_name); for (const key of searchKeys) { - const localResult = findLocalPlaces(key, hierarchyLevel.contact_type, sessionCache, options, fuzzFunction); + const localResult = findLocalPlaces(key, hierarchyLevel.contact_type, sessionCache, options); if (localResult) { - addKeyToMap(mapIdToDetails, key, localResult); + addKeyToMap(mapIdToDetails, key.original, localResult); } } } const placesFoundRemote = await findRemotePlacesInHierarchy(place, hierarchyLevel, chtApi); placesFoundRemote.forEach(remotePlace => { - addKeyToMap(mapIdToDetails, remotePlace.name, remotePlace); + addKeyToMap(mapIdToDetails, remotePlace.name.original, remotePlace); if (options?.fuzz) { - const alteredName = fuzzFunction(remotePlace.name); - if (remotePlace.name !== alteredName) { - addKeyToMap(mapIdToDetails, alteredName, remotePlace); + if (remotePlace.name.original !== remotePlace.name.formatted) { + addKeyToMap(mapIdToDetails, remotePlace.name.formatted, remotePlace); } } }); const placeName = place.hierarchyProperties[hierarchyLevel.property_name]; - place.resolvedHierarchy[hierarchyLevel.level] = pickFromMapOptimistic(mapIdToDetails, placeName, fuzzFunction, !!options?.fuzz); + place.resolvedHierarchy[hierarchyLevel.level] = pickFromMapOptimistic(mapIdToDetails, placeName, !!options?.fuzz); } await RemotePlaceResolver.resolveAmbiguousParent(place); @@ -109,21 +111,12 @@ export default class RemotePlaceResolver { }; } -function getFuzzFunction(place: Place, hierarchyLevel: HierarchyConstraint, contactType: ContactType) { - const fuzzingProperty = hierarchyLevel.level === 0 ? contactType.replacement_property : hierarchyLevel; - if (fuzzingProperty.type === 'generated') { - throw Error(`Invalid configuration: hierarchy properties cannot be of type "generated".`); - } - - return (val: string) => Validation.formatSingle(place, fuzzingProperty, val); -} - async function findRemotePlacesInHierarchy( place: Place, hierarchyLevel: HierarchyConstraint, chtApi: ChtApi ) : Promise { - let searchPool = await RemotePlaceCache.getPlacesWithType(chtApi, hierarchyLevel.contact_type); + let searchPool = await RemotePlaceCache.getPlacesWithType(chtApi, place.type, hierarchyLevel); searchPool = searchPool.filter(remotePlace => chtApi.chtSession.isPlaceAuthorized(remotePlace)); const topDownHierarchy = Config.getHierarchyWithReplacement(place.type, 'desc'); @@ -152,49 +145,43 @@ async function findRemotePlacesInHierarchy( return searchPool; } -function getSearchKeys(place: Place, searchPropertyName: string, fuzzFunction: (key: string) => string, fuzz: boolean) - : string[] { +function getSearchKeys(place: Place, searchPropertyName: string) + : IPropertyValue[] { const keys = []; const key = place.hierarchyProperties[searchPropertyName]; if (key) { keys.push(key); } - - if (fuzz) { - keys.push(fuzzFunction(key)); - } - - return _.uniq(keys); + + return _.uniqBy(keys, 'formatted'); } -function pickFromMapOptimistic(map: RemotePlaceMap, placeName: string, fuzzFunction: (key: string) => string, fuzz: boolean) +function pickFromMapOptimistic(map: RemotePlaceMap, placeName: IPropertyValue, fuzz: boolean) : RemotePlace | undefined { if (!placeName) { return; } - const result = map[placeName.toLowerCase()]; + const result = map[placeName.original.toLowerCase()]; if (!fuzz) { return result; } - const fuzzyName = fuzzFunction(placeName); - const fuzzyResult = map[fuzzyName.toLowerCase()]; + const fuzzyResult = map[placeName.formatted.toLowerCase()]; const [optimisticResult] = [result, fuzzyResult].filter(r => r && r.type !== 'invalid'); return optimisticResult || result || fuzzyResult || RemotePlaceResolver.NoResult; } function findLocalPlaces( - name: string, + name: IPropertyValue, type: string, sessionCache: SessionCache, - options: PlaceResolverOptions | undefined, - fuzzFunction: (key: string) => string + options: PlaceResolverOptions | undefined ): RemotePlace | undefined { - let places = sessionCache.getPlaces({ type, nameExact: name }); + let places = sessionCache.getPlaces({ type, nameExact: name.original }); if (options?.fuzz && !places.length) { - places = sessionCache.getPlaces({ type, nameExact: fuzzFunction(name) }); + places = sessionCache.getPlaces({ type, nameExact: name.formatted }); } if (places.length > 1) { diff --git a/src/lib/search.ts b/src/lib/search.ts index dee99799..14c2963c 100644 --- a/src/lib/search.ts +++ b/src/lib/search.ts @@ -1,7 +1,8 @@ import _ from 'lodash'; import SessionCache from '../services/session-cache'; -import { ChtApi, RemotePlace } from './cht-api'; -import RemotePlaceCache from './remote-place-cache'; +import { ChtApi } from './cht-api'; +import { PropertyValues } from '../property-value'; +import RemotePlaceCache, { RemotePlace } from './remote-place-cache'; import RemotePlaceResolver from './remote-place-resolver'; import { Config, ContactType, HierarchyConstraint } from '../config'; import Place from '../services/place'; @@ -23,7 +24,7 @@ export default class SearchLib { const searchResults: RemotePlace[] = _.uniqWith([ ...localResults.map(r => r.asRemotePlace()), ...remoteResults, - ], (placeA: RemotePlace, placeB: RemotePlace) => placeA.name === placeB.name && placeA.type === placeB.type); + ], (placeA: RemotePlace, placeB: RemotePlace) => placeA.name.formatted === placeB.name.formatted && placeA.type === placeB.type); if (searchResults.length === 0) { searchResults.push(RemotePlaceResolver.NoResult); @@ -56,9 +57,9 @@ async function getRemoteResults( chtApi: ChtApi, dataPrefix: string ) : Promise { - let remoteResults = (await RemotePlaceCache.getPlacesWithType(chtApi, hierarchyLevel.contact_type)) + let remoteResults = (await RemotePlaceCache.getPlacesWithType(chtApi, contactType, hierarchyLevel)) .filter(remotePlace => chtApi.chtSession.isPlaceAuthorized(remotePlace)) - .filter(place => place.name.includes(searchString)); + .filter(place => PropertyValues.includes(place.name, searchString)); const topDownHierarchy = Config.getHierarchyWithReplacement(contactType, 'desc'); for (const constrainingHierarchy of topDownHierarchy) { @@ -66,14 +67,14 @@ async function getRemoteResults( break; } - const searchStringAtLevel = formData[`${dataPrefix}${constrainingHierarchy.property_name}`]?.toLowerCase(); + const searchStringAtLevel = formData[`${dataPrefix}${constrainingHierarchy.property_name}`]; if (!searchStringAtLevel) { continue; } - const placesAtLevel = await RemotePlaceCache.getPlacesWithType(chtApi, constrainingHierarchy.contact_type); + const placesAtLevel = await RemotePlaceCache.getPlacesWithType(chtApi, contactType, constrainingHierarchy); const relevantPlaceIds = placesAtLevel - .filter(remotePlace => remotePlace.name.includes(searchStringAtLevel)) + .filter(remotePlace => PropertyValues.includes(remotePlace.name, searchStringAtLevel)) .map(remotePlace => remotePlace.id); const hierarchyIndex = constrainingHierarchy.level - hierarchyLevel.level - 1; remoteResults = remoteResults.filter(result => relevantPlaceIds.includes(result.lineage[hierarchyIndex])); diff --git a/src/lib/validation.ts b/src/lib/validation.ts deleted file mode 100644 index 031a630f..00000000 --- a/src/lib/validation.ts +++ /dev/null @@ -1,205 +0,0 @@ -import _ from 'lodash'; -import { Config, ContactProperty } from '../config'; -import Place from '../services/place'; -import RemotePlaceResolver from './remote-place-resolver'; -import { RemotePlace } from './cht-api'; - -import ValidatorDateOfBirth from './validator-dob'; -import ValidatorGenerated from './validator-generated'; -import ValidatorName from './validator-name'; -import ValidatorPhone from './validator-phone'; -import ValidatorRegex from './validator-regex'; -import ValidatorSelectMultiple from './validator-select-multiple'; -import ValidatorSelectOne from './validator-select-one'; -import ValidatorSkip from './validator-skip'; -import ValidatorString from './validator-string'; - -export type ValidationError = { - property_name: string; - description: string; -}; - -export interface IValidator { - isValid(input: string, property? : ContactProperty) : boolean | string; - format(input : string, property? : ContactProperty) : string; - get defaultError(): string; -} - -type ValidatorMap = { - [key: string]: IValidator; -}; - -const TypeValidatorMap: ValidatorMap = { - dob: new ValidatorDateOfBirth(), - generated: new ValidatorGenerated(), - name: new ValidatorName(), - none: new ValidatorSkip(), - phone: new ValidatorPhone(), - regex: new ValidatorRegex(), - string: new ValidatorString(), - select_one: new ValidatorSelectOne(), - select_multiple: new ValidatorSelectMultiple(), -}; - -export class Validation { - public static getValidationErrors(place: Place) : ValidationError[] { - const requiredColumns = Config.getRequiredColumns(place.type, place.isReplacement); - const result = [ - ...Validation.validateHierarchy(place), - ...Validation.validateProperties(place.properties, place.type.place_properties, requiredColumns, 'place_'), - ...Validation.validateProperties(place.contact.properties, place.type.contact_properties, requiredColumns, 'contact_'), - ...Validation.validateProperties(place.userRoleProperties, [Config.getUserRoleConfig(place.type)], requiredColumns, 'user_') - ]; - - return result; - } - - public static format(place: Place): void { - const doFormatting = (withGenerators: boolean) => { - const isGenerator = (property: ContactProperty) => property.type === 'generated'; - const alterAllProperties = (propertiesToAlter: ContactProperty[], objectToAlter: any) => { - for (const property of propertiesToAlter) { - if (isGenerator(property) === withGenerators) { - this.alterProperty(place, property, objectToAlter); - } - } - }; - - alterAllProperties(place.type.contact_properties, place.contact.properties); - alterAllProperties(place.type.place_properties, place.properties); - for (const hierarchy of Config.getHierarchyWithReplacement(place.type)) { - this.alterProperty(place, hierarchy, place.hierarchyProperties); - } - }; - - doFormatting(false); - doFormatting(true); - } - - public static formatSingle(place: Place, propertyMatch: ContactProperty, val: string): string { - const object = { [propertyMatch.property_name]: val }; - Validation.alterProperty(place, propertyMatch, object); - return object[propertyMatch.property_name]; - } - - private static validateHierarchy(place: Place): ValidationError[] { - const result: ValidationError[] = []; - - const hierarchy = Config.getHierarchyWithReplacement(place.type); - hierarchy.forEach((hierarchyLevel, index) => { - const data = place.hierarchyProperties[hierarchyLevel.property_name]; - - if (hierarchyLevel.level !== 0 || data) { - const isExpected = hierarchyLevel.required; - const resolution = place.resolvedHierarchy[hierarchyLevel.level]; - const isValid = resolution?.type !== 'invalid' && ( - !isExpected || - resolution?.type === 'remote' || - resolution?.type === 'local' - ); - if (!isValid) { - const levelUp = hierarchy[index + 1]?.property_name; - result.push({ - property_name: `hierarchy_${hierarchyLevel.property_name}`, - description: this.describeInvalidRemotePlace( - resolution, - hierarchyLevel.contact_type, - data, - place.hierarchyProperties[levelUp] - ), - }); - } - } - }); - - return result; - } - - private static validateProperties( - obj : any, - properties : ContactProperty[], - requiredProperties: ContactProperty[], - prefix: string - ) : ValidationError[] { - const invalid: ValidationError[] = []; - - for (const property of properties) { - const value = obj[property.property_name]; - - const isRequired = requiredProperties.some((prop) => _.isEqual(prop, property)); - const errorPropertyName = `${prefix}${property.property_name}`; - if (value === undefined && isRequired) { - invalid.push({ - property_name: errorPropertyName, - description: 'Is Required', - }); - - continue; - } - - if (value || isRequired) { - const isValid = Validation.isValid(property, value); - if (isValid === false || typeof isValid === 'string') { - invalid.push({ - property_name: errorPropertyName, - description: isValid === false ? 'Value is invalid' : isValid as string, - }); - } - } - } - - return invalid; - } - - private static isValid(property : ContactProperty, value: string) : boolean | string { - const validator = this.getValidator(property); - try { - const isValid = validator.isValid(value, property); - return isValid === false ? property.errorDescription || validator.defaultError : isValid; - } catch (e) { - const error = `Error in isValid for '${property.type}': ${e}`; - console.log(error); - return error; - } - } - - private static alterProperty(place: Place, property : ContactProperty, obj: any) { - const value = obj[property.property_name]; - const validator = this.getValidator(property); - if (validator instanceof ValidatorGenerated) { - const altered = validator.format(place, property); - obj[property.property_name] = altered; - } else if (value) { - const altered = validator.format(value, property); - obj[property.property_name] = altered; - } - } - - private static getValidator(property: ContactProperty) : IValidator { - const validator = TypeValidatorMap[property.type]; - if (!validator) { - throw Error(`unvalidatable type: '${property.friendly_name}' has type '${property.type}'`); - } - - return validator; - } - - private static describeInvalidRemotePlace( - remotePlace: RemotePlace | undefined, - friendlyType: string, - searchStr?: string, - requiredParent?: string - ): string { - if (!searchStr) { - return `Cannot find ${friendlyType} because the search string is empty`; - } - - const requiredParentSuffix = requiredParent ? ` under '${requiredParent}'` : ''; - if (RemotePlaceResolver.Multiple.id === remotePlace?.id) { - const ambiguityDetails = JSON.stringify(remotePlace.ambiguities?.map(a => a.id)); - return `Found multiple ${friendlyType}s matching '${searchStr}'${requiredParentSuffix} ${ambiguityDetails}`; - } - - return `Cannot find '${friendlyType}' matching '${searchStr}'${requiredParentSuffix}`; - } -} diff --git a/src/liquid/app/form_switch.html b/src/liquid/app/form_switch.html index 2a53fd24..bb7d5a0c 100644 --- a/src/liquid/app/form_switch.html +++ b/src/liquid/app/form_switch.html @@ -1,8 +1,10 @@
{% capture header_caption %} {% if op == "bulk" %} Bulk Load from CSV - {% elsif op == "replace"%} Replace Existing - {% elsif op == "move"%} Move + {% elsif op == "replace" %} Replace Existing + {% elsif op == "move" %} Move + {% elsif op == "merge" %} Merge Two + {% elsif op == "delete" %} Delete a {% elsif op == "edit" %} Edit {% else %} New {% endif %} @@ -18,13 +20,26 @@ {{contactType.friendly}} {% endif %}

+

+ {% if op == "merge" %} + The first contact below will have all of its data moved to be under the second contact. + The first contact, once emptied, will be deleted. + This is useful to merge two duplicate records. This operation cannot be undone. + {% elsif op == "move" %} + The first contact selected below will be moved such that the second contact is its "parent". + Please ensure all affected users have synced their data fully before they are moved or data may be lost. + {% elsif op == "delete" %} + Deleting a contact will permanently remove the contact and all data within it. + This operation cannot be undone. + {% endif %} +

{% if op == "bulk" %} {% include "place/bulk_create_form.html" %} - {% elsif op == "move" %} - {% include "place/move_form.html" %} + {% elsif op == "move" or op == "merge" or op == "delete" %} + {% include "place/manage_hierarchy_form.html" %} {% else %} {% include "place/create_form.html" %} {% endif %} diff --git a/src/liquid/app/nav.html b/src/liquid/app/nav.html index 533ef2d8..802e88d4 100644 --- a/src/liquid/app/nav.html +++ b/src/liquid/app/nav.html @@ -31,11 +31,17 @@ diff --git a/src/liquid/components/manage_hierarchy_form_content.html b/src/liquid/components/manage_hierarchy_form_content.html new file mode 100644 index 00000000..e5eedccc --- /dev/null +++ b/src/liquid/components/manage_hierarchy_form_content.html @@ -0,0 +1,54 @@ +{% if error %} +
+ {{ error }} +
+{% endif %} + +{% if success %} +
+{% endif %} + + + + +{% if confirm %} + {% include "components/manage_hierarchy_warning" %} +{% endif %} + +
+
+

{{ sourceDescription }}

+ {% for hierarchy in sourceHierarchy %} + {% + include "components/search_input.html" + type=contactType.name + hierarchy=hierarchy + data=data + required=hierarchy.required + prefix="source_" + %} + {% endfor %} +
+ + {% if destinationHierarchy.size > 0 %} +
+

{{ destinationDescription }}

+ {% for hierarchy in destinationHierarchy %} + {% + include "components/search_input.html" + type=contactType.name + hierarchy=hierarchy + data=data + required=hierarchy.required + prefix="destination_" + %} + {% endfor %} +
+ {% endif %} + +
+
+ +
+
+
\ No newline at end of file diff --git a/src/liquid/components/manage_hierarchy_warning.html b/src/liquid/components/manage_hierarchy_warning.html new file mode 100644 index 00000000..aa9b15ef --- /dev/null +++ b/src/liquid/components/manage_hierarchy_warning.html @@ -0,0 +1,49 @@ +
+

Confirm you want to {{ op }} this:

+ + + {% for hierarchy in sourceHierarchy %} + {% capture property_name %}source_{{ hierarchy.property_name }}{% endcapture %} + {%if data[property_name] and data[property_name] != empty %} + + + + + {% endif %} + {% endfor %} + + {% for hierarchy in destinationHierarchy %} + {% capture property_name %}destination_{{ hierarchy.property_name }}{% endcapture %} + {%if data[property_name] and data[property_name] != empty %} + + + + + {% endif %} + {% endfor %} + + + + + + + + + + + +
Source {{ hierarchy.friendly_name }}{{ data[property_name] }}
Destination {{ hierarchy.friendly_name }}{{ data[property_name] }}
# of Affected Contacts{{ warningInfo.affectedPlaceCount }}
User's Last Sync{{ warningInfo.lastSyncDescription }}
+ + {% if isPermanent %}Cannot be undone{% endif %} + {% if warningInfo.userIsActive %}User is active{% endif %} + {% if warningInfo.lotsOfPlaces %}Large amount of data{% endif %} + +
+
+ + Cancel +
+
+ + +
\ No newline at end of file diff --git a/src/liquid/place/create_form.html b/src/liquid/place/create_form.html index 71a9bcad..23fa16dd 100644 --- a/src/liquid/place/create_form.html +++ b/src/liquid/place/create_form.html @@ -5,7 +5,7 @@
{% for hierarchy in hierarchy %} - {% if hierarchy.level != 0 or op == 'replace' or place.hierarchyProperties.replacement %} + {% if hierarchy.level != 0 or op == 'replace' or place.hierarchyProperties.replacement.original %} {% include "components/search_input.html" type=contactType.name diff --git a/src/liquid/place/directive_1_get_started.html b/src/liquid/place/directive_1_get_started.html index a926790a..19b567c1 100644 --- a/src/liquid/place/directive_1_get_started.html +++ b/src/liquid/place/directive_1_get_started.html @@ -15,7 +15,9 @@ Create New Replace Existing Upload from CSV - Move + Move + Merge + Delete diff --git a/src/liquid/place/manage_hierarchy_form.html b/src/liquid/place/manage_hierarchy_form.html new file mode 100644 index 00000000..8299b954 --- /dev/null +++ b/src/liquid/place/manage_hierarchy_form.html @@ -0,0 +1,31 @@ +
+ {% include "components/manage_hierarchy_form_content" %} + + +
\ No newline at end of file diff --git a/src/liquid/place/move_form.html b/src/liquid/place/move_form.html deleted file mode 100644 index 2788ed5a..00000000 --- a/src/liquid/place/move_form.html +++ /dev/null @@ -1,69 +0,0 @@ -
- {% if error %} -
- {{ error }} -
- {% endif %} - - {% if success %} -
- {% endif %} - - - -
-

From

- {% for hierarchy in fromHierarchy %} - {% - include "components/search_input.html" - type=contactType.name - hierarchy=hierarchy - data=data - required=hierarchy.required - prefix="from_" - %} - {% endfor %} -
-
-

To

- {% for hierarchy in toHierarchy %} - {% - include "components/search_input.html" - type=contactType.name - hierarchy=hierarchy - data=data - required=hierarchy.required - prefix="to_" - %} - {% endfor %} -
-
-
- - Cancel -
-
-
- - \ No newline at end of file diff --git a/src/plugins/bullmq.ts b/src/plugins/bullmq.ts index dfe59646..34caa8fe 100644 --- a/src/plugins/bullmq.ts +++ b/src/plugins/bullmq.ts @@ -5,7 +5,7 @@ import { BullMQAdapter } from '@bull-board/api/bullMQAdapter'; import { createBullBoard } from '@bull-board/api'; import { FastifyAdapter } from '@bull-board/fastify'; -import { getMoveContactQueue } from '../lib/queues'; +import { getChtConfQueue } from '../lib/queues'; async function bullMQBoardPlugin(fastify: FastifyInstance) { @@ -15,7 +15,7 @@ async function bullMQBoardPlugin(fastify: FastifyInstance) { createBullBoard({ queues: [ new BullMQAdapter( - getMoveContactQueue().bullQueue + getChtConfQueue().bullQueue ), ], serverAdapter, diff --git a/src/property-value/index.ts b/src/property-value/index.ts new file mode 100644 index 00000000..0f92a247 --- /dev/null +++ b/src/property-value/index.ts @@ -0,0 +1,68 @@ +import { HierarchyPropertyValue, ContactPropertyValue } from './validated-property-values'; +import { NamePropertyValue } from './name-property-value'; +import UnvalidatedPropertyValue from './unvalidated-property-value'; + +export class PropertyValues { + public static includes(searchWithin?: string | IPropertyValue, searchFor?: string | IPropertyValue): boolean { + const insensitiveMatch = (within: string, toFind: string) => within.includes(toFind); + return PropertyValues.doIt(insensitiveMatch, searchWithin, searchFor); + } + + public static isMatch(searchWithin?: string | IPropertyValue, searchFor?: string | IPropertyValue): boolean { + const insensitiveMatch = (within: string, toFind: string) => within === toFind; + return PropertyValues.doIt(insensitiveMatch, searchWithin, searchFor); + } + + private static doIt( + comparator: (a: string, b: string) => boolean, + a?: string | IPropertyValue, + b?: string | IPropertyValue, + ): boolean { + if (a === undefined || b === undefined) { + return false; + } + + const normalize = (str: string) => str.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase(); + const valueAsArray = (val: string | IPropertyValue): string[] => { + const values = typeof val === 'string' ? [val] : [val.formatted, val.original]; + return values.map(normalize); + }; + + const withinArray: string[] = valueAsArray(a); + const forArray: string[] = valueAsArray(b); + + + return withinArray.some(within => forArray.some(forX => comparator(within, forX))); + } +} + +export interface IPropertyValue { + get original(): string; + get formatted(): string; + get propertyNameWithPrefix(): string; + + validationError?: string; + + validate(): void; + toString(): string; +} + +/** + * For validating levels of the hierarchy +*/ +export { HierarchyPropertyValue }; + +/** + * For validating ContactProperty values + */ +export { ContactPropertyValue }; + +/** + * When storing a Name, and don't need access to an underlying Place + */ +export { NamePropertyValue }; + +/** + * When storing something that doesn't need validation + */ +export { UnvalidatedPropertyValue }; diff --git a/src/property-value/name-property-value.ts b/src/property-value/name-property-value.ts new file mode 100644 index 00000000..c9890865 --- /dev/null +++ b/src/property-value/name-property-value.ts @@ -0,0 +1,22 @@ +import { ContactProperty } from '../config'; +import { IPropertyValue } from '.'; +import Validation from '../validation'; + +export class NamePropertyValue implements IPropertyValue { + public original: string; + public formatted: string; + public propertyNameWithPrefix: string; + public validationError?: string; + + constructor(value: string, nameContactProperty: ContactProperty) { + this.original = value; + this.propertyNameWithPrefix = `place_name`; + this.formatted = Validation.formatDuringInitialization(nameContactProperty, value); + } + + public validate(): void {} + + public toString(): string { + return this.formatted; + } +} diff --git a/src/property-value/unvalidated-property-value.ts b/src/property-value/unvalidated-property-value.ts new file mode 100644 index 00000000..fca4739b --- /dev/null +++ b/src/property-value/unvalidated-property-value.ts @@ -0,0 +1,20 @@ +import { IPropertyValue } from '.'; + +export default class UnvalidatedPropertyValue implements IPropertyValue { + public original: string; + public formatted: string; + public propertyNameWithPrefix: string; + public validationError?: string; + + constructor(value: string, propertyNameWithPrefix: string = value) { + this.original = value; + this.formatted = value; + this.propertyNameWithPrefix = propertyNameWithPrefix; + } + + public validate(): void {} + + public toString(): string { + return this.formatted; + } +} diff --git a/src/property-value/validated-property-values.ts b/src/property-value/validated-property-values.ts new file mode 100644 index 00000000..49dd7957 --- /dev/null +++ b/src/property-value/validated-property-values.ts @@ -0,0 +1,74 @@ +import { Config, ContactProperty, HierarchyConstraint } from '../config'; +import { IPropertyValue } from '.'; +import Place from '../services/place'; +import Validation from '../validation'; + +abstract class AbstractPropertyValue implements IPropertyValue { + public readonly original: string; + protected readonly place: Place; + protected readonly property: ContactProperty; + private readonly propertyPrefix: string; + + protected formattedValue: string; + private validationErrorValue?: string; + + constructor(place: Place, property: ContactProperty, prefix: string, value: string) { + this.original = value; + this.place = place; + this.property = property; + this.propertyPrefix = prefix; + this.formattedValue = Validation.formatDuringInitialization(this.property, value); + } + + public validate(): void { + this.validationErrorValue = this.doValidation(); + } + + public get propertyNameWithPrefix(): string { + return this.propertyPrefix + this.property.property_name; + } + + public get formatted(): string { + return this.formattedValue; + } + + public get validationError(): string | undefined { + return this.validationErrorValue; + } + + public toString(): string { + return this.formatted; + } + + protected abstract doValidation(): string | undefined; +} + +export class ContactPropertyValue extends AbstractPropertyValue { + constructor(place: Place, property: ContactProperty, prefix: string, value: string) { + super(place, property, prefix, value); + } + + protected override doValidation(): string | undefined { + const requiredProperties = Config.getRequiredColumns(this.place.type, this.place.isReplacement); + const hasGeneratedProperty = this.property.type === 'generated'; + + let valueToValidate = this.original; + if (hasGeneratedProperty) { + this.formattedValue = Validation.generateAfterInitialization(this.place, this.property) || ''; + valueToValidate = this.formattedValue; + } + + return Validation.validateProperty(valueToValidate, this.property, requiredProperties); + } +} + +export class HierarchyPropertyValue extends AbstractPropertyValue { + constructor(place: Place, property: HierarchyConstraint, prefix: string, value: string) { + super(place, property, prefix, value); + } + + protected override doValidation(): string | undefined { + return Validation.validateHierarchyLevel(this.place, this.property as HierarchyConstraint); + } +} + diff --git a/src/routes/add-place.ts b/src/routes/add-place.ts index 1d18459c..72a69b35 100644 --- a/src/routes/add-place.ts +++ b/src/routes/add-place.ts @@ -77,7 +77,6 @@ export default async function addPlace(fastify: FastifyInstance) { // back to places list resp.header('HX-Redirect', `/`); - resp.header('HX-Redirect', '/'); return; } diff --git a/src/routes/files.ts b/src/routes/files.ts index 86b3236a..44c16f6e 100644 --- a/src/routes/files.ts +++ b/src/routes/files.ts @@ -1,8 +1,10 @@ import { FastifyInstance } from 'fastify'; +import JSZip from 'jszip'; import { stringify } from 'csv/sync'; + import { Config } from '../config'; +import getCredentialsFiles from '../lib/credentials-file'; import SessionCache from '../services/session-cache'; -import JSZip from 'jszip'; export default async function files(fastify: FastifyInstance) { fastify.get('/files/template/:placeType', async (req) => { @@ -14,40 +16,13 @@ export default async function files(fastify: FastifyInstance) { fastify.get('/files/credentials', async (req, reply) => { const sessionCache: SessionCache = req.sessionCache; + const zip = new JSZip(); - for (const contactType of Config.contactTypes()) { - const places = sessionCache.getPlaces({ type: contactType.name }); - if (!places.length) { - continue; - } - const rows = places.map((place) => [ - ...Object.values(place.hierarchyProperties), - place.name, - place.contact.properties.name, - place.contact.properties.phone, - place.userRoles.join(' '), - place.creationDetails.username, - place.creationDetails.password, - ]); - const constraints = Config.getHierarchyWithReplacement(contactType); - const props = Object.keys(places[0].hierarchyProperties).map(prop => constraints.find(c => c.property_name === prop)!.friendly_name); - const columns = [ - ...props, - contactType.friendly, - 'name', - 'phone', - 'role', - 'username', - 'password', - ]; - zip.file( - `${contactType.name}.csv`, - stringify(rows, { - columns, - header: true, - }) - ); + const files = getCredentialsFiles(sessionCache, Config.contactTypes()); + for (const file of files) { + zip.file(file.filename, file.content); } + reply.header('Content-Disposition', `attachment; filename="${Date.now()}_${req.chtSession.authInfo.friendly}_users.zip"`); return zip.generateNodeStream(); }); diff --git a/src/routes/manage-hierarchy.ts b/src/routes/manage-hierarchy.ts new file mode 100644 index 00000000..7dec55f5 --- /dev/null +++ b/src/routes/manage-hierarchy.ts @@ -0,0 +1,64 @@ +import { Config } from '../config'; +import { ChtApi } from '../lib/cht-api'; +import { FastifyInstance } from 'fastify'; +import ManageHierarchyLib from '../lib/manage-hierarchy'; +import SessionCache from '../services/session-cache'; +import { hierarchyViewModel } from '../services/hierarchy-view-model'; + +export default async function sessionCache(fastify: FastifyInstance) { + fastify.get('/manage-hierarchy/:action/:placeType', async (req, resp) => { + const params: any = req.params; + const placeType = params.placeType; + const contactTypes = Config.contactTypes(); + + const contactType = Config.getContactType(placeType); + const tmplData = { + view: 'manage-hierarchy', + op: params.action, + logo: Config.getLogoBase64(), + contactTypes, + contactType, + session: req.chtSession, + ...hierarchyViewModel(params.action, contactType), + }; + + return resp.view('src/liquid/app/view.html', tmplData); + }); + + fastify.post('/manage-hierarchy', async (req, resp) => { + const formData:any = req.body; + + const sessionCache: SessionCache = req.sessionCache; + const contactType = Config.getContactType(formData.place_type); + const chtApi = new ChtApi(req.chtSession); + + const tmplData: any = { + view: 'manage-hierarchy', + op: formData.op, + logo: Config.getLogoBase64(), + contactType, + data: formData, + session: req.chtSession, + ...hierarchyViewModel(formData.op, contactType), + }; + + try { + const isConfirmed = formData.confirmed === 'true'; + const job = await ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApi); + if (isConfirmed) { + await ManageHierarchyLib.scheduleJob(job); + tmplData.success = true; + } else { + const warningInfo = await ManageHierarchyLib.getWarningInfo(job, chtApi); + tmplData.warningInfo = warningInfo; + } + + tmplData.confirm = !isConfirmed; + return resp.view('src/liquid/components/manage_hierarchy_form_content.html', tmplData); + } catch (e: any) { + tmplData.error = e.toString(); + return resp.view('src/liquid/components/manage_hierarchy_form_content.html', tmplData); + } + }); +} + diff --git a/src/routes/move.ts b/src/routes/move.ts deleted file mode 100644 index 0a2dbf77..00000000 --- a/src/routes/move.ts +++ /dev/null @@ -1,80 +0,0 @@ -import _ from 'lodash'; - -import { Config, ContactType } from '../config'; -import { ChtApi } from '../lib/cht-api'; -import { FastifyInstance } from 'fastify'; -import MoveLib from '../lib/move'; -import SessionCache from '../services/session-cache'; - -export default async function sessionCache(fastify: FastifyInstance) { - fastify.get('/move/:placeType', async (req, resp) => { - const params: any = req.params; - const placeType = params.placeType; - const contactTypes = Config.contactTypes(); - - const contactType = Config.getContactType(placeType); - const tmplData = { - view: 'move', - op: 'move', - logo: Config.getLogoBase64(), - contactTypes, - contactType, - session: req.chtSession, - ...moveViewModel(contactType), - }; - - return resp.view('src/liquid/app/view.html', tmplData); - }); - - fastify.post('/move', async (req, resp) => { - const formData:any = req.body; - - const sessionCache: SessionCache = req.sessionCache; - const contactType = Config.getContactType(formData.place_type); - const chtApi = new ChtApi(req.chtSession); - - try { - const result = await MoveLib.move(formData, contactType, sessionCache, chtApi); - - const tmplData = { - view: 'move', - op: 'move', - logo: Config.getLogoBase64(), - contactType, - session: req.chtSession, - ...moveViewModel(contactType), - ...result - }; - return resp.view('src/liquid/place/move_form.html', tmplData); - } catch (e: any) { - const tmplData = { - view: 'move', - op: 'move', - contactTypes: Config.contactTypes(), - session: req.chtSession, - data: formData, - contactType, - ...moveViewModel(contactType), - error: e.toString(), - }; - - return resp.view('src/liquid/place/move_form.html', tmplData); - } - }); -} - -export function moveViewModel(contactType: ContactType) { - const parentTypeName = contactType.hierarchy.find(h => h.level === 1)?.contact_type; - if (!parentTypeName) { - throw Error('parent type name'); - } - - const fromHierarchy = Config.getHierarchyWithReplacement(contactType, 'desc'); - const toHierarchy = _.orderBy(contactType.hierarchy, 'level', 'desc'); - fromHierarchy[fromHierarchy.length - 1].friendly_name = contactType.friendly; - - return { - fromHierarchy, - toHierarchy, - }; -} diff --git a/src/routes/search.ts b/src/routes/search.ts index 2ad7a57e..c39c92b1 100644 --- a/src/routes/search.ts +++ b/src/routes/search.ts @@ -1,11 +1,13 @@ import { FastifyInstance } from 'fastify'; import { Config } from '../config'; -import { ChtApi, RemotePlace } from '../lib/cht-api'; +import { ChtApi } from '../lib/cht-api'; +import { RemotePlace } from '../lib/remote-place-cache'; import SessionCache from '../services/session-cache'; import SearchLib from '../lib/search'; -import { moveViewModel } from './move'; +import { HIERARCHY_ACTIONS } from '../lib/manage-hierarchy'; +import { hierarchyViewModel } from '../services/hierarchy-view-model'; export default async function place(fastify: FastifyInstance) { // returns search results dropdown @@ -63,7 +65,11 @@ export default async function place(fastify: FastifyInstance) { } const contactType = Config.getContactType(data.place_type); - const moveModel = moveViewModel(contactType); + let moveModel; + if (HIERARCHY_ACTIONS.includes(op)) { + moveModel = hierarchyViewModel(op, contactType); + } + const hierarchyLevel = Config.getHierarchyWithReplacement(contactType).find(hierarchy => hierarchy.level === level); if (!hierarchyLevel) { throw Error(`not hierarchy constraint at ${level}`); @@ -86,8 +92,8 @@ export default async function place(fastify: FastifyInstance) { } tmplData.backend = `/place/edit/${place.id}`; - } else if (op === 'move') { - tmplData.backend = `/move`; + } else if (HIERARCHY_ACTIONS.includes(op)) { + tmplData.backend = `/manage-hierarchy`; } return resp.view('src/liquid/app/form_switch.html', tmplData); diff --git a/src/server.ts b/src/server.ts index f72f56c0..75790858 100644 --- a/src/server.ts +++ b/src/server.ts @@ -70,7 +70,7 @@ const build = (opts: FastifyServerOptions): FastifyInstance => { } try { - const chtSession = Auth.decodeTokenForCookie(cookieToken); + const chtSession = Auth.createCookieSession(cookieToken); req.chtSession = chtSession; req.sessionCache = SessionCache.getForSession(chtSession); } catch (e) { diff --git a/src/services/contact.ts b/src/services/contact.ts index 437cd5ea..04d923e0 100644 --- a/src/services/contact.ts +++ b/src/services/contact.ts @@ -1,12 +1,11 @@ import { v4 as uuidv4 } from 'uuid'; import { Config, ContactType } from '../config'; +import { FormattedPropertyCollection } from './place'; export default class Contact { public id: string; public type: ContactType; - public properties: { - [key: string]: any; - }; + public properties: FormattedPropertyCollection; constructor(type: ContactType) { this.id = uuidv4(); @@ -16,6 +15,6 @@ export default class Contact { public get name() : string { const nameProperty = Config.getPropertyWithName(this.type.contact_properties, 'name'); - return this.properties[nameProperty.property_name]; + return this.properties[nameProperty.property_name]?.formatted; } } diff --git a/src/services/hierarchy-view-model.ts b/src/services/hierarchy-view-model.ts new file mode 100644 index 00000000..41b5864b --- /dev/null +++ b/src/services/hierarchy-view-model.ts @@ -0,0 +1,39 @@ +import _ from 'lodash'; +import { Config, ContactType } from '../config'; +import ManageHierarchyLib from '../lib/manage-hierarchy'; + +export function hierarchyViewModel(action: string, contactType: ContactType) { + const parentTypeName = contactType.hierarchy.find(h => h.level === 1)?.contact_type; + if (!parentTypeName) { + throw Error('Parent type name not found in config'); + } + + const isPermanent = ['merge', 'delete'].includes(action); + const sourceHierarchy = Config.getHierarchyWithReplacement(contactType, 'desc'); + sourceHierarchy[sourceHierarchy.length - 1].friendly_name = contactType.friendly; + const hierarchyAction = ManageHierarchyLib.parseHierarchyAction(action); + const destinationHierarchy = getDestinationHierarchy(); + const sourceDescription = hierarchyAction === 'move' ? 'Move This Contact' : 'Delete This Contact'; + const destinationDescription = hierarchyAction === 'move' ? 'To Have This Parent' : 'After Moving Data Into'; + + return { + isPermanent, + sourceDescription, + destinationDescription, + + sourceHierarchy, + destinationHierarchy, + }; + + function getDestinationHierarchy() { + if (hierarchyAction === 'delete') { + return []; + } + + if (hierarchyAction === 'merge') { + return sourceHierarchy; + } + + return _.orderBy(contactType.hierarchy, 'level', 'desc'); + } +} diff --git a/src/services/place-factory.ts b/src/services/place-factory.ts index 74f76c82..9dd975cd 100644 --- a/src/services/place-factory.ts +++ b/src/services/place-factory.ts @@ -1,19 +1,18 @@ import { parse } from 'csv'; import { ChtApi } from '../lib/cht-api'; -import { Config, ContactType } from '../config'; -import Place from './place'; +import { Config, ContactProperty, ContactType } from '../config'; +import Place, { FormattedPropertyCollection } from './place'; import SessionCache from './session-cache'; import RemotePlaceResolver from '../lib/remote-place-resolver'; +import { HierarchyPropertyValue, ContactPropertyValue, IPropertyValue } from '../property-value'; export default class PlaceFactory { public static async createFromCsv(csvBuffer: Buffer, contactType: ContactType, sessionCache: SessionCache, chtApi: ChtApi) : Promise { const places = await PlaceFactory.loadPlacesFromCsv(csvBuffer, contactType); - const validateAll = () => places.forEach(p => p.validate()); - await RemotePlaceResolver.resolve(places, sessionCache, chtApi, { fuzz: true }); - validateAll(); + places.forEach(place => place.validate()); sessionCache.savePlaces(...places); return places; } @@ -22,7 +21,6 @@ export default class PlaceFactory { : Promise => { const place = new Place(contactType); place.setPropertiesFromFormData(formData, 'hierarchy_'); - await RemotePlaceResolver.resolveOne(place, sessionCache, chtApi, { fuzz: true }); place.validate(); sessionCache.savePlaces(place); @@ -58,24 +56,36 @@ export default class PlaceFactory { csvColumns.push(...row); } else { const place = new Place(contactType); - for (const placeProperty of contactType.place_properties) { - place.properties[placeProperty.property_name] = row[csvColumns.indexOf(placeProperty.friendly_name)]; + const lookupPropertyAndCreateValue = ( + writeTo: FormattedPropertyCollection, + contactProperty: ContactProperty, + createFromValue: (value: string) => IPropertyValue + ) => { + const value = row[csvColumns.indexOf(contactProperty.friendly_name)] || ''; + const validatedProperty = createFromValue(value); + writeTo[contactProperty.property_name] = validatedProperty; + }; + + for (const hierarchyConstraint of Config.getHierarchyWithReplacement(contactType)) { + const createFromValue = (value: string) => new HierarchyPropertyValue(place, hierarchyConstraint, 'hierarchy_', value); + lookupPropertyAndCreateValue(place.hierarchyProperties, hierarchyConstraint, createFromValue); } - for (const contactProperty of contactType.contact_properties) { - place.contact.properties[contactProperty.property_name] = row[csvColumns.indexOf(contactProperty.friendly_name)]; + // place properties must be read after hierarchy constraints since validation logic is dependent on isReplacement + for (const placeProperty of contactType.place_properties) { + const createFromValue = (value: string) => new ContactPropertyValue(place, placeProperty, 'place_', value); + lookupPropertyAndCreateValue(place.properties, placeProperty, createFromValue); } - for (const hierarchyConstraint of Config.getHierarchyWithReplacement(contactType)) { - const columnIndex = csvColumns.indexOf(hierarchyConstraint.friendly_name); - place.hierarchyProperties[hierarchyConstraint.property_name] = row[columnIndex]; + for (const contactProperty of contactType.contact_properties) { + const createFromValue = (value: string) => new ContactPropertyValue(place, contactProperty, 'contact_', value); + lookupPropertyAndCreateValue(place.contact.properties, contactProperty, createFromValue); } if (Config.hasMultipleRoles(contactType)) { const userRoleProperty = Config.getUserRoleConfig(contactType); - place.userRoleProperties[userRoleProperty.property_name] = row[ - csvColumns.indexOf(userRoleProperty.friendly_name) - ]; + const createFromValue = (value: string) => new ContactPropertyValue(place, userRoleProperty, 'user_', value); + lookupPropertyAndCreateValue(place.userRoleProperties, userRoleProperty, createFromValue); } places.push(place); diff --git a/src/services/place.ts b/src/services/place.ts index b4de42f2..ebf9d1be 100644 --- a/src/services/place.ts +++ b/src/services/place.ts @@ -1,13 +1,19 @@ -import _ from 'lodash'; import Contact from './contact'; import { v4 as uuidv4 } from 'uuid'; import { Config, ContactProperty, ContactType } from '../config'; -import { PlacePayload, RemotePlace } from '../lib/cht-api'; -import { Validation } from '../lib/validation'; +import { IPropertyValue } from '../property-value'; +import { PlacePayload } from '../lib/cht-api'; // can't use package.json because of rootDir in ts import { version as appVersion } from '../package.json'; import RemotePlaceResolver from '../lib/remote-place-resolver'; +import { HierarchyPropertyValue, ContactPropertyValue } from '../property-value'; +import { RemotePlace } from '../lib/remote-place-cache'; +import { NamePropertyValue } from '../property-value/name-property-value'; + +export type FormattedPropertyCollection = { + [key: string]: IPropertyValue; +}; export type UserCreationDetails = { username?: string; @@ -36,20 +42,9 @@ export default class Place { public readonly creationDetails : UserCreationDetails = {}; public readonly resolvedHierarchy: (RemotePlace | undefined)[]; - public properties: { - name?: string; - [key: string]: any; - }; - - public hierarchyProperties: { - PARENT?: string; - replacement?: string; - [key: string]: any; - }; - - public userRoleProperties: { - [key: string]: any; - }; + public properties: FormattedPropertyCollection; + public hierarchyProperties: FormattedPropertyCollection; + public userRoleProperties: FormattedPropertyCollection; public state : PlaceUploadState; @@ -72,40 +67,43 @@ export default class Place { FormData for a place has the expected format `place_${property_name}`. */ public setPropertiesFromFormData(formData: any, hierarchyPrefix: string): void { - const getPropertySetWithPrefix = (expectedProperties: ContactProperty[], prefix: string): any => { - const propertiesInDataFormat = expectedProperties.map(p => prefix + p.property_name); - const relevantData = _.pick(formData, propertiesInDataFormat); - return Object.keys(relevantData).reduce((agg, key) => { - const keyWithoutPrefix = key.substring(prefix.length); - return { ...agg, [keyWithoutPrefix]: relevantData[key] }; - }, {}); + const getPropertySetWithPrefix = (expectedProperties: ContactProperty[], prefix: string): FormattedPropertyCollection => { + const result: FormattedPropertyCollection = {}; + for (const property of expectedProperties) { + const dataFormat = prefix + property.property_name; + result[property.property_name] = new ContactPropertyValue(this, property, prefix, formData[dataFormat]); + } + return result; }; + for (const hierarchyLevel of Config.getHierarchyWithReplacement(this.type)) { + const propertyName = hierarchyLevel.property_name; + const hierarchyValue = formData[`${hierarchyPrefix}${propertyName}`] ?? ''; + + // validation of hierachies requires RemotePlaceResolver to do its thing + // at this point; these may report errors but that's ok as long as hierarchy properties are revalidated later + this.hierarchyProperties[propertyName] = new HierarchyPropertyValue(this, hierarchyLevel, hierarchyPrefix, hierarchyValue); + } + + // place properties must be set after hierarchy constraints since validation logic is dependent on isReplacement this.properties = { ...this.properties, ...getPropertySetWithPrefix(this.type.place_properties, PLACE_PREFIX), }; + this.contact.properties = { ...this.contact.properties, ...getPropertySetWithPrefix(this.type.contact_properties, CONTACT_PREFIX), }; - for (const hierarchyLevel of Config.getHierarchyWithReplacement(this.type)) { - const propertyName = hierarchyLevel.property_name; - this.hierarchyProperties[propertyName] = formData[`${hierarchyPrefix}${propertyName}`] ?? ''; - } - if (Config.hasMultipleRoles(this.type)) { const userRoleConfig = Config.getUserRoleConfig(this.type); const propertyName = userRoleConfig.property_name; const roleFormData = formData[`${USER_PREFIX}${propertyName}`]; // When multiple are selected, the form data is an array - if (Array.isArray(roleFormData)) { - this.userRoleProperties[propertyName] = roleFormData.join(' '); - } else { - this.userRoleProperties[propertyName] = roleFormData; - } + const userRoleValue = Array.isArray(roleFormData) ? roleFormData.join(' ') : roleFormData; + this.userRoleProperties[propertyName] = new ContactPropertyValue(this, userRoleConfig, USER_PREFIX, userRoleValue); } } @@ -115,11 +113,11 @@ export default class Place { * To keep views simple and provide default values when editing, we can express a form in its form data */ public asFormData(hierarchyPrefix: string): any { - const addPrefixToPropertySet = (properties: any, prefix: string): any => { + const addPrefixToPropertySet = (properties: FormattedPropertyCollection, prefix: string): any => { const result: any = {}; for (const key of Object.keys(properties)) { const keyWithPrefix: string = prefix + key; - result[keyWithPrefix] = properties[key]; + result[keyWithPrefix] = properties[key].original; } return result; @@ -138,16 +136,12 @@ export default class Place { tool: `cht-user-management-${appVersion}`, username: creator, created_time: Date.now(), - replacement: this.resolvedHierarchy[0], + replacement: this.resolvedHierarchy[0]?.name.formatted, }; - const filteredProperties = (properties: any) => { - if (!this.isReplacement) { - return properties; - } - + const filteredProperties = (properties: FormattedPropertyCollection) => { return Object.keys(properties).reduce((agg: any, key: string) => { - const value = properties[key]; + const value = properties[key]?.formatted; if (value !== undefined && value !== '') { agg[key] = value; } @@ -183,11 +177,6 @@ export default class Place { } public asRemotePlace() : RemotePlace { - const isHierarchyValid = !this.resolvedHierarchy.find(h => h?.type === 'invalid'); - if (!isHierarchyValid) { - throw Error('Cannot call asRemotePlace on place with invalid hierarchy'); - } - let lastKnownHierarchy = this.resolvedHierarchy.find(h => h) || RemotePlaceResolver.NoResult; let lastKnownIndex = 0; @@ -203,27 +192,42 @@ export default class Place { } } + const nameProperty = Config.getPropertyWithName(this.type.place_properties, 'name'); return { id: this.id, - name: this.name, + name: new NamePropertyValue(this.name, nameProperty), type: this.isCreated ? 'remote' : 'local', lineage, }; } public validate(): void { - Validation.format(this); - - const errors = Validation.getValidationErrors(this); + const validateCollection = (collection: FormattedPropertyCollection) => Object.values(collection).forEach(prop => prop.validate()); + // hierarchy properties need to revalidation after resolution + validateCollection(this.hierarchyProperties); + // contact properties need to be revalidated after generation + validateCollection(this.properties); + validateCollection(this.contact.properties); + validateCollection(this.userRoleProperties); + + const extractErrorsFromCollection = (properties: FormattedPropertyCollection) => Object.values(properties).filter(prop => prop.validationError); + const propertiesWithErrors: IPropertyValue[] = [ + ...extractErrorsFromCollection(this.properties), + ...extractErrorsFromCollection(this.contact.properties), + ...extractErrorsFromCollection(this.userRoleProperties), + ...extractErrorsFromCollection(this.hierarchyProperties), + ]; + this.validationErrors = {}; - for (const error of errors) { - this.validationErrors[error.property_name] = error.description; + for (const property of propertiesWithErrors) { + this.validationErrors[property.propertyNameWithPrefix] = property.validationError as string; } } public generateUsername(): string { const propertySource = this.type.username_from_place ? this.properties : this.contact.properties; - let username = propertySource.name || this.hierarchyProperties.replacement; // if name is not present, it must be a replacement + // if name is not present, it must be a replacement + let username = propertySource.name?.formatted || this.hierarchyProperties.replacement?.formatted; username = username ?.replace(/[ ]/g, '_') ?.replace(/[^a-zA-Z0-9_]/g, '') @@ -248,7 +252,7 @@ export default class Place { throw Error(`Place role data is required when multiple roles are available.`); } - return roles.split(' ').map((role: string) => role.trim()).filter(Boolean); + return roles.formatted.split(' ').map((role: string) => role.trim()).filter(Boolean); } public get hasValidationErrors() : boolean { @@ -261,11 +265,11 @@ export default class Place { public get name() : string { const nameProperty = Config.getPropertyWithName(this.type.place_properties, 'name'); - return this.properties[nameProperty.property_name]; + return this.properties[nameProperty.property_name]?.formatted; } public get isReplacement(): boolean { - return !!this.hierarchyProperties.replacement; + return !!this.hierarchyProperties.replacement?.original; } public get isCreated(): boolean { diff --git a/src/services/upload-manager.ts b/src/services/upload-manager.ts index 01c760ed..50c5a4ba 100644 --- a/src/services/upload-manager.ts +++ b/src/services/upload-manager.ts @@ -1,7 +1,7 @@ import EventEmitter from 'events'; import * as RetryLogic from '../lib/retry-logic'; -import { ChtApi, PlacePayload } from '../lib/cht-api'; +import { ChtApi, CreatedPlaceResult, PlacePayload } from '../lib/cht-api'; import { Config } from '../config'; import Place, { PlaceUploadState } from './place'; import RemotePlaceCache from '../lib/remote-place-cache'; @@ -14,8 +14,7 @@ const UPLOAD_BATCH_SIZE = 15; export interface Uploader { handleContact (payload: PlacePayload): Promise; - handlePlacePayload (place: Place, payload: PlacePayload) : Promise; - linkContactAndPlace (place: Place, placeId: string): Promise; + handlePlacePayload (place: Place, payload: PlacePayload) : Promise; } export class UploadManager extends EventEmitter { @@ -43,7 +42,7 @@ export class UploadManager extends EventEmitter { try { const uploader: Uploader = pickUploader(place, chtApi); const payload = place.asChtPayload(chtApi.chtSession.username); - await Config.mutate(payload, chtApi, !!place.properties.replacement); + await Config.mutate(payload, chtApi, place.isReplacement); if (!place.creationDetails.contactId) { const contactId = await uploader.handleContact(payload); @@ -51,13 +50,11 @@ export class UploadManager extends EventEmitter { } if (!place.creationDetails.placeId) { - const placeId = await uploader.handlePlacePayload(place, payload); - place.creationDetails.placeId = placeId; + const placeResult = await uploader.handlePlacePayload(place, payload); + place.creationDetails.placeId = placeResult.placeId; + place.creationDetails.contactId ||= placeResult.contactId; } - const createdPlaceId = place.creationDetails.placeId; // closure required for typescript - await RetryLogic.retryOnUpdateConflict(() => uploader.linkContactAndPlace(place, createdPlaceId)); - if (!place.creationDetails.contactId) { throw Error('creationDetails.contactId not set'); } @@ -69,7 +66,7 @@ export class UploadManager extends EventEmitter { place.creationDetails.password = password; } - await RemotePlaceCache.add(place, chtApi); + RemotePlaceCache.add(place, chtApi); delete place.uploadError; console.log(`successfully created ${JSON.stringify(place.creationDetails)}`); @@ -110,7 +107,7 @@ function getErrorDetails(err: any) { } function pickUploader(place: Place, chtApi: ChtApi): Uploader { - if (!place.hierarchyProperties.replacement) { + if (!place.hierarchyProperties.replacement.original) { return new UploadNewPlace(chtApi); } diff --git a/src/services/upload.deactivate.ts b/src/services/upload.deactivate.ts index 64bbc11f..74dc98c5 100644 --- a/src/services/upload.deactivate.ts +++ b/src/services/upload.deactivate.ts @@ -1,4 +1,5 @@ -import { ChtApi, PlacePayload } from '../lib/cht-api'; +import { ChtApi, CreatedPlaceResult, PlacePayload } from '../lib/cht-api'; +import { DisableUsers } from '../lib/disable-users'; import Place from './place'; import { retryOnUpdateConflict } from '../lib/retry-logic'; import { Uploader } from './upload-manager'; @@ -14,7 +15,7 @@ export class UploadReplacementWithDeactivation implements Uploader { return await this.chtApi.createContact(payload); }; - handlePlacePayload = async (place: Place, payload: PlacePayload): Promise => { + handlePlacePayload = async (place: Place, payload: PlacePayload): Promise => { const contactId = place.creationDetails?.contactId; const placeId = place.resolvedHierarchy[0]?.id; @@ -23,12 +24,10 @@ export class UploadReplacementWithDeactivation implements Uploader { } const updatedPlaceDoc = await retryOnUpdateConflict(() => this.chtApi.updatePlace(payload, contactId)); - await this.chtApi.deactivateUsersWithPlace(placeId); - return updatedPlaceDoc._id; - }; - - linkContactAndPlace = async (place: Place, placeId: string): Promise => { - const contactId = await this.chtApi.updateContactParent(placeId); - place.creationDetails.contactId = contactId; + await DisableUsers.deactivateUsersAt(placeId, this.chtApi); + return { + placeId: updatedPlaceDoc._id, + contactId, + }; }; } diff --git a/src/services/upload.new.ts b/src/services/upload.new.ts index 95b60f0a..98630473 100644 --- a/src/services/upload.new.ts +++ b/src/services/upload.new.ts @@ -1,4 +1,4 @@ -import { ChtApi, PlacePayload } from '../lib/cht-api'; +import { ChtApi, CreatedPlaceResult, PlacePayload } from '../lib/cht-api'; import Place from './place'; import { Uploader } from './upload-manager'; @@ -13,18 +13,7 @@ export class UploadNewPlace implements Uploader { return; }; - handlePlacePayload = async (place: Place, payload: PlacePayload): Promise => { + handlePlacePayload = async (place: Place, payload: PlacePayload): Promise => { return await this.chtApi.createPlace(payload); }; - - // we don't get a contact id when we create a place with a contact defined - // https://github.com/medic/cht-core/issues/8674 - linkContactAndPlace = async (place: Place, placeId: string): Promise => { - if (place.creationDetails?.contactId) { - return; - } - - const contactId = await this.chtApi.updateContactParent(placeId); - place.creationDetails.contactId = contactId; - }; } diff --git a/src/services/upload.replacement.ts b/src/services/upload.replacement.ts index 05bcc976..5fa96b5f 100644 --- a/src/services/upload.replacement.ts +++ b/src/services/upload.replacement.ts @@ -1,4 +1,5 @@ -import { ChtApi, PlacePayload } from '../lib/cht-api'; +import { ChtApi, CreatedPlaceResult, PlacePayload } from '../lib/cht-api'; +import { DisableUsers } from '../lib/disable-users'; import Place from './place'; import { retryOnUpdateConflict } from '../lib/retry-logic'; import { Uploader } from './upload-manager'; @@ -14,7 +15,7 @@ export class UploadReplacementWithDeletion implements Uploader { return await this.chtApi.createContact(payload); }; - handlePlacePayload = async (place: Place, payload: PlacePayload): Promise => { + handlePlacePayload = async (place: Place, payload: PlacePayload): Promise => { const contactId = place.creationDetails?.contactId; const placeId = place.resolvedHierarchy[0]?.id; @@ -28,12 +29,7 @@ export class UploadReplacementWithDeletion implements Uploader { await retryOnUpdateConflict(() => this.chtApi.deleteDoc(previousPrimaryContact)); } - await this.chtApi.disableUsersWithPlace(placeId); - return updatedPlaceDoc._id; - }; - - linkContactAndPlace = async (place: Place, placeId: string): Promise => { - const contactId = await this.chtApi.updateContactParent(placeId); - place.creationDetails.contactId = contactId; + await DisableUsers.disableUsersAt(placeId, this.chtApi); + return { placeId, contactId }; }; } diff --git a/src/services/user-payload.ts b/src/services/user-payload.ts index fb525cdf..19a73163 100644 --- a/src/services/user-payload.ts +++ b/src/services/user-payload.ts @@ -17,7 +17,7 @@ export class UserPayload { this.place = placeId; this.contact = contactId; this.fullname = place.contact.name; - this.phone = place.contact.properties.phone; // best guess + this.phone = place.contact.properties.phone?.formatted; // best guess } public regeneratePassword(): void { diff --git a/src/validation/index.ts b/src/validation/index.ts new file mode 100644 index 00000000..69d0c658 --- /dev/null +++ b/src/validation/index.ts @@ -0,0 +1,15 @@ +import { ContactProperty } from '../config'; +import { Validation } from './validation'; + +export type ValidationError = { + property_name: string; + description: string; +}; + +export interface IValidator { + isValid(input: string, property? : ContactProperty) : boolean | string; + format(input : string, property? : ContactProperty) : string; + get defaultError(): string; +} + +export default Validation; diff --git a/src/validation/validation.ts b/src/validation/validation.ts new file mode 100644 index 00000000..ccea98a8 --- /dev/null +++ b/src/validation/validation.ts @@ -0,0 +1,145 @@ +import _ from 'lodash'; +import { Config, ContactProperty, HierarchyConstraint } from '../config'; +import { IValidator } from '.'; +import Place from '../services/place'; +import RemotePlaceResolver from '../lib/remote-place-resolver'; + +import ValidatorDateOfBirth from './validator-dob'; +import ValidatorGenerated from './validator-generated'; +import ValidatorName from './validator-name'; +import ValidatorPhone from './validator-phone'; +import ValidatorRegex from './validator-regex'; +import ValidatorSelectMultiple from './validator-select-multiple'; +import ValidatorSelectOne from './validator-select-one'; +import ValidatorSkip from './validator-skip'; +import ValidatorString from './validator-string'; +import { RemotePlace } from '../lib/remote-place-cache'; + +type ValidatorMap = { + [key: string]: IValidator; +}; + +const TypeValidatorMap: ValidatorMap = { + dob: new ValidatorDateOfBirth(), + generated: new ValidatorGenerated(), + name: new ValidatorName(), + none: new ValidatorSkip(), + phone: new ValidatorPhone(), + regex: new ValidatorRegex(), + string: new ValidatorString(), + select_one: new ValidatorSelectOne(), + select_multiple: new ValidatorSelectMultiple(), +}; + +export class Validation { + public static validateProperty( + value: string, + property : ContactProperty, + requiredProperties: ContactProperty[] + ) : string | undefined { + const isRequired = requiredProperties.some((prop) => _.isEqual(prop, property)); + if (!value && isRequired) { + return 'Is Required'; + } + + if (value || isRequired) { + const isValid = Validation.isValid(property, value); + if (isValid === false || typeof isValid === 'string') { + return isValid === false ? 'Value is invalid' : isValid as string; + } + } + } + + public static formatDuringInitialization(property: ContactProperty, value: string): string { + const validator = this.getValidator(property); + if (!(validator instanceof ValidatorGenerated) && value) { + return validator.format(value, property); + } + + return value; + } + + public static generateAfterInitialization(place: Place, property: ContactProperty): string | undefined { + const validator = this.getValidator(property); + if (validator instanceof ValidatorGenerated) { + return validator.format(place, property); + } + + return; + } + + public static validateHierarchyLevel(place: Place, hierarchyLevel: HierarchyConstraint): string | undefined { + const hierarchy = Config.getHierarchyWithReplacement(place.type); + const data = place.hierarchyProperties[hierarchyLevel.property_name]; + + if (hierarchyLevel.level !== 0 || data?.formatted) { + const isExpected = hierarchyLevel.required; + const resolution = place.resolvedHierarchy[hierarchyLevel.level]; + const isValid = resolution?.type !== 'invalid' && ( + !isExpected || + resolution?.type === 'remote' || + resolution?.type === 'local' + ); + if (!isValid) { + const index = hierarchy.findIndex(h => h.level === hierarchyLevel.level); + if (index < 0) { + throw Error('Failed to find hierachy level'); + } + + const levelUp = hierarchy[index + 1]?.property_name; + const error = this.describeInvalidRemotePlace( + resolution, + hierarchyLevel.contact_type, + data?.original, + place.hierarchyProperties[levelUp]?.original + ); + + return error; + } + } + } + + public static getKnownContactPropertyTypes(): string[] { + return Object.keys(TypeValidatorMap); + } + + private static isValid(property : ContactProperty, value: string) : boolean | string { + const validator = this.getValidator(property); + try { + const isValid = validator.isValid(value, property); + return isValid === false ? property.errorDescription || validator.defaultError : isValid; + } catch (e) { + const error = `Error in isValid for '${property.type}': ${e}`; + console.log(error); + return error; + } + } + + private static getValidator(property: ContactProperty) : IValidator { + const validator = TypeValidatorMap[property.type]; + if (!validator) { + throw Error(`unvalidatable type: '${property.friendly_name}' has type '${property.type}'`); + } + + return validator; + } + + private static describeInvalidRemotePlace( + remotePlace: RemotePlace | undefined, + friendlyType: string, + searchStr?: string, + requiredParent?: string + ): string { + if (!searchStr) { + return `Cannot find ${friendlyType} because the search string is empty`; + } + + const requiredParentSuffix = requiredParent ? ` under '${requiredParent}'` : ''; + if (RemotePlaceResolver.Multiple.id === remotePlace?.id) { + const ambiguityDetails = JSON.stringify(remotePlace.ambiguities?.map(a => a.id)); + return `Found multiple ${friendlyType}s matching '${searchStr}'${requiredParentSuffix} ${ambiguityDetails}`; + } + + return `Cannot find '${friendlyType}' matching '${searchStr}'${requiredParentSuffix}`; + } +} diff --git a/src/lib/validator-dob.ts b/src/validation/validator-dob.ts similarity index 96% rename from src/lib/validator-dob.ts rename to src/validation/validator-dob.ts index 48a4cbf4..278c9c05 100644 --- a/src/lib/validator-dob.ts +++ b/src/validation/validator-dob.ts @@ -1,5 +1,5 @@ import { DateTime } from 'luxon'; -import { IValidator } from './validation'; +import { IValidator } from '.'; export default class ValidatorDateOfBirth implements IValidator { isValid(input: string) : boolean { diff --git a/src/lib/validator-generated.ts b/src/validation/validator-generated.ts similarity index 71% rename from src/lib/validator-generated.ts rename to src/validation/validator-generated.ts index 32663680..b70bd83b 100644 --- a/src/lib/validator-generated.ts +++ b/src/validation/validator-generated.ts @@ -1,7 +1,7 @@ import { Liquid } from 'liquidjs'; -import { IValidator } from './validation'; +import { IValidator } from '.'; import { ContactProperty } from '../config'; -import Place from '../services/place'; +import Place, { FormattedPropertyCollection } from '../services/place'; const engine = new Liquid({ strictVariables: false, @@ -25,10 +25,17 @@ export default class ValidatorGenerated implements IValidator { } const place:Place = input; + const mapToFormatted = (collection: FormattedPropertyCollection) => { + return Object.keys(collection).reduce((agg: any, key: string) => { + agg[key] = collection[key].formatted; + return agg; + }, {}); + }; + const generationScope: GeneratorScope = { - place: place.properties, - contact: place.contact.properties, - lineage: place.hierarchyProperties, + place: mapToFormatted(place.properties), + contact: mapToFormatted(place.contact.properties), + lineage: mapToFormatted(place.hierarchyProperties), }; const parameter = this.getParameter(property); diff --git a/src/lib/validator-name.ts b/src/validation/validator-name.ts similarity index 87% rename from src/lib/validator-name.ts rename to src/validation/validator-name.ts index 5293a8d8..b518d197 100644 --- a/src/lib/validator-name.ts +++ b/src/validation/validator-name.ts @@ -1,5 +1,5 @@ import { ContactProperty } from '../config'; -import { IValidator } from './validation'; +import { IValidator } from '.'; import ValidatorString from './validator-string'; export default class ValidatorName implements IValidator { @@ -15,20 +15,20 @@ export default class ValidatorName implements IValidator { format(input : string, property : ContactProperty) : string { input = input.replace(/\./g, ' '); input = input.replace(/\//g, ' / '); - let toAlter = input; + let toFormat = input; if (property.parameter) { if (!Array.isArray(property.parameter)) { throw Error(`property with type "name": parameter should be an array`); } - toAlter = property.parameter.reduce((agg, toRemove) => { + toFormat = property.parameter.reduce((agg, toRemove) => { const regex = new RegExp(toRemove, 'ig'); return agg.replace(regex, ''); - }, toAlter); + }, toFormat); } const validatorStr = new ValidatorString(); - return this.titleCase(validatorStr.format(toAlter)); + return this.titleCase(validatorStr.format(toFormat)); } get defaultError(): string { diff --git a/src/lib/validator-phone.ts b/src/validation/validator-phone.ts similarity index 96% rename from src/lib/validator-phone.ts rename to src/validation/validator-phone.ts index 40e2896a..a0a9eb1c 100644 --- a/src/lib/validator-phone.ts +++ b/src/validation/validator-phone.ts @@ -1,7 +1,7 @@ import { CountryCode, parsePhoneNumber, isValidNumberForRegion } from 'libphonenumber-js'; import { ContactProperty } from '../config'; -import { IValidator } from './validation'; +import { IValidator } from '.'; export default class ValidatorPhone implements IValidator { isValid(input: string, property : ContactProperty) : boolean | string { diff --git a/src/lib/validator-regex.ts b/src/validation/validator-regex.ts similarity index 87% rename from src/lib/validator-regex.ts rename to src/validation/validator-regex.ts index be49e29e..4c8a0ee5 100644 --- a/src/lib/validator-regex.ts +++ b/src/validation/validator-regex.ts @@ -1,5 +1,5 @@ import { ContactProperty } from '../config'; -import { IValidator } from './validation'; +import { IValidator } from '.'; import ValidatorString from './validator-string'; @@ -15,8 +15,8 @@ export default class ValidatorRegex implements IValidator { const regex = new RegExp(property.parameter.toString()); const validatorStr = new ValidatorString(); - const altered = validatorStr.format(input); - const match = altered.match(regex); + const formatted = validatorStr.format(input); + const match = formatted.match(regex); return !!match && match.length > 0; } diff --git a/src/lib/validator-select-multiple.ts b/src/validation/validator-select-multiple.ts similarity index 97% rename from src/lib/validator-select-multiple.ts rename to src/validation/validator-select-multiple.ts index a423c240..aea069d8 100644 --- a/src/lib/validator-select-multiple.ts +++ b/src/validation/validator-select-multiple.ts @@ -1,5 +1,5 @@ import {ContactProperty} from '../config'; -import {IValidator} from './validation'; +import { IValidator } from '.'; import ValidatorString from './validator-string'; import ValidatorSelectOne from './validator-select-one'; diff --git a/src/lib/validator-select-one.ts b/src/validation/validator-select-one.ts similarity index 95% rename from src/lib/validator-select-one.ts rename to src/validation/validator-select-one.ts index 69d943d9..55b1aa3b 100644 --- a/src/lib/validator-select-one.ts +++ b/src/validation/validator-select-one.ts @@ -1,5 +1,5 @@ import {ContactProperty} from '../config'; -import {IValidator} from './validation'; +import { IValidator } from '.'; import ValidatorString from './validator-string'; export default class ValidatorSelectOne implements IValidator { diff --git a/src/lib/validator-skip.ts b/src/validation/validator-skip.ts similarity index 84% rename from src/lib/validator-skip.ts rename to src/validation/validator-skip.ts index eee1b311..f309f50c 100644 --- a/src/lib/validator-skip.ts +++ b/src/validation/validator-skip.ts @@ -1,4 +1,4 @@ -import { IValidator } from './validation'; +import { IValidator } from '.'; export default class ValidatorSkip implements IValidator { isValid() : boolean | string { diff --git a/src/lib/validator-string.ts b/src/validation/validator-string.ts similarity index 89% rename from src/lib/validator-string.ts rename to src/validation/validator-string.ts index 7e4dd251..60f5d773 100644 --- a/src/lib/validator-string.ts +++ b/src/validation/validator-string.ts @@ -1,4 +1,4 @@ -import { IValidator } from './validation'; +import { IValidator } from '.'; export default class ValidatorString implements IValidator { isValid(input: string) : boolean | string { diff --git a/src/worker/cht-conf-worker.ts b/src/worker/cht-conf-worker.ts new file mode 100644 index 00000000..23f2b9e5 --- /dev/null +++ b/src/worker/cht-conf-worker.ts @@ -0,0 +1,228 @@ +import axios from 'axios'; +import { spawn } from 'child_process'; +import { Worker, Job, DelayedError, ConnectionOptions, MinimalJob } from 'bullmq'; +import { DateTime } from 'luxon'; + +import Auth from '../lib/authentication'; +import { HierarchyAction } from '../lib/manage-hierarchy'; + +export interface ChtConfJobData { + sourceId: string; + destinationId: string; + action: HierarchyAction; + sessionToken: string; + instanceUrl: string; +} + +export interface PostponeReason { + reason: string; +} + +export type JobResult = { success: boolean; message: string }; + +export class ChtConfWorker { + private static readonly DELAY_IN_MILLIS = 4 * 60 * 60 * 1000; // 4 hours + private static readonly MAX_TIMEOUT_IN_MILLIS = 4 * 60 * 60 * 1000; // 4 hours + private static readonly MAX_CONCURRENCY = 1; // Limit concurrency to 1 job at a time + private static readonly MAX_SENTINEL_BACKLOG = 7000; // ensure we don't take down the server + static worker: Worker; + + public static processQueue(queueName: string, connection: ConnectionOptions) { + this.worker = new Worker( + queueName, + this.handleJob, + { + connection, + concurrency: this.MAX_CONCURRENCY, + settings: { + backoffStrategy: this.handleRetryBackoff, + } + } + ); + } + + public static async close() { + const client = await this.worker?.client; + if (client?.status !== 'end') { + await this.worker?.close(true); + } + } + + private static handleJob = async (job: Job, processingToken?: string): Promise => { + const jobData: ChtConfJobData = job.data; + + // Ensure server availability + const postponseReason = await this.shouldPostpone(jobData); + if (postponseReason) { + await this.postpone(job, postponseReason.reason, processingToken); + throw new DelayedError(); + } + + const result = await this.processChtConfJob(job); + if (!result.success) { + const errorMessage = `Job ${job.id} failed with the following error: ${result.message}`; + console.error(errorMessage); + this.logWithTimestamp(job, errorMessage); + throw new Error(errorMessage); + } + + console.log(`Job completed successfully: ${job.id}`); + return true; + }; + + private static handleRetryBackoff = ( + attemptsMade: number, type: string | undefined, err: Error | undefined, job: MinimalJob | undefined + ): number => { + const {retryTimeFormatted} = this.computeRetryTime(); + + const fullMessage = `Job ${job?.id} will retry at ${retryTimeFormatted}.\ + Attempt Number: ${attemptsMade + 1}. Due to failure: ${type}: ${err?.message}`; + + this.logWithTimestamp(job, fullMessage); + return this.DELAY_IN_MILLIS; + }; + + private static async shouldPostpone(jobData: ChtConfJobData): Promise { + try { + const { instanceUrl } = jobData; + const response = await ChtConfWorker.fetchMonitoringApi(instanceUrl); + const sentinelBacklog = response.data.sentinel?.backlog; + console.log(`Sentinel backlog at ${sentinelBacklog} of ${this.MAX_SENTINEL_BACKLOG}`); + + return sentinelBacklog > this.MAX_SENTINEL_BACKLOG + ? { reason: `Sentinel backlog too high at ${sentinelBacklog}` } + : undefined; + } catch (err: any) { + const errorMessage = err.response?.data?.error?.message || err.response?.error || err?.message; + console.error('Error fetching monitoring data:', errorMessage); + + // Handle server unavailability (HTTP 500 errors) + if (err.response?.status === 500) { + console.log('Server error encountered, postponing job...'); + return { reason: `Server error encountered: ${errorMessage}` }; + } + return undefined; + } + } + + private static fetchMonitoringApi(instanceUrl: string) { + return axios.get(`${instanceUrl}/api/v2/monitoring`); + } + + private static async processChtConfJob(job: Job): Promise { + try { + const jobData: ChtConfJobData = job.data; + + if (!jobData.sessionToken) { + return { success: false, message: 'Missing session token' }; + } + + const decodedToken = Auth.createWorkerSession(jobData.sessionToken); + const token = decodedToken.sessionToken.replace('AuthSession=', ''); + + const command = 'cht'; + const args = this.buildCommandArgs(jobData, token); + + this.logCommand(command, args); + await this.executeCommand(command, args, job); + + return { success: true, message: `Job processing completed.` }; + } catch (error) { + return { success: false, message: error as string }; + } + } + + private static buildCommandArgs(data: ChtConfJobData, decodedToken: string): string[] { + return [ + `--url=${data.instanceUrl}`, + `--session-token=${decodedToken}`, + '--force', + getConfActionName(), + 'upload-docs', + '--', + ...getActionArgs(), + ]; + + function getConfActionName() { + switch (data.action) { + case 'delete': + return 'delete-contacts'; + case 'merge': + return 'merge-contacts'; + default: + return 'move-contacts'; + } + } + + function getActionArgs() { + switch (data.action) { + case 'delete': + return [`--contacts=${data.sourceId}`, '--disable-users']; + case 'merge': + return [`--sources=${data.sourceId}`, `--destination=${data.destinationId}`, '--merge-primary-contacts', '--disable-users']; + default: + return [`--contacts=${data.sourceId}`, `--parent=${data.destinationId}`]; + } + } + } + + private static logCommand(command: string, args: string[]): void { + const maskedArgs = args.map(arg => arg.startsWith('--session-token=') ? '--session-token=********' : arg); + console.log('Executing command:', `${command} ${maskedArgs.join(' ')}`); + } + + private static async executeCommand(command: string, args: string[], job: Job): Promise { + return new Promise((resolve, reject) => { + const chtProcess = spawn(command, args); + let lastOutput = ''; + + const timeout = setTimeout(() => { + chtProcess.kill(); + reject(new Error('cht-conf timed out')); + }, this.MAX_TIMEOUT_IN_MILLIS); + + chtProcess.stdout.on('data', data => { + lastOutput = data.toString(); + this.logWithTimestamp(job, `cht-conf output: ${data.toString()}`); + }); + + chtProcess.stderr.on('data', error => { + lastOutput = error.toString(); + this.logWithTimestamp(job, `cht-conf error: ${error.toString()}`); + }); + + chtProcess.on('close', code => { + clearTimeout(timeout); + if (code === 0) { + resolve(); + } + reject(new Error(`CHT command exited with code ${code}. Last output: ${lastOutput}`)); + }); + + chtProcess.on('error', error => { + clearTimeout(timeout); + this.logWithTimestamp(job, `cht-conf process error: ${error.toString()}`); + reject(error); + }); + }); + } + + private static async postpone(job: Job, retryMessage: string, processingToken?: string): Promise { + const { retryTimeFormatted, retryTime } = this.computeRetryTime(); + this.logWithTimestamp(job, `Job ${job.id} postponed until ${retryTimeFormatted}. Reason: ${retryMessage}.`); + await job.moveToDelayed(retryTime.toMillis(), processingToken); + } + + private static computeRetryTime(): { retryTime: DateTime; retryTimeFormatted: string } { + const retryTime = DateTime.now().plus({ milliseconds: this.DELAY_IN_MILLIS }); + const retryTimeFormatted = retryTime.toLocaleString(DateTime.TIME_SIMPLE); + return { retryTime, retryTimeFormatted }; + } + + private static logWithTimestamp(job: Job|MinimalJob|undefined, message: string): void { + const timestamp = DateTime.now().toISO(); + const fullMessage = `[${timestamp}] ${message}`; + job?.log(fullMessage); + console.log(fullMessage); + } +} diff --git a/src/worker/main.ts b/src/worker/main.ts index 10d28fd9..5f31f806 100644 --- a/src/worker/main.ts +++ b/src/worker/main.ts @@ -2,15 +2,15 @@ import { config } from 'dotenv'; config(); -import { MoveContactWorker } from './move-contact-worker'; +import { ChtConfWorker } from './cht-conf-worker'; import { WorkerConfig, checkRedisConnection } from '../config/config-worker'; (async () => { - const { moveContactQueue, redisConnection} = WorkerConfig; + const { chtConfQueueName, redisConnection } = WorkerConfig; await checkRedisConnection(); - MoveContactWorker.processQueue( - moveContactQueue, + ChtConfWorker.processQueue( + chtConfQueueName, redisConnection ); - console.log(`🚀 Move Contact Worker is listening`); + console.log(`🚀 CHT Conf Worker is listening`); })(); diff --git a/src/worker/move-contact-worker.ts b/src/worker/move-contact-worker.ts deleted file mode 100644 index 0b18da1f..00000000 --- a/src/worker/move-contact-worker.ts +++ /dev/null @@ -1,162 +0,0 @@ -import axios from 'axios'; -import { spawn } from 'child_process'; -import { Worker, Job, DelayedError, ConnectionOptions } from 'bullmq'; -import { DateTime } from 'luxon'; - -import Auth from '../lib/authentication'; - -export interface MoveContactData { - parentId: string; - contactId: string; - sessionToken: string; - instanceUrl: string; -} - -export type JobResult = { success: boolean; message: string }; - -export class MoveContactWorker { - private static readonly DELAY_IN_MILLIS = 4 * 60 * 60 * 1000; // 4 hours - private static readonly MAX_TIMEOUT_IN_MILLIS = 4 * 60 * 60 * 1000; // 4 hours - private static readonly MAX_CONCURRENCY = 1; // Limit concurrency to 1 job at a time - private static readonly MAX_SENTINEL_BACKLOG = 7000; // ensure we don't take down the server - static worker: Worker; - - public static processQueue(queueName: string, connection: ConnectionOptions) { - this.worker = new Worker( - queueName, - this.handleJob, - { connection, concurrency: this.MAX_CONCURRENCY } - ); - } - - public static async close() { - const client = await this.worker?.client; - if (client?.status !== 'end') { - await this.worker?.close(true); - } - } - - private static handleJob = async (job: Job, processingToken?: string): Promise => { - const jobData: MoveContactData = job.data; - - // Ensure server availability - if (await this.shouldPostpone(jobData)) { - await this.postpone(job, processingToken); - throw new DelayedError(); - } - - const result = await this.moveContact(jobData); - if (!result.success) { - job.log(`[${new Date().toISOString()}]: ${result.message}`); - const errorMessage = `Job ${job.id} failed with the following error: ${result.message}`; - console.error(errorMessage); - throw new Error(errorMessage); - } - - console.log(`Job completed successfully: ${job.id}`); - return true; - }; - - private static async shouldPostpone(jobData: MoveContactData): Promise { - try { - const { instanceUrl } = jobData; - const response = await axios.get(`${instanceUrl}/api/v2/monitoring`); - const sentinelBacklog = response.data.sentinel?.backlog; - console.log(`Sentinel backlog at ${sentinelBacklog} of ${this.MAX_SENTINEL_BACKLOG}`); - return sentinelBacklog > this.MAX_SENTINEL_BACKLOG; - } catch (err: any) { - const errorMessage = err.response?.data?.error?.message || err.response?.error || err?.message; - console.error('Error fetching monitoring data:', errorMessage); - return true; - } - } - - private static async moveContact(jobData: MoveContactData): Promise { - try { - const { contactId, parentId, instanceUrl, sessionToken } = jobData; - - if (!sessionToken) { - return { success: false, message: 'Missing session token' }; - } - - const decodedToken = Auth.decodeTokenForWorker(sessionToken); - const token = decodedToken.sessionToken.replace('AuthSession=', ''); - - const command = 'cht'; - const args = this.buildCommandArgs(instanceUrl, token, contactId, parentId); - - this.logCommand(command, args); - await this.executeCommand(command, args); - - return { success: true, message: `Job processing completed.` }; - } catch (error) { - return { success: false, message: error as string }; - } - } - - private static buildCommandArgs(instanceUrl: string, sessionToken: string, contactId: string, parentId: string): string[] { - return [ - `--url=${instanceUrl}`, - `--session-token=${sessionToken}`, - '--force', - 'move-contacts', - 'upload-docs', - '--', - `--contacts=${contactId}`, - `--parent=${parentId}` - ]; - } - - private static logCommand(command: string, args: string[]): void { - const maskedArgs = args.map(arg => arg.startsWith('--session-token=') ? '--session-token=********' : arg); - console.log('Executing command:', `${command} ${maskedArgs.join(' ')}`); - } - - private static async executeCommand(command: string, args: string[]): Promise { - return new Promise((resolve, reject) => { - const chtProcess = spawn(command, args); - let lastOutput = ''; - - const timeout = setTimeout(() => { - chtProcess.kill(); - reject(new Error('cht-conf timed out')); - }, this.MAX_TIMEOUT_IN_MILLIS); - - chtProcess.stdout.on('data', data => { - console.log(`cht-conf: ${data}`); - lastOutput = data.toString(); - }); - - chtProcess.stderr.on('data', error => { - console.error(`cht-conf error: ${error}`); - }); - - chtProcess.on('close', code => { - clearTimeout(timeout); - if (code === 0) { - resolve(); - } - reject(new Error(`Move contact command exited with code ${code}. Last output: ${lastOutput}`)); - }); - - chtProcess.on('error', error => { - clearTimeout(timeout); - console.log(error); - reject(error); - }); - }); - } - - private static async postpone(job: Job, processingToken?: string): Promise { - // Calculate the retry time using luxon - const retryTime = DateTime.now().plus({ milliseconds: this.DELAY_IN_MILLIS }); - const retryTimeFormatted = retryTime.toLocaleString(DateTime.TIME_SIMPLE); - - // Delayed this job by DELAY_IN_MILLIS, using the current worker processing token - await job.moveToDelayed(retryTime.toMillis(), processingToken); - - const retryMessage = `Job ${job.id} postponed until ${retryTimeFormatted}. Reason was sentinel backlog.`; - job.log(`[${new Date().toISOString()}]: ${retryMessage}`); - console.log(retryMessage); - } -} diff --git a/test/config.spec.ts b/test/config.spec.ts new file mode 100644 index 00000000..81a8ba35 --- /dev/null +++ b/test/config.spec.ts @@ -0,0 +1,62 @@ +import { expect } from 'chai'; + +import { Config, PartnerConfig } from '../src/config'; +import { CONFIG_MAP } from '../src/config/config-factory'; +import { mockSimpleContactType } from './mocks'; + +const mockPartnerConfig = (): PartnerConfig => ({ + config: { + domains: [], + contact_types: [mockSimpleContactType('string')], + logoBase64: '', + } +}); + +describe('config', () => { + it('mock partner config is valid', () => { + const mockConfig = mockPartnerConfig(); + Config.assertValid(mockConfig); + }); + + it('assert on unknown property type', () => { + const mockConfig = mockPartnerConfig(); + mockConfig.config.contact_types[0].hierarchy[0].type = 'unknown'; + const assertion = () => Config.assertValid(mockConfig); + expect(assertion).to.throw('type "unknown"'); + }); + + it('place name is always required', () => { + const mockConfig = mockPartnerConfig(); + mockConfig.config.contact_types[0].place_properties.shift(); + const assertion = () => Config.assertValid(mockConfig); + expect(assertion).to.throw('"name"'); + }); + + it('contact name is always required', () => { + const mockConfig = mockPartnerConfig(); + mockConfig.config.contact_types[0].contact_properties.shift(); + const assertion = () => Config.assertValid(mockConfig); + expect(assertion).to.throw('"name"'); + }); + + it('#124 - cannot have generated property in hierarchy', () => { + const mockConfig = mockPartnerConfig(); + mockConfig.config.contact_types[0].hierarchy[0].type = 'generated'; + const assertion = () => Config.assertValid(mockConfig); + expect(assertion).to.throw('cannot be of type "generated"'); + }); + + it('#124 - cannot have generated property as replacement_property', () => { + const mockConfig = mockPartnerConfig(); + mockConfig.config.contact_types[0].replacement_property.type = 'generated'; + const assertion = () => Config.assertValid(mockConfig); + expect(assertion).to.throw('cannot be of type "generated"'); + }); + + const configs = Object.entries(CONFIG_MAP); + for (const [configName, partnerConfig] of configs) { + it(`config ${configName} is valid`, () => { + Config.assertValid(partnerConfig); + }); + } +}); diff --git a/test/create-user-managers.spec.ts b/test/create-user-managers.spec.ts index c2a55ede..930ae578 100644 --- a/test/create-user-managers.spec.ts +++ b/test/create-user-managers.spec.ts @@ -6,6 +6,7 @@ import { mockChtSession } from './mocks'; const createUserManagers = rewire('../scripts/create-user-managers/create-user-managers'); import chaiAsPromised from 'chai-as-promised'; +import RemotePlaceCache from '../src/lib/remote-place-cache'; Chai.use(chaiAsPromised); const { expect } = Chai; @@ -18,16 +19,17 @@ const StandardArgv = [ let fakeGetPlacesWithType; describe('scripts/create-user-managers.ts', () => { beforeEach(() => { + RemotePlaceCache.clear(); + const session = mockChtSession('abc'); const mockSession = { - create: sinon.stub().resolves(mockChtSession('abc')), + create: sinon.stub().resolves(session), }; fakeGetPlacesWithType = sinon.stub().resolves([{ - id: 'county_id', + _id: 'county_id', name: 'vihiga', - lineage: [], - type: 'remote', }]); const mockChtApi = class MockChtApi { + public chtSession = session; public getPlacesWithType = fakeGetPlacesWithType; public createContact = sinon.stub().resolves({}); @@ -74,16 +76,12 @@ describe('scripts/create-user-managers.ts', () => { fakeGetPlacesWithType.resolves([ { - id: 'county_id', + _id: 'county_id', name: 'vihiga', - lineage: [], - type: 'remote', }, { - id: 'county_id2', + _id: 'county_id2', name: 'kakamega', - lineage: [], - type: 'remote', } ]); diff --git a/test/integration/move-contact.spec.ts b/test/integration/manage-hierarchy.spec.ts similarity index 81% rename from test/integration/move-contact.spec.ts rename to test/integration/manage-hierarchy.spec.ts index d4b348bb..f7ac0332 100644 --- a/test/integration/move-contact.spec.ts +++ b/test/integration/manage-hierarchy.spec.ts @@ -4,22 +4,23 @@ import chaiAsPromised from 'chai-as-promised'; import { Job} from 'bullmq'; import sinon from 'sinon'; -import MoveLib from '../../src/lib/move'; +import MoveLib from '../../src/lib/manage-hierarchy'; import Auth from '../../src/lib/authentication'; import { Config } from '../../src/config'; import { BullQueue } from '../../src/lib/queues'; import { mockChtApi, mockChtSession } from '../mocks'; -import { MoveContactWorker } from '../../src/worker/move-contact-worker'; +import { ChtConfWorker } from '../../src/worker/cht-conf-worker'; import SessionCache from '../../src/services/session-cache'; const { expect } = chai; chai.use(chaiAsPromised); -describe('integration/move-contact', function () { +describe('integration/manage-hierarchy', function () { const queueName = 'move_contact_queue'; const connection = { host: '127.0.0.1', port: 6363 }; + const defaultJobOptions = { attempts: 3, backoff: { type: 'custom' } }; let sandbox: sinon.SinonSandbox; let addStub: sinon.SinonStub; @@ -32,21 +33,21 @@ describe('integration/move-contact', function () { beforeEach(async () => { sandbox = sinon.createSandbox(); - moveContactQueue = new BullQueue(queueName, connection); + moveContactQueue = new BullQueue(queueName, connection, defaultJobOptions); addStub = sandbox.stub(moveContactQueue, 'add'); - handleJobStub = sandbox.stub(MoveContactWorker as any, 'handleJob'); - shouldPostponeStub = sandbox.stub(MoveContactWorker as any, 'shouldPostpone'); - executeCommandStub = sandbox.stub(MoveContactWorker as any, 'executeCommand'); + handleJobStub = sandbox.stub(ChtConfWorker as any, 'handleJob'); + shouldPostponeStub = sandbox.stub(ChtConfWorker as any, 'shouldPostpone'); + executeCommandStub = sandbox.stub(ChtConfWorker as any, 'executeCommand'); encodeTokenStub = sandbox.stub(Auth, 'encodeTokenForWorker'); - decodeTokenStub = sandbox.stub(Auth, 'decodeTokenForWorker'); + decodeTokenStub = sandbox.stub(Auth, 'createWorkerSession'); - MoveContactWorker.processQueue(queueName, connection); + ChtConfWorker.processQueue(queueName, connection); }); afterEach(async () => { - await MoveContactWorker.close(); + await ChtConfWorker.close(); await moveContactQueue.close(); sandbox.restore(); }); @@ -75,7 +76,7 @@ describe('integration/move-contact', function () { encodeTokenStub.returns('encoded-token'); decodeTokenStub.returns(session); - await MoveLib.move( + await MoveLib.scheduleJob( formData, contactType, sessionCache, chtApi(), moveContactQueue ); @@ -106,7 +107,7 @@ describe('integration/move-contact', function () { encodeTokenStub.returns('encoded-token'); decodeTokenStub.throws(new Error('Missing WORKER_PRIVATE_KEY')); - await MoveLib.move( + await MoveLib.scheduleJob( formData, contactType, sessionCache, chtApi(), moveContactQueue ); @@ -116,7 +117,7 @@ describe('integration/move-contact', function () { await new Promise(resolve => setTimeout(resolve, 1000)); // Check if the job has failed - const job = await moveContactQueue['bullQueue'].getJob(jobId) as Job; + const job = await moveContactQueue['bullQueue'].getJob(jobId) as unknown as Job; expect(await job.getState()).to.equal('failed'); }); }); diff --git a/test/lib/authentication.spec.ts b/test/lib/authentication.spec.ts index 032f5922..a9ab9b5f 100644 --- a/test/lib/authentication.spec.ts +++ b/test/lib/authentication.spec.ts @@ -10,37 +10,37 @@ describe('lib/authentication.ts', () => { it('encode and decode for cookie', () => { const session = mockChtSession(); const encoded = Auth.encodeTokenForCookie(session); - const decoded = Auth.decodeTokenForCookie(encoded); + const decoded = Auth.createCookieSession(encoded); expect(session).excluding('axiosInstance').to.deep.eq(decoded); }); it('encode and decode for workers', () => { const session = mockChtSession(); const encoded = Auth.encodeTokenForWorker(session); - const decoded = Auth.decodeTokenForWorker(encoded); + const decoded = Auth.createWorkerSession(encoded); expect(session).excluding('axiosInstance').to.deep.eq(decoded); }); it('invalid token cannot be decoded for cookie', () => { - expect(() => Auth.decodeTokenForCookie('encoded')).to.throw('jwt malformed'); + expect(() => Auth.createCookieSession('encoded')).to.throw('jwt malformed'); }); it('invalid token cannot be decoded for workers', () => { - expect(() => Auth.decodeTokenForWorker('encoded')).to.throw('jwt malformed'); + expect(() => Auth.createWorkerSession('encoded')).to.throw('jwt malformed'); }); it('invalid session cannot be decoded for cookie', () => { const session = mockChtSession(); delete session.username; const encoded = Auth.encodeTokenForCookie(session); - expect(() => Auth.decodeTokenForCookie(encoded)).to.throw('invalid CHT session information'); + expect(() => Auth.createCookieSession(encoded)).to.throw('invalid CHT session information'); }); it('invalid session cannot be decoded for workers', () => { const session = mockChtSession(); delete session.username; const encoded = Auth.encodeTokenForWorker(session); - expect(() => Auth.decodeTokenForWorker(encoded)).to.throw('invalid CHT session information'); + expect(() => Auth.createWorkerSession(encoded)).to.throw('invalid CHT session information'); }); }); diff --git a/test/lib/cht-session.spec.ts b/test/lib/cht-session.spec.ts index f0e30cbf..3e5f8b7a 100644 --- a/test/lib/cht-session.spec.ts +++ b/test/lib/cht-session.spec.ts @@ -3,7 +3,7 @@ import rewire from 'rewire'; import sinon from 'sinon'; import { AuthenticationInfo } from '../../src/config'; -import { RemotePlace } from '../../src/lib/cht-api'; +import { RemotePlace } from '../../src/lib/remote-place-cache'; const ChtSession = rewire('../../src/lib/cht-session'); import chaiAsPromised from 'chai-as-promised'; @@ -44,7 +44,8 @@ describe('lib/cht-session.ts', () => { }, }, post: sinon.stub().resolves(mockSessionResponse()), - get: sinon.stub().resolves(mockUserFacilityDoc()), + get: sinon.stub().resolves(mockUserFacilityDoc()) + .onSecondCall().resolves({ data: { version: { app: '4.7.0' } } }), }; ChtSession.__set__('axios', { create: sinon.stub().returns(mockAxios), @@ -58,6 +59,7 @@ describe('lib/cht-session.ts', () => { expect(mockAxios.post.args[0][0]).to.be.a('string'); expect(session.sessionToken).to.eq('AuthSession=123'); expect(session.username).to.eq('user'); + expect(session.isAdmin).to.be.false; }); it('throw cht yields no authtoken', async () => { @@ -72,10 +74,13 @@ describe('lib/cht-session.ts', () => { it('throw if user-settings has no facility_id', async () => { mockAxios.get.resolves(mockUserFacilityDoc('', [])); - ChtSession.__set__('axios', mockAxios); - await expect(ChtSession.default.create(mockAuthInfo, 'user', 'pwd')).to.eventually.be.rejectedWith('does not have a facility_id'); }); + + it('throw if cht-core is 4.6.5', async () => { + mockAxios.get.onSecondCall().resolves({ data: { version: { app: '4.6.5' } } }); + await expect(ChtSession.default.create(mockAuthInfo, 'user', 'pwd')).to.eventually.be.rejectedWith('CHT Core Version must be'); + }); }); it('createFromDataString', async () => { @@ -83,6 +88,7 @@ describe('lib/cht-session.ts', () => { const data = JSON.stringify(session); const actual = ChtSession.default.createFromDataString(data); expect(actual).to.deep.eq(session); + expect(session.isAdmin).to.be.false; }); describe('isPlaceAuthorized', () => { diff --git a/test/lib/credentials-file.spec.ts b/test/lib/credentials-file.spec.ts new file mode 100644 index 00000000..b8329a85 --- /dev/null +++ b/test/lib/credentials-file.spec.ts @@ -0,0 +1,68 @@ +import SessionCache from '../../src/services/session-cache'; +import getCredentialsFiles from '../../src/lib/credentials-file'; +import PlaceFactory from '../../src/services/place-factory'; +import { ChtDoc, mockChtApi, mockValidContactType } from '../mocks'; +import { expect } from 'chai'; + +describe('lib/credentials-file.ts', () => { + it('one csv file per contact type', async () => { + const sessionCache = new SessionCache(); + const subcounty: ChtDoc = { + _id: 'parent-id', + name: 'parent-name', + }; + const fakeFormData: any = { + place_name: 'place', + place_prop: 'foo', + hierarchy_PARENT: subcounty.name, + contact_name: 'contact', + contact_phone: '0712344321', + }; + const chtApi = mockChtApi([subcounty]); + const contactType = mockValidContactType('string', undefined); + contactType.contact_properties.push({ + friendly_name: 'CHP Phone', + property_name: 'phone', + parameter: 'KE', + type: 'phone', + required: true + }); + + const place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); + + sessionCache.savePlaces(place); + const actual = getCredentialsFiles(sessionCache, [contactType]); + expect(actual).to.deep.eq([{ + filename: 'contacttype-name.csv', + content: `friendly replacement,friendly PARENT,friendly GRANDPARENT,friendly,name,phone,role,username,password +,Parent-name,,Place,contact,0712 344321,role,, +` + }]); + }); + + it('contact without phone number', async () => { + const sessionCache = new SessionCache(); + const subcounty: ChtDoc = { + _id: 'parent-id', + name: 'parent-name', + }; + const fakeFormData: any = { + place_name: 'place', + place_prop: 'foo', + hierarchy_PARENT: subcounty.name, + contact_name: 'contact', + }; + const chtApi = mockChtApi([subcounty]); + const contactType = mockValidContactType('string', undefined); + const place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); + + sessionCache.savePlaces(place); + const actual = getCredentialsFiles(sessionCache, [contactType]); + expect(actual).to.deep.eq([{ + filename: 'contacttype-name.csv', + content: `friendly replacement,friendly PARENT,friendly GRANDPARENT,friendly,name,phone,role,username,password +,Parent-name,,Place,contact,,role,, +` + }]); + }); +}); diff --git a/test/lib/disable-users.spec.ts b/test/lib/disable-users.spec.ts new file mode 100644 index 00000000..f6266aae --- /dev/null +++ b/test/lib/disable-users.spec.ts @@ -0,0 +1,111 @@ +import { expect } from 'chai'; +import Sinon from 'sinon'; + +import { DisableUsers } from '../../src/lib/disable-users'; + +const PLACE_ID = 'abc'; + +const mockChtApi = (usersAtPlace) => ({ + getUsersAtPlace: Sinon.stub().resolves(usersAtPlace), + disableUser: Sinon.stub().resolves(), + updateUser: Sinon.stub().resolves(), +}); + +describe('lib/disable-users.ts', () => { + it('disable a user with single facility (4.7)', async () => { + const cht = mockChtApi([{ + username: 'user', + place: { _id: PLACE_ID } + }]); + const actual = await DisableUsers.disableUsersAt(PLACE_ID, cht); + expect(cht.disableUser.callCount).to.eq(1); + expect(cht.disableUser.args[0]).to.deep.eq(['user']); + expect(cht.updateUser.called).to.be.false; + expect(actual).to.deep.eq(['user']); + }); + + it('disable a user with single facility (4.11)', async () => { + const cht = mockChtApi([{ + username: 'user', + place: [{ _id: PLACE_ID }] + }]); + const actual = await DisableUsers.disableUsersAt(PLACE_ID, cht); + expect(cht.disableUser.callCount).to.eq(1); + expect(cht.updateUser.called).to.be.false; + expect(actual).to.deep.eq(['user']); + }); + + it('deactivate a user with single facility (4.11)', async () => { + const cht = mockChtApi([{ + username: 'user', + place: [{ _id: PLACE_ID }] + }]); + const actual = await DisableUsers.deactivateUsersAt(PLACE_ID, cht); + expect(cht.disableUser.called).to.be.false; + expect(cht.updateUser.callCount).to.eq(1); + expect(cht.updateUser.args[0]).to.deep.eq([{ + username: 'user', + roles: ['deactivated'], + }]); + expect(actual).to.deep.eq(['user']); + }); + + it('user is updated when one of two facilities are removed (disable)', async () => { + const cht = mockChtApi([{ + username: 'user', + place: [{ _id: PLACE_ID }, { _id: 'efg' }] + }]); + const actual = await DisableUsers.disableUsersAt(PLACE_ID, cht); + expect(cht.disableUser.called).to.be.false; + expect(cht.updateUser.called).to.be.true; + expect(cht.updateUser.args[0]).to.deep.eq([{ + username: 'user', + place: ['efg'], + }]); + expect(actual).to.deep.eq(['user']); + }); + + it('user is updated when one of two facilities are removed (deactivate)', async () => { + const cht = mockChtApi([{ + username: 'user', + place: [{ _id: PLACE_ID }, { _id: 'efg' }] + }]); + const actual = await DisableUsers.deactivateUsersAt(PLACE_ID, cht); + expect(cht.disableUser.called).to.be.false; + expect(cht.updateUser.called).to.be.true; + expect(cht.updateUser.args[0]).to.deep.eq([{ + username: 'user', + place: ['efg'], + }]); + expect(actual).to.deep.eq(['user']); + }); + + it('two users are disabled when they share a facility', async () => { + const cht = mockChtApi([ + { + username: 'user', + place: [{ _id: PLACE_ID }], + }, + { + username: 'other', + place: [{ _id: PLACE_ID }], + }, + ]); + + const actual = await DisableUsers.disableUsersAt(PLACE_ID, cht); + expect(cht.disableUser.callCount).to.eq(2); + expect(cht.disableUser.args).to.deep.eq([['user'], ['other']]); + expect(cht.updateUser.called).to.be.false; + expect(actual).to.deep.eq(['user', 'other']); + }); + + it('some user facility_ids do not exist', async () => { + const cht = mockChtApi([{ + username: 'user', + place: [null, { _id: PLACE_ID }, null, { _id: 'efg' }] + }]); + await DisableUsers.disableUsersAt(PLACE_ID, cht); + expect(cht.disableUser.called).to.be.false; + expect(cht.updateUser.callCount).to.eq(1); + }); +}); diff --git a/test/lib/manage-hierarchy.spec.ts b/test/lib/manage-hierarchy.spec.ts new file mode 100644 index 00000000..f0a5fd3b --- /dev/null +++ b/test/lib/manage-hierarchy.spec.ts @@ -0,0 +1,215 @@ +import Chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { DateTime } from 'luxon'; +import sinon from 'sinon'; + +import Auth from '../../src/lib/authentication'; +import { Config } from '../../src/config'; +import { JobParams } from '../../src/lib/queues'; +import ManageHierarchyLib from '../../src/lib/manage-hierarchy'; +import { mockChtApi, mockChtSession } from '../mocks'; +import RemotePlaceCache from '../../src/lib/remote-place-cache'; +import SessionCache from '../../src/services/session-cache'; + +Chai.use(chaiAsPromised); + +const { expect } = Chai; + +describe('lib/manage-hierarchy.ts', () => { + const subcountyDocs = [ + { _id: 'from-sub', name: 'From Sub' }, + { _id: 'to-sub', name: 'To Sub' } + ]; + const chuDocs = [ + { _id: 'from-chu-id', name: 'c-h-u', parent: { _id: 'from-sub' } }, + { _id: 'to-chu-id', name: 'destination', parent: { _id: 'to-sub' } }, + ]; + + const chtApiWithDocs = () => mockChtApi(subcountyDocs, chuDocs); + + beforeEach(() => { + sinon.stub(Auth, 'encodeTokenForWorker').returns('encoded-token'); + RemotePlaceCache.clear({}); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('move', () => { + it('move CHU: success', async () => { + const formData = { + op: 'move', + source_replacement: 'c-h-u', + source_SUBCOUNTY: 'from sub', + destination_SUBCOUNTY: 'to sub', + }; + const contactType = Config.getContactType('c_community_health_unit'); + const sessionCache = new SessionCache(); + + const jobParams = await ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs()); + expect(jobParams).to.have.property('jobName').that.equals('move_[From Sub.C-h-u]_to_[To Sub]'); + expect(jobParams).to.have.property('jobData').that.deep.include({ + action: 'move', + sourceId: 'from-chu-id', + destinationId: 'to-sub', + instanceUrl: 'http://domain.com', + sessionToken: 'encoded-token', + }); + }); + + it('move CHU: subcounty required', async () => { + const formData = { + op: 'move', + source_replacement: 'c-h-u', + destination_SUBCOUNTY: 'to sub', + }; + const contactType = Config.getContactType('c_community_health_unit'); + const sessionCache = new SessionCache(); + + const actual = ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, mockChtApi(chuDocs)); + await expect(actual).to.eventually.be.rejectedWith('search string is empty'); + }); + + it('move CHU: cant move to same place', async () => { + const formData = { + op: 'move', + source_replacement: 'c-h-u', + source_SUBCOUNTY: 'from SUB', + destination_SUBCOUNTY: 'from sub', + }; + const contactType = Config.getContactType('c_community_health_unit'); + const sessionCache = new SessionCache(); + + const actual = ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs()); + await expect(actual).to.eventually.be.rejectedWith('Place "c-h-u" already has "From Sub" as parent'); + }); + + it('move CHU: fail to resolve parent', async () => { + const formData = { + op: 'move', + source_replacement: 'c-h-u', + source_SUBCOUNTY: 'from SUB', + destination_SUBCOUNTY: 'invalid sub', + }; + const contactType = Config.getContactType('c_community_health_unit'); + const sessionCache = new SessionCache(); + + const actual = ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs()); + await expect(actual).to.eventually.be.rejectedWith('Cannot find \'b_sub_county\' matching \'invalid sub\''); + }); + }); + + describe('merge', () => { + it('merge CHU: success', async () => { + const formData = { + op: 'merge', + source_replacement: 'c-h-u', + source_SUBCOUNTY: 'from sub', + destination_SUBCOUNTY: 'to sub', + destination_replacement: 'destination', + }; + const contactType = Config.getContactType('c_community_health_unit'); + const sessionCache = new SessionCache(); + + const jobParams = await ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs()); + expect(jobParams).to.have.property('jobName').that.equals('merge_[From Sub.C-h-u]_to_[To Sub.Destination]'); + expect(jobParams).to.have.property('jobData').that.deep.include({ + action: 'merge', + sourceId: 'from-chu-id', + destinationId: 'to-chu-id', + instanceUrl: 'http://domain.com', + sessionToken: 'encoded-token', + }); + }); + }); + + describe('delete', () => { + it('delete CHU: success', async () => { + const formData = { + op: 'delete', + source_replacement: 'c-h-u', + source_SUBCOUNTY: 'from sub' + }; + const contactType = Config.getContactType('c_community_health_unit'); + const sessionCache = new SessionCache(); + + const jobParams = await ManageHierarchyLib.getJobDetails(formData, contactType, sessionCache, chtApiWithDocs()); + expect(jobParams).to.have.property('jobName').that.equals('delete_[From Sub.C-h-u]'); + expect(jobParams).to.have.property('jobData').that.deep.include({ + action: 'delete', + sourceId: 'from-chu-id', + instanceUrl: 'http://domain.com', + sessionToken: 'encoded-token', + }); + }); + }); + + describe('getWarningInfo', () => { + const fakeJob: JobParams = { jobName: 'foo', jobData: { sourceId: 'abc' }}; + + it('below thrsholds', async () => { + const chtApi = mockChtApi(); + chtApi.countContactsUnderPlace = sinon.stub().resolves(5); + chtApi.lastSyncAtPlace = sinon.stub().resolves(DateTime.now().minus({ days: 100 })); + const actual = await ManageHierarchyLib.getWarningInfo(fakeJob, chtApi); + expect(actual).to.deep.eq({ + affectedPlaceCount: 5, + lastSyncDescription: '3 months ago', + userIsActive: false, + lotsOfPlaces: false, + }); + }); + + it('above thresholds', async () => { + const chtApi = mockChtApi(); + chtApi.countContactsUnderPlace = sinon.stub().resolves(1000); + chtApi.lastSyncAtPlace = sinon.stub().resolves(DateTime.now().minus({ days: 10 })); + const actual = await ManageHierarchyLib.getWarningInfo(fakeJob, chtApi); + expect(actual).to.deep.eq({ + affectedPlaceCount: 1000, + lastSyncDescription: '10 days ago', + userIsActive: true, + lotsOfPlaces: true, + }); + }); + + it('no sync details for non-admins', async () => { + const chtApi = mockChtApi(); + chtApi.chtSession = mockChtSession('abc'); + chtApi.countContactsUnderPlace = sinon.stub().resolves(2); + chtApi.lastSyncAtPlace = sinon.stub().throws('only for admins'); + const actual = await ManageHierarchyLib.getWarningInfo(fakeJob, chtApi); + expect(actual).to.deep.eq({ + affectedPlaceCount: 2, + lastSyncDescription: '-', + userIsActive: false, + lotsOfPlaces: false, + }); + expect(chtApi.lastSyncAtPlace.called).to.be.false; + }); + + it('very old sync dates show as -', async () => { + const chtApi = mockChtApi(); + chtApi.countContactsUnderPlace = sinon.stub().resolves(2); + chtApi.lastSyncAtPlace = sinon.stub().resolves(DateTime.now().minus({ days: 1000 })); + const actual = await ManageHierarchyLib.getWarningInfo(fakeJob, chtApi); + expect(actual).to.deep.include({ + lastSyncDescription: 'over a year', + userIsActive: false, + }); + }); + + it('sync dates in future show as -', async () => { + const chtApi = mockChtApi(); + chtApi.countContactsUnderPlace = sinon.stub().resolves(2); + chtApi.lastSyncAtPlace = sinon.stub().resolves(DateTime.now().plus({ days: 1 })); + const actual = await ManageHierarchyLib.getWarningInfo(fakeJob, chtApi); + expect(actual).to.deep.include({ + lastSyncDescription: '-', + userIsActive: false, + }); + }); + }); +}); + diff --git a/test/lib/move.spec.ts b/test/lib/move.spec.ts deleted file mode 100644 index 8c314a73..00000000 --- a/test/lib/move.spec.ts +++ /dev/null @@ -1,100 +0,0 @@ -import Chai from 'chai'; -import sinon from 'sinon'; - -import MoveLib from '../../src/lib/move'; -import { Config } from '../../src/config'; -import SessionCache from '../../src/services/session-cache'; -import { mockChtApi } from '../mocks'; - -import chaiAsPromised from 'chai-as-promised'; -import Auth from '../../src/lib/authentication'; -import { BullQueue } from '../../src/lib/queues'; -Chai.use(chaiAsPromised); - -const { expect } = Chai; - -describe('lib/move.ts', () => { - let moveContactQueue: any; - - beforeEach(() => { - moveContactQueue = sinon.createStubInstance(BullQueue); - sinon.stub(Auth, 'encodeTokenForWorker').returns('encoded-token'); - }); - - afterEach(() => { - sinon.restore(); - }); - - const chtApi = () => mockChtApi( - [ - { id: 'from-sub', name: 'From Sub', lineage: [], type: 'remote' }, - { id: 'to-sub', name: 'To Sub', lineage: [], type: 'remote' } - ], - [{ id: 'chu-id', name: 'c-h-u', lineage: ['from-sub'], type: 'remote' }], - ); - - it('move CHU: success', async () => { - const formData = { - from_replacement: 'c-h-u', - from_SUBCOUNTY: 'from sub', - to_SUBCOUNTY: 'to sub', - }; - const contactType = Config.getContactType('c_community_health_unit'); - const sessionCache = new SessionCache(); - - const actual = await MoveLib.move(formData, contactType, sessionCache, chtApi(), moveContactQueue); - expect(actual.fromLineage.map((l:any) => l.id)).to.deep.eq(['chu-id', 'from-sub']); - expect(actual.toLineage.map((l:any) => l.id)).to.deep.eq([undefined, 'to-sub']); - - // Verify the data passed to mockmoveContactQueue - expect(moveContactQueue.add.calledOnce).to.be.true; - const jobParams = moveContactQueue.add.getCall(0).args[0]; - - expect(jobParams).to.have.property('jobName').that.equals('move_[c-h-u]_from_[From Sub]_to_[To Sub]'); - expect(jobParams).to.have.property('jobData').that.deep.include({ - contactId: 'chu-id', - parentId: 'to-sub', - instanceUrl: 'http://domain.com', - sessionToken: 'encoded-token', - }); - }); - - it('move CHU: subcounty required', async () => { - const formData = { - from_replacement: 'c-h-u', - to_SUBCOUNTY: 'to sub', - }; - const contactType = Config.getContactType('c_community_health_unit'); - const sessionCache = new SessionCache(); - - const actual = MoveLib.move(formData, contactType, sessionCache, chtApi(), moveContactQueue); - await expect(actual).to.eventually.be.rejectedWith('search string is empty'); - }); - - it('move CHU: cant move to same place', async () => { - const formData = { - from_replacement: 'c-h-u', - from_SUBCOUNTY: 'from SUB', - to_SUBCOUNTY: 'from sub', - }; - const contactType = Config.getContactType('c_community_health_unit'); - const sessionCache = new SessionCache(); - - const actual = MoveLib.move(formData, contactType, sessionCache, chtApi(), moveContactQueue); - await expect(actual).to.eventually.be.rejectedWith('Place "c-h-u" already has "From Sub" as parent'); - }); - - it('move CHU: fail to resolve parent', async () => { - const formData = { - from_replacement: 'c-h-u', - from_SUBCOUNTY: 'from SUB', - to_SUBCOUNTY: 'invalid sub', - }; - const contactType = Config.getContactType('c_community_health_unit'); - const sessionCache = new SessionCache(); - - const actual = MoveLib.move(formData, contactType, sessionCache, chtApi(), moveContactQueue); - await expect(actual).to.eventually.be.rejectedWith('Cannot find \'b_sub_county\' matching \'Invalid Sub\''); - }); -}); - diff --git a/test/lib/remote-place-cache.spec.ts b/test/lib/remote-place-cache.spec.ts index ae205267..76f86642 100644 --- a/test/lib/remote-place-cache.spec.ts +++ b/test/lib/remote-place-cache.spec.ts @@ -1,46 +1,88 @@ import { expect } from 'chai'; -import { RemotePlace } from '../../src/lib/cht-api'; +import { ChtDoc, mockChtApi, mockPlace, mockSimpleContactType } from '../mocks'; +import { HierarchyConstraint } from '../../src/config'; import RemotePlaceCache from '../../src/lib/remote-place-cache'; -import { mockChtApi, mockPlace, mockSimpleContactType } from '../mocks'; describe('lib/remote-place-cache.ts', () => { beforeEach(() => { RemotePlaceCache.clear({}); }); - const remotePlace: RemotePlace = { - id: 'parent-id', + const doc: ChtDoc = { + _id: 'parent-id', name: 'parent', + }; + + const docAsRemotePlace = { + id: doc._id, + 'name.original': doc.name, type: 'remote', lineage: [], }; + const contactType = mockSimpleContactType('string', undefined); + const hierarchyLevel = contactType.hierarchy[0]; + it('cache miss', async () => { - const chtApi = mockChtApi([remotePlace]); - const actual = await RemotePlaceCache.getPlacesWithType(chtApi, 'type'); - expect(actual).to.deep.eq([remotePlace]); + const chtApi = mockChtApi([doc]); + const actual = await RemotePlaceCache.getPlacesWithType(chtApi, contactType, hierarchyLevel); + expect(actual).to.have.property('length', 1); + expect(actual[0]).to.deep.nested.include(docAsRemotePlace); expect(chtApi.getPlacesWithType.calledOnce).to.be.true; }); it('cache hit', async () => { - const chtApi = mockChtApi([remotePlace]); - await RemotePlaceCache.getPlacesWithType(chtApi, 'type'); - const second = await RemotePlaceCache.getPlacesWithType(chtApi, 'type'); - expect(second).to.deep.eq([remotePlace]); + const chtApi = mockChtApi([doc]); + + await RemotePlaceCache.getPlacesWithType(chtApi, contactType, hierarchyLevel); + const second = await RemotePlaceCache.getPlacesWithType(chtApi, contactType, hierarchyLevel); + expect(second).to.have.property('length', 1); + expect(second[0]).to.deep.nested.include(docAsRemotePlace); expect(chtApi.getPlacesWithType.calledOnce).to.be.true; }); it('add', async () => { - const contactType = mockSimpleContactType('unknown`', undefined); + const contactType = mockSimpleContactType('string', undefined); const place = mockPlace(contactType, 'prop'); + const chtApi = mockChtApi([doc]); + + const contactTypeAsHierarchyLevel: HierarchyConstraint = { + contact_type: contactType.name, + property_name: 'level', + friendly_name: 'pretend another ContactType needs this', + type: 'name', + required: true, + level: 0, + }; + await RemotePlaceCache.getPlacesWithType(chtApi, contactType, contactTypeAsHierarchyLevel); + RemotePlaceCache.add(place, chtApi); - const chtApi = mockChtApi([remotePlace]); - await RemotePlaceCache.add(place, chtApi); - - const second = await RemotePlaceCache.getPlacesWithType(chtApi, contactType.name); - expect(second).to.deep.eq([remotePlace, place.asRemotePlace()]); + const second = await RemotePlaceCache.getPlacesWithType(chtApi, contactType, contactTypeAsHierarchyLevel); + expect(second).to.have.property('length', 2); + expect(second[0]).to.deep.nested.include(docAsRemotePlace); + expect(second[1].id).to.eq(place.asRemotePlace().id); expect(chtApi.getPlacesWithType.calledOnce).to.be.true; }); + + it('clear', async () => { + const contactType = mockSimpleContactType('string', undefined); + const place = mockPlace(contactType, 'prop'); + const chtApi = mockChtApi([doc]); + + const contactTypeAsHierarchyLevel: HierarchyConstraint = { + contact_type: contactType.name, + property_name: 'level', + friendly_name: 'pretend another ContactType needs this', + type: 'name', + required: true, + level: 0, + }; + await RemotePlaceCache.getPlacesWithType(chtApi, contactType, contactTypeAsHierarchyLevel); + RemotePlaceCache.add(place, chtApi); + + chtApi.chtSession.authInfo.domain = 'http://other'; + RemotePlaceCache.clear(chtApi, 'other'); + }); }); diff --git a/test/lib/search.spec.ts b/test/lib/search.spec.ts index 2e8895fb..92d294d1 100644 --- a/test/lib/search.spec.ts +++ b/test/lib/search.spec.ts @@ -1,9 +1,8 @@ import { expect } from 'chai'; -import { RemotePlace } from '../../src/lib/cht-api'; -import RemotePlaceCache from '../../src/lib/remote-place-cache'; +import RemotePlaceCache, { RemotePlace } from '../../src/lib/remote-place-cache'; import SearchLib from '../../src/lib/search'; -import { mockChtApi, mockChtSession, mockValidContactType } from '../mocks'; +import { ChtDoc, mockChtApi, mockChtSession, mockValidContactType } from '../mocks'; import SessionCache from '../../src/services/session-cache'; import { Config } from '../../src/config'; import RemotePlaceResolver from '../../src/lib/remote-place-resolver'; @@ -13,18 +12,16 @@ describe('lib/remote-place-cache.ts', () => { RemotePlaceCache.clear({}); }); - const parentPlace: RemotePlace = { - id: 'parent-id', + const parentPlace: ChtDoc = { + _id: 'parent-id', name: 'parent', - type: 'remote', - lineage: ['grandparent-id'], + parent: { _id: 'grandparent-id' }, }; - const toReplacePlace: RemotePlace = { - id: 'to-replace', + const toReplacePlace: ChtDoc = { + _id: 'to-replace', name: 'replace me', - type: 'remote', - lineage: [parentPlace.id, ...parentPlace.lineage], + parent: { _id: parentPlace._id, parent: parentPlace.parent }, }; it('simple search', async () => { @@ -39,7 +36,7 @@ describe('lib/remote-place-cache.ts', () => { const [replacementLevel] = Config.getHierarchyWithReplacement(contactType); const actual = await SearchLib.search(contactType, formData, 'hierarchy_', replacementLevel, chtApi, sessionCache); - expect(actual).to.deep.eq([toReplacePlace]); + assertPlaceMatchesDoc(actual, [toReplacePlace]); }); it('data prefix', async () => { @@ -54,16 +51,15 @@ describe('lib/remote-place-cache.ts', () => { const [replacementLevel] = Config.getHierarchyWithReplacement(contactType); const actual = await SearchLib.search(contactType, formData, 'prefix_', replacementLevel, chtApi, sessionCache); - expect(actual).to.deep.eq([toReplacePlace]); + assertPlaceMatchesDoc(actual, [toReplacePlace]); }); it('search constrained by parent', async () => { const sessionCache = new SessionCache(); - const ambiguity: RemotePlace = { - id: 'ambiguous', + const ambiguity: ChtDoc = { + _id: 'ambiguous', name: 'me ambiguous', - type: 'remote', - lineage: ['other-parent', ...parentPlace.lineage], + parent: { _id: 'other-parent', parent: parentPlace.parent }, }; const contactType = mockValidContactType('string', undefined); @@ -77,7 +73,22 @@ describe('lib/remote-place-cache.ts', () => { const [replacementLevel] = Config.getHierarchyWithReplacement(contactType); const actual = await SearchLib.search(contactType, formData, 'hierarchy_', replacementLevel, chtApi, sessionCache); - expect(actual).to.deep.eq([toReplacePlace]); + assertPlaceMatchesDoc(actual, [toReplacePlace]); + }); + + it('ignores accents', async () => { + const sessionCache = new SessionCache(); + const contactType = mockValidContactType('string', undefined); + const formData = { + hierarchy_replacement: 'plÀce', + }; + const chtApi = mockChtApi(); + chtApi.getPlacesWithType.resolves([toReplacePlace]) + .onSecondCall().resolves([parentPlace]); + + const [replacementLevel] = Config.getHierarchyWithReplacement(contactType); + const actual = await SearchLib.search(contactType, formData, 'hierarchy_', replacementLevel, chtApi, sessionCache); + assertPlaceMatchesDoc(actual, [toReplacePlace]); }); it('search unsuccessful when result is not child of user facility', async () => { @@ -97,3 +108,9 @@ describe('lib/remote-place-cache.ts', () => { }); }); +function assertPlaceMatchesDoc(remotePlace: RemotePlace[], docs: ChtDoc[]) { + const remotePlaceIds = remotePlace.map(a => a.id); + const docIds = docs.map(doc => doc._id); + expect(remotePlaceIds).to.deep.eq(docIds); +} + diff --git a/test/lib/validation.spec.ts b/test/lib/validation.spec.ts deleted file mode 100644 index aa0861ca..00000000 --- a/test/lib/validation.spec.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { DateTime } from 'luxon'; -import { expect } from 'chai'; - -import { Validation } from '../../src/lib/validation'; -import { mockSimpleContactType, mockPlace } from '../mocks'; -import RemotePlaceResolver from '../../src/lib/remote-place-resolver'; - -type Scenario = { - type: string; - prop?: string; - isValid: boolean; - propertyParameter?: string | string[] | object; - altered?: string; - propertyErrorDescription?: string; - error?: string; -}; - -const EMAIL_REGEX = '^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$'; -const GENDER_OPTIONS = { male: 'Male', female: 'Female' }; -const CANDIES_OPTIONS = { chocolate: 'Chocolate', strawberry: 'Strawberry' }; - -const scenarios: Scenario[] = [ - { type: 'string', prop: undefined, isValid: false, error: 'Required' }, - { type: 'string', prop: 'abc', isValid: true }, - { type: 'string', prop: ' ab\nc', isValid: true, altered: 'abc' }, - { type: 'string', prop: 'Mr. Sand(m-a-n)', isValid: true, altered: 'Mr. Sand(m-a-n)' }, - { type: 'string', prop: 'Université ', isValid: true, altered: 'Université' }, - { type: 'string', prop: `Infirmière d'Etat`, isValid: true, altered: `Infirmière d'Etat` }, - { type: 'string', prop: '', isValid: false, altered: '', error: 'Required' }, - - { type: 'phone', prop: undefined, isValid: false, error: 'Required' }, - { type: 'phone', prop: '+254712345678', isValid: true, altered: '0712 345678', propertyParameter: 'KE' }, - { type: 'phone', prop: '712345678', isValid: true, altered: '0712 345678', propertyParameter: 'KE' }, - { type: 'phone', prop: '+254712345678', isValid: false, altered: '0712 345678', propertyParameter: 'UG', error: 'Not a valid' }, - { type: 'phone', prop: '+17058772274', isValid: false, altered: '(705) 877-2274', propertyParameter: 'KE', error: 'KE' }, - - { type: 'regex', prop: undefined, isValid: false, error: 'Required' }, - { type: 'regex', propertyParameter: '^\\d{6}$', prop: '123456', isValid: true }, - { type: 'regex', propertyParameter: '^\\d{6}$', prop: ' 123456 *&%', isValid: true, altered: '123456' }, - { type: 'regex', propertyParameter: '^\\d{6}$', prop: '1234567', isValid: false, error: 'six digit', propertyErrorDescription: 'six digit number' }, - { type: 'regex', propertyParameter: EMAIL_REGEX, prop: 'email@address.com', isValid: true, altered: 'email@address.com' }, - { type: 'regex', propertyParameter: EMAIL_REGEX, prop: '.com', isValid: false, propertyErrorDescription: 'valid email address', error: 'email' }, - { type: 'regex', propertyParameter: undefined, prop: 'abc', isValid: false, error: 'missing parameter' }, - - { type: 'name', prop: undefined, isValid: false, error: 'Required' }, - { type: 'name', prop: 'abc', isValid: true, altered: 'Abc' }, - { type: 'name', prop: 'a b c', isValid: true, altered: 'A B C' }, - { type: 'name', prop: 'Mr. Sand(m-a-n)', isValid: true, altered: 'Mr Sand(m-a-n)' }, - { type: 'name', prop: 'WELDON KO(E)CH \n', isValid: true, altered: 'Weldon Ko(e)ch' }, - { type: 'name', prop: 'S \'am \'s', isValid: true, altered: 'S\'am\'s' }, - { type: 'name', prop: 'KYAMBOO/KALILUNI', isValid: true, altered: 'Kyamboo / Kaliluni' }, - { type: 'name', prop: 'NZATANI / ILALAMBYU', isValid: true, altered: 'Nzatani / Ilalambyu' }, - { type: 'name', prop: 'Sam\'s CHU', propertyParameter: ['CHU', 'Comm Unit'], isValid: true, altered: 'Sam\'s' }, - { type: 'name', prop: 'Jonathan M.Barasa', isValid: true, altered: 'Jonathan M Barasa' }, - { type: 'name', prop: 'Robert xiv', isValid: true, altered: 'Robert XIV' }, - { type: 'name', prop: ' ', isValid: true, altered: '' }, - - { type: 'dob', prop: undefined, isValid: false, error: 'Required' }, - { type: 'dob', prop: '', isValid: false }, - { type: 'dob', prop: '2016/05/25', isValid: false }, - { type: 'dob', prop: 'May 25, 2016', isValid: false }, - { type: 'dob', prop: '2030-05-25', isValid: false }, - { type: 'dob', prop: '2016-05-25', isValid: true, altered: '2016-05-25' }, - { type: 'dob', prop: ' 20 16- 05- 25 ', isValid: true, altered: '2016-05-25' }, - { type: 'dob', prop: '20', isValid: true, altered: DateTime.now().minus({ years: 20 }).toISODate() }, - { type: 'dob', prop: ' 20 ', isValid: true, altered: DateTime.now().minus({ years: 20 }).toISODate() }, - { type: 'dob', prop: 'abc', isValid: false, altered: 'abc' }, - { type: 'dob', prop: ' 1 0 0 ', isValid: true, altered: DateTime.now().minus({ years: 100 }).toISODate() }, - { type: 'dob', prop: '-1', isValid: false, altered: '-1' }, - { type: 'dob', prop: '15/2/1985', isValid: true, altered: '1985-02-15' }, - { type: 'dob', prop: '1/2/1 985', isValid: true, altered: '1985-02-01' }, - { type: 'dob', prop: '1/13/1985', isValid: false }, - - { type: 'select_one', prop: undefined, isValid: false, error: 'Required' }, - { type: 'select_one', prop: ' male', isValid: true, propertyParameter: GENDER_OPTIONS }, - { type: 'select_one', prop: 'female ', isValid: true, propertyParameter: GENDER_OPTIONS }, - { type: 'select_one', prop: 'FeMale ', isValid: false, propertyParameter: GENDER_OPTIONS }, - { type: 'select_one', prop: 'f', isValid: false, propertyParameter: GENDER_OPTIONS }, - { type: 'select_one', prop: '', isValid: false, propertyParameter: GENDER_OPTIONS }, - - { type: 'select_multiple', prop: undefined, isValid: false, error: 'Required' }, - { type: 'select_multiple', prop: 'chocolate', isValid: true, propertyParameter: CANDIES_OPTIONS }, - { type: 'select_multiple', prop: 'chocolate strawberry', isValid: true, propertyParameter: CANDIES_OPTIONS }, - { type: 'select_multiple', prop: ' chocolate strawberry', isValid: true, propertyParameter: CANDIES_OPTIONS }, - { type: 'select_multiple', prop: 'c,s', isValid: false, propertyParameter: CANDIES_OPTIONS, error: 'Invalid values' }, - { type: 'select_multiple', prop: '', isValid: false, propertyParameter: CANDIES_OPTIONS, error: 'required' }, - - { type: 'generated', prop: 'b', propertyParameter: 'a {{ place.prop }} c', isValid: true, altered: 'a b c' }, - { type: 'generated', prop: 'b', propertyParameter: '{{ contact.name }} ({{ lineage.PARENT }})', isValid: true, altered: 'contact (Parent)' }, - { type: 'generated', prop: 'b', propertyParameter: 'x {{ contact.dne }}', isValid: true, altered: 'x ' }, -]; - -describe('lib/validation.ts', () => { - for (const scenario of scenarios) { - it(`scenario: ${JSON.stringify(scenario)}`, () => { - const contactType = mockSimpleContactType(scenario.type, scenario.propertyParameter, scenario.propertyErrorDescription); - const place = mockPlace(contactType, scenario.prop); - - const actualValidity = Validation.getValidationErrors(place); - expect(actualValidity.map(a => a.property_name)).to.deep.eq(scenario.isValid ? [] : ['place_prop']); - - if (scenario.error) { - expect(actualValidity?.[0].description).to.include(scenario.error); - } - - Validation.format(place); - expect(place.properties.prop).to.eq(scenario.altered ?? scenario.prop); - }); - } - - it('unknown property type throws', () => { - const contactType = mockSimpleContactType('unknown`', undefined); - const place = mockPlace(contactType, 'prop'); - - expect(() => Validation.getValidationErrors(place)).to.throw('unvalidatable'); - }); - - it('property with required:false can be empty', () => { - const contactType = mockSimpleContactType('string', undefined); - contactType.place_properties[contactType.place_properties.length-1].required = false; - - const place = mockPlace(contactType, undefined); - place.properties = { name: 'foo' }; - place.hierarchyProperties = { PARENT: 'parent' }; - - expect(Validation.getValidationErrors(place)).to.be.empty; - }); - - it('#91 - parent is invalid when required:false but resolution is NoResult', () => { - const contactType = mockSimpleContactType('string', undefined); - contactType.hierarchy[0].required = false; - - const place = mockPlace(contactType, 'prop'); - place.resolvedHierarchy[1] = RemotePlaceResolver.NoResult; - - console.log('Validation.getValidationErrors(place)', Validation.getValidationErrors(place)); - expect(Validation.getValidationErrors(place)).to.deep.eq([{ - property_name: 'hierarchy_PARENT', - description: `Cannot find 'parent' matching 'parent'`, - }]); - }); - - it('parent is invalid when missing but expected', () => { - const contactType = mockSimpleContactType('string', undefined); - const place = mockPlace(contactType, 'prop'); - delete place.resolvedHierarchy[1]; - - expect(Validation.getValidationErrors(place)).to.deep.eq([{ - property_name: 'hierarchy_PARENT', - description: `Cannot find 'parent' matching 'parent'`, - }]); - }); - - it('parent is valid when missing and not expected', () => { - const contactType = mockSimpleContactType('string', undefined); - contactType.hierarchy[0].required = false; - - const place = mockPlace(contactType, 'prop'); - delete place.resolvedHierarchy[1]; - - expect(Validation.getValidationErrors(place)).to.be.empty; - }); - - it('replacement property is validated and altered as property_name:name', () => { - const contactType = mockSimpleContactType('string', undefined); - - const place = mockPlace(contactType, 'foo'); - place.hierarchyProperties.replacement = 'sin bad'; - - Validation.format(place); - expect(place.hierarchyProperties.replacement).to.eq('Sin Bad'); - - const validationErrors = Validation.getValidationErrors(place); - expect(validationErrors).to.deep.eq([{ - property_name: 'hierarchy_replacement', - description: `Cannot find 'contacttype-name' matching 'Sin Bad' under 'Parent'`, - }]); - }); - - it('user_role property empty throws', () => { - const contactType = mockSimpleContactType('string', undefined); - contactType.user_role = []; - - const place = mockPlace(contactType, 'prop'); - - expect(() => Validation.getValidationErrors(place)).to.throw('unvalidatable'); - }); - - it('user_role property contains empty string throws', () => { - const contactType = mockSimpleContactType('string', undefined); - contactType.user_role = ['']; - - const place = mockPlace(contactType, 'prop'); - - expect(() => Validation.getValidationErrors(place)).to.throw('unvalidatable'); - }); - - it('user role is invalid when not allowed', () => { - const contactType = mockSimpleContactType('string', undefined); - contactType.user_role = ['supervisor', 'stock_manager']; - - const place = mockPlace(contactType, 'prop'); - - const formData = { - place_prop: 'abc', - contact_prop: 'efg', - garbage: 'ghj', - user_role: 'supervisor stockmanager', - }; - place.setPropertiesFromFormData(formData); - - expect(Validation.getValidationErrors(place)).to.deep.eq([{ - property_name: 'user_role', - description: `Invalid values for property "Roles": stockmanager` - }]); - }); -}); diff --git a/test/mocks.ts b/test/mocks.ts index 88c4dafa..b6eae55d 100644 --- a/test/mocks.ts +++ b/test/mocks.ts @@ -1,40 +1,46 @@ import { expect } from 'chai'; -import Sinon from 'sinon'; +import sinon from 'sinon'; -import { ChtApi, RemotePlace } from '../src/lib/cht-api'; +import { ChtApi } from '../src/lib/cht-api'; import ChtSession from '../src/lib/cht-session'; -import { ContactProperty, ContactType } from '../src/config'; +import { Config, ContactProperty, ContactType } from '../src/config'; import Place from '../src/services/place'; +import PlaceFactory from '../src/services/place-factory'; +import { UnvalidatedPropertyValue } from '../src/property-value'; +export type ChtDoc = { + _id: string; + name: string; + [key: string]: string | Object; +}; -export const mockPlace = (type: ContactType, prop: any) : Place => { - const result = new Place(type); - result.properties = { - name: 'place', - prop - }; - result.hierarchyProperties = { - PARENT: 'parent', - }; - result.contact.properties = { - name: 'contact', - }; - result.resolvedHierarchy[1] = { +export const mockPlace = (contactType: ContactType, formDataOverride?: any) : Place => { + const formData = Object.assign({ + place_name: 'name', + place_prop: 'prop', + hierarchy_PARENT: 'parent', + contact_name: 'contact' + }, formDataOverride); + const place = new Place(contactType); + place.setPropertiesFromFormData(formData, 'hierarchy_'); + place.resolvedHierarchy[1] = { id: 'known', - name: 'parent', + name: new UnvalidatedPropertyValue('parent'), + lineage: [], type: 'remote', }; - return result; + place.validate(); + return place; }; -export const mockChtApi: ChtApi = (first: RemotePlace[] = [], second: RemotePlace[] = []) => ({ +export const mockChtApi = (first: ChtDoc[] = [], second: ChtDoc[] = []): any => ({ chtSession: mockChtSession(), - getPlacesWithType: Sinon.stub().resolves(first).onSecondCall().resolves(second), + getPlacesWithType: sinon.stub().resolves(first).onSecondCall().resolves(second), }); export const mockSimpleContactType = ( propertyType: string, - propertyValidator: string | string[] | undefined, + propertyValidator?: string | string[] | object, errorDescription?: string ) : ContactType => { const mockedProperty = mockProperty(propertyType, propertyValidator); @@ -58,10 +64,28 @@ export const mockSimpleContactType = ( mockProperty('name', undefined, 'name'), mockedProperty, ], - contact_properties: [], + contact_properties: [ + mockProperty('name', undefined, 'name'), + ], }; }; +export async function createChu(subcounty: ChtDoc, chu_name: string, sessionCache: any, chtApi: ChtApi, dataOverrides?: any): Promise { + const chuType = Config.getContactType('c_community_health_unit'); + const chuData = Object.assign({ + hierarchy_SUBCOUNTY: subcounty.name, + place_name: chu_name, + place_code: '676767', + place_link_facility_name: 'facility name', + place_link_facility_code: '23456', + contact_name: 'new cha', + contact_phone: '0712345678', + }, dataOverrides); + const chu = await PlaceFactory.createOne(chuData, chuType, sessionCache, chtApi); + expect(chu.validationErrors).to.be.empty; + return chu; +} + export const mockValidContactType = (propertyType: string, propertyValidator: string | string[] | undefined) : ContactType => ({ name: 'contacttype-name', friendly: 'friendly', @@ -94,12 +118,12 @@ export const mockValidContactType = (propertyType: string, propertyValidator: st export const mockParentPlace = (parentPlaceType: ContactType, parentName: string) => { const place = new Place(parentPlaceType); - place.properties.name = parentName; + place.properties.name = new UnvalidatedPropertyValue(parentName, 'name'); return place; }; -export const mockProperty = (type: string, parameter: string | string[] | undefined | object, property_name: string = 'prop'): ContactProperty => ({ - friendly_name: 'csv', +export const mockProperty = (type: string, parameter?: string | string[] | object, property_name: string = 'prop'): ContactProperty => ({ + friendly_name: `friendly ${property_name}`, property_name, type, parameter, @@ -107,16 +131,20 @@ export const mockProperty = (type: string, parameter: string | string[] | undefi }); // Constructor of class ChtSession is private and only accessible within the class declaration. -export const mockChtSession = (userFacilityId: string = '*') : ChtSession => new ChtSession( - { - friendly: 'domain', - domain: 'domain.com', - useHttp: true, - }, - 'session-token', - 'username', - userFacilityId -); +export function mockChtSession(userFacilityId: string = '*') : ChtSession { + const creationDetails = { + authInfo: { + friendly: 'domain', + domain: 'domain.com', + useHttp: true, + }, + sessionToken: 'session-token', + username: 'username', + facilityIds: [userFacilityId], + chtCoreVersion: '4.7.0', + }; + return new ChtSession(creationDetails); +} export function expectInvalidProperties( validationErrors: { [key: string]: string } | undefined, diff --git a/test/property-value.spec.ts b/test/property-value.spec.ts new file mode 100644 index 00000000..db279c7a --- /dev/null +++ b/test/property-value.spec.ts @@ -0,0 +1,58 @@ +import { expect } from 'chai'; +import { NamePropertyValue, PropertyValues, UnvalidatedPropertyValue } from '../src/property-value'; +import { ContactProperty } from '../src/config'; +import { mockProperty } from './mocks'; + +describe('property-value', () => { + const namePropertyValue: ContactProperty = mockProperty('name'); + const includeScenarios = [ + { searchWithin: 'abc', searchFor: 'bc', expected: true }, + { searchWithin: 'abc', searchFor: 'AbC', expected: true }, + { searchWithin: 'place', searchFor: '', expected: true }, + { searchWithin: 'plÀce', searchFor: 'lac', expected: true }, + { searchWithin: 'place', searchFor: 'À', expected: true }, + { searchWithin: 'plÀce', searchFor: 'lAc', expected: true }, + + { searchWithin: 'abc', searchFor: 'e', expected: false }, + { searchWithin: 'abc', searchFor: undefined, expected: false }, + { searchWithin: 'abc', searchFor: ' a', expected: false }, + { searchWithin: undefined, searchFor: 'a', expected: false }, + { searchWithin: undefined, searchFor: undefined, expected: false }, + + { searchWithin: new UnvalidatedPropertyValue('abc'), searchFor: 'a', expected: true }, + { searchWithin: new UnvalidatedPropertyValue('abc'), searchFor: 'a', expected: true }, + + { searchWithin: new NamePropertyValue('a.b.c', namePropertyValue), searchFor: 'a b c', expected: true }, + { searchWithin: new NamePropertyValue('a.b.c', namePropertyValue), searchFor: new NamePropertyValue('a.b c', namePropertyValue), expected: true }, + ]; + + const matchScenarios = [ + { a: 'abc', b: 'abc', expected: true }, + { a: 'abc', b: 'AbC', expected: true }, + { a: 'plÀce', b: 'PlacE', expected: true }, + { a: 'place', b: 'PlÀcE', expected: true }, + + { a: 'place', b: 'lÀc', expected: false }, + { a: undefined, b: 'abc', expected: false }, + { a: 'abc', b: undefined, expected: false }, + { a: undefined, b: undefined, expected: false }, + ]; + + describe('include', () => { + for (const scenario of includeScenarios) { + it(JSON.stringify(scenario), () => { + const actual = PropertyValues.includes(scenario.searchWithin, scenario.searchFor); + expect(actual).to.eq(scenario.expected); + }); + } + }); + + describe('isMatch', () => { + for (const scenario of matchScenarios) { + it(JSON.stringify(scenario), () => { + const actual = PropertyValues.isMatch(scenario.a, scenario.b); + expect(actual).to.eq(scenario.expected); + }); + } + }); +}); diff --git a/test/services/place-factory.spec.ts b/test/services/place-factory.spec.ts index 6c1ae46b..62fa4dd7 100644 --- a/test/services/place-factory.spec.ts +++ b/test/services/place-factory.spec.ts @@ -1,16 +1,21 @@ import _ from 'lodash'; +import Chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; import fs from 'fs'; -import { expect } from 'chai'; import sinon from 'sinon'; -import { expectInvalidProperties, mockChtSession, mockParentPlace, mockProperty, mockValidContactType } from '../mocks'; +import { ChtDoc, expectInvalidProperties, mockChtSession, mockParentPlace, mockProperty, mockValidContactType } from '../mocks'; import { Config } from '../../src/config'; import Place from '../../src/services/place'; import PlaceFactory from '../../src/services/place-factory'; -import { RemotePlace } from '../../src/lib/cht-api'; import RemotePlaceCache from '../../src/lib/remote-place-cache'; import RemotePlaceResolver from '../../src/lib/remote-place-resolver'; import SessionCache from '../../src/services/session-cache'; +import { UnvalidatedPropertyValue } from '../../src/property-value'; + +Chai.use(chaiAsPromised); + +const { expect } = Chai; describe('services/place-factory.ts', () => { beforeEach(() => { @@ -28,10 +33,10 @@ describe('services/place-factory.ts', () => { }); it('name conflict at remote yields invalid', async () => { - const { remotePlace, sessionCache, fakeFormData, contactType, chtApi } = mockScenario(); - const secondParent = _.cloneDeep(remotePlace); - secondParent.id = 'second-id'; - chtApi.getPlacesWithType.resolves([remotePlace, secondParent]); + const { parentDoc, sessionCache, fakeFormData, contactType, chtApi } = mockScenario(); + const secondParent = _.cloneDeep(parentDoc); + secondParent._id = 'second-id'; + chtApi.getPlacesWithType.resolves([parentDoc, secondParent]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); expectInvalidProperties(place.validationErrors, ['hierarchy_PARENT'], 'multiple'); @@ -41,7 +46,7 @@ describe('services/place-factory.ts', () => { const { sessionCache, fakeFormData, contactType, parentContactType, chtApi } = mockScenario(); const chu = new Place(parentContactType); - chu.properties.name = 'Demesi'; + chu.properties.name = new UnvalidatedPropertyValue('Demesi', 'name'); sessionCache.savePlaces(chu); fakeFormData.hierarchy_PARENT = 'Demesi '; @@ -49,41 +54,41 @@ describe('services/place-factory.ts', () => { const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); expect(place.validationErrors).to.be.empty; expect(place.resolvedHierarchy[1]?.id).to.eq(chu.id); - expect(place.hierarchyProperties.PARENT).to.eq('Demesi'); + expect(place.hierarchyProperties.PARENT.formatted).to.eq('Demesi'); }); it('bulk upload fuzzed parent matching', async () => { - const { remotePlace, sessionCache, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, fakeFormData, chtApi } = mockScenario(); - const nameValidator = ['Cu', 'Community Health Unit']; const contactType = mockValidContactType('string', undefined); + const nameValidatorParameter = ['Cu', 'Community Health Unit']; contactType.hierarchy[0] = { - ...mockProperty('name', nameValidator, 'PARENT'), + ...mockProperty('name', nameValidatorParameter, 'PARENT'), level: 1, contact_type: 'parent', }; - remotePlace.name = 'Cheplanget Cu'; + parentDoc.name = 'Cheplanget Cu'; fakeFormData.hierarchy_PARENT = 'Cheplanget Community Health Unit'; const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); + expect(place.validationErrors).to.be.empty; expect(place.resolvedHierarchy[1]?.id).to.eq('parent-id'); }); it('simple replacement', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); fakeFormData.hierarchy_replacement = 'to-replace'; - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: parentDoc._id }, }; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([parentDoc]) .onSecondCall().resolves([toReplace]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); @@ -93,11 +98,11 @@ describe('services/place-factory.ts', () => { }); it('invalid when name doesnt match any remote place', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - remotePlace.name = 'foobar'; + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + parentDoc.name = 'foobar'; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([parentDoc]) .onSecondCall().resolves([]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); @@ -105,19 +110,18 @@ describe('services/place-factory.ts', () => { }); it('simple eCHIS csv', async () => { - const { remotePlace, sessionCache, chtApi } = mockScenario(); + const { parentDoc, sessionCache, chtApi } = mockScenario(); - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'bob', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: parentDoc._id }, }; - remotePlace.name = 'Chepalungu CHU'; + parentDoc.name = 'Chepalungu CHU'; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([parentDoc]) .onSecondCall().resolves([toReplace]); const singleCsvBuffer = fs.readFileSync('./test/single.csv'); @@ -128,47 +132,58 @@ describe('services/place-factory.ts', () => { const [successfulPlace] = places; expect(successfulPlace).to.deep.nested.include({ - 'contact.properties.name': 'Sally', - 'contact.properties.phone': '0712 345678', + name: 'Sally Area', + 'contact.properties.name.formatted': 'Sally', + 'contact.properties.phone.formatted': '0712 345678', creationDetails: {}, - 'properties.name': 'Sally Area', - 'hierarchyProperties.CHU': 'Chepalungu', + 'properties.name.formatted': 'Sally Area', + 'hierarchyProperties.CHU.original': 'chepalungu', + 'hierarchyProperties.CHU.formatted': 'Chepalungu', resolvedHierarchy: [ { id: 'id-replace', - name: 'bob', + name: { + formatted: 'Bob', + original: 'bob', + propertyNameWithPrefix: 'place_name', + }, lineage: ['parent-id'], type: 'remote', }, { id: 'parent-id', - name: 'Chepalungu CHU', + name: { + formatted: 'Chepalungu', + original: parentDoc.name, + propertyNameWithPrefix: 'place_name', + }, type: 'remote', lineage: [], }, ], validationErrors: {}, + userRoleProperties: {}, + state: 'staged', }); }); it('ambiguous parent resolves if only one has the replacement', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: parentDoc._id }, }; fakeFormData.hierarchy_replacement = toReplace.name; const ambiguous = { - ...remotePlace, - id: 'id-parent-ambiguous', + ...parentDoc, + _id: 'id-parent-ambiguous', }; chtApi.getPlacesWithType - .resolves([remotePlace, ambiguous]) + .resolves([parentDoc, ambiguous]) .onSecondCall().resolves([toReplace]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); @@ -178,13 +193,11 @@ describe('services/place-factory.ts', () => { }); it('ambiguous greatgrandparent disambiguated by parent', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - const greatParent: RemotePlace = { - id: 'id-great-grandparent', + const greatParent: ChtDoc = { + _id: 'id-great-grandparent', name: 'great-grand-parent', - type: 'remote', - lineage: [], }; contactType.hierarchy[1] = { ...mockProperty('name', undefined, 'GREATGRANDPARENT'), @@ -193,65 +206,62 @@ describe('services/place-factory.ts', () => { required: false, }; fakeFormData.hierarchy_GREATGRANDPARENT = greatParent.name; - remotePlace.lineage[1] = greatParent.id; + parentDoc.parent = { /*_id: ?,*/ parent: { _id: greatParent._id } }; - const ambiguous = { + const ambiguous: ChtDoc = { ...greatParent, - id: 'ambiguous-great-grandparent', + _id: 'ambiguous-great-grandparent', }; chtApi.getPlacesWithType .resolves([greatParent, ambiguous]) - .onSecondCall().resolves([remotePlace]); + .onSecondCall().resolves([parentDoc]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); expect(place.validationErrors).to.be.empty; - expect(place.resolvedHierarchy[3]?.id).to.eq(greatParent.id); - expect(place.resolvedHierarchy[1]?.id).to.eq(remotePlace.id); + expect(place.resolvedHierarchy[3]?.id).to.eq(greatParent._id); + expect(place.resolvedHierarchy[1]?.id).to.eq(parentDoc._id); }); it('ambiguous parent disambiguated by grandparent', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - const grandParent: RemotePlace = { - id: 'id-grandparent', + const grandParent: ChtDoc = { + _id: 'id-grandparent', name: 'grand-parent', - type: 'remote', - lineage: [], }; fakeFormData.hierarchy_GRANDPARENT = grandParent.name; - const ambiguous = { - ...remotePlace, - id: 'id-ambiguous', + const ambiguous: ChtDoc = { + ...parentDoc, + _id: 'id-ambiguous', }; - remotePlace.lineage = [grandParent.id]; - ambiguous.lineage = ['not-grandpa']; + parentDoc.parent = { _id: grandParent._id }; + ambiguous.parent = { _id: 'not-grandpa' }; chtApi.getPlacesWithType .resolves([grandParent]) - .onSecondCall().resolves([remotePlace, ambiguous]); + .onSecondCall().resolves([parentDoc, ambiguous]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); expect(place.validationErrors).to.be.empty; - expect(place.resolvedHierarchy).to.deep.eq([undefined, remotePlace, grandParent]); + const resolvedHierarchyIds = place.resolvedHierarchy.map(h => h?.id); + expect(resolvedHierarchyIds).to.deep.eq([undefined, parentDoc._id, grandParent._id]); }); it('#91 - no result for optional level in hierarchy causes validation error', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - const grandParent: RemotePlace = { - id: 'id-grandparent', + const grandParent: ChtDoc = { + _id: 'id-grandparent', name: 'grand-parent', - type: 'remote', - lineage: [], }; - remotePlace.lineage = [grandParent.id]; + parentDoc.parent = { _id: grandParent._id }; fakeFormData.hierarchy_GRANDPARENT = 'no match'; chtApi.getPlacesWithType .resolves([grandParent]) - .onSecondCall().resolves([remotePlace]); + .onSecondCall().resolves([parentDoc]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); expect(place.resolvedHierarchy[2]).to.eq(RemotePlaceResolver.NoResult); @@ -259,20 +269,18 @@ describe('services/place-factory.ts', () => { }); it('hierarchy resolution can be resolved by editing to blank', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - const grandParent: RemotePlace = { - id: 'id-grandparent', + const grandParent: ChtDoc = { + _id: 'id-grandparent', name: 'grand-parent', - type: 'remote', - lineage: [], }; - remotePlace.lineage = [grandParent.id]; + parentDoc.parent = { _id: grandParent._id }; fakeFormData.hierarchy_GRANDPARENT = 'no match'; chtApi.getPlacesWithType .resolves([grandParent]) - .onSecondCall().resolves([remotePlace]); + .onSecondCall().resolves([parentDoc]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); expectInvalidProperties(place.validationErrors, ['hierarchy_PARENT', 'hierarchy_GRANDPARENT'], 'Cannot find'); @@ -283,13 +291,11 @@ describe('services/place-factory.ts', () => { }); it('ambiguous parent disambiguated by greatgrandparent', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - const greatParent: RemotePlace = { - id: 'id-great-grandparent', + const greatParent: ChtDoc = { + _id: 'id-great-grandparent', name: 'great-grand-parent', - type: 'remote', - lineage: [], }; contactType.hierarchy[1] = { ...mockProperty('name', undefined, 'GREATGRANDPARENT'), @@ -299,40 +305,39 @@ describe('services/place-factory.ts', () => { }; fakeFormData.hierarchy_GREATGRANDPARENT = greatParent.name; - const ambiguous = { - ...remotePlace, - id: 'id-ambiguous', + const ambiguous: ChtDoc = { + ...parentDoc, + _id: 'id-ambiguous', }; - remotePlace.lineage = ['no-matter', greatParent.id]; - ambiguous.lineage = ['not-grandpa', 'not-grandpa']; + parentDoc.parent = { _id: 'no-matter', parent: { _id: greatParent._id } }; + ambiguous.parent = { _id: 'not-grandpa', parent: { _id: 'not-grandpa' } }; chtApi.getPlacesWithType .resolves([greatParent]) - .onSecondCall().resolves([remotePlace, ambiguous]); + .onSecondCall().resolves([parentDoc, ambiguous]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); expect(place.validationErrors).to.be.empty; - expect(place.resolvedHierarchy).to.deep.eq([undefined, remotePlace, undefined, greatParent]); + const resolvedHierarchyIds = place.resolvedHierarchy.map(h => h?.id); + expect(resolvedHierarchyIds).to.deep.eq([undefined, parentDoc._id, undefined, greatParent._id]); }); it('ambiguous place under single parent is invalid', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); fakeFormData.hierarchy_replacement = 'to-replace'; - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace', - lineage: [remotePlace.id], - type: 'remote', }; - const ambiguous = { + const ambiguous: ChtDoc = { ...toReplace, - id: 'id-replace-ambiguous', - parentId: remotePlace.id, + _id: 'id-replace-ambiguous', + parentId: parentDoc._id, }; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([parentDoc]) .onSecondCall() .resolves([toReplace, ambiguous]); @@ -344,17 +349,16 @@ describe('services/place-factory.ts', () => { }); it('replacement place not under parent is invalid', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace', - lineage: ['different-parent'], - type: 'remote', + parent: { _id: 'different-parent' }, }; fakeFormData.hierarchy_replacement = toReplace.name; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([parentDoc]) .onSecondCall().resolves([toReplace]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); @@ -364,9 +368,9 @@ describe('services/place-factory.ts', () => { }); it('place not under users facility is invalid', async () => { - const { remotePlace, sessionCache, contactType, parentContactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, parentContactType, fakeFormData, chtApi } = mockScenario(); const parent1 = mockParentPlace(parentContactType, fakeFormData.hierarchy_PARENT); - chtApi.getPlacesWithType.resolves([remotePlace]); + chtApi.getPlacesWithType.resolves([parentDoc]); chtApi.chtSession = mockChtSession('other'); fakeFormData.hierarchy_PARENT = parent1.name; @@ -375,31 +379,30 @@ describe('services/place-factory.ts', () => { }); it('#124 - testing replacement when place.name is generated', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); fakeFormData.hierarchy_replacement = 'dne'; contactType.place_properties[0] = { friendly_name: '124', property_name: 'name', type: 'generated', + required: true, parameter: '{{contact.name}} Area', }; - const otherPlace: RemotePlace = { - id: 'other-place', + const otherPlace: ChtDoc = { + _id: 'other-place', name: 'other-place', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: parentDoc._id }, }; - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: parentDoc._id }, }; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([parentDoc]) .onSecondCall().resolves([toReplace, otherPlace]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); @@ -407,7 +410,7 @@ describe('services/place-factory.ts', () => { }); it('#124 - replacement_property is used for fuzzing during replacement', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + const { parentDoc, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); fakeFormData.hierarchy_replacement = 'to-replace'; contactType.replacement_property = { @@ -418,15 +421,14 @@ describe('services/place-factory.ts', () => { required: true }; - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace Area (village)', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: parentDoc._id }, }; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([parentDoc]) .onSecondCall().resolves([toReplace]); const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); @@ -435,31 +437,42 @@ describe('services/place-factory.ts', () => { expect(place.resolvedHierarchy[0]?.id).to.eq('id-replace'); }); - it('#124 - replacement_property cannot have type:"generated"', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); - fakeFormData.hierarchy_replacement = 'to-replace'; + it('assertion if data for a required level is totally missing', async () => { + const { sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + delete fakeFormData.hierarchy_PARENT; - contactType.replacement_property = { - friendly_name: 'Outgoing CHP', - property_name: 'replacement', + const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); + expectInvalidProperties(place.validationErrors, ['hierarchy_PARENT'], 'is empty'); + }); + + it('create a place even if generated property is required', async () => { + const { sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + contactType.place_properties[0] = { + friendly_name: 'CHP Area Name', + property_name: 'name', type: 'generated', parameter: '{{ contact.name }} Area', required: true }; + delete fakeFormData.place_name; - const toReplace: RemotePlace = { - id: 'id-replace', - name: 'to-replace Area', - lineage: [remotePlace.id], - type: 'remote', - }; + const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); + expect(place.validationErrors).to.be.empty; + }); - chtApi.getPlacesWithType - .resolves([remotePlace]) - .onSecondCall().resolves([toReplace]); + it('fail to create a place with missing generated property which is required', async () => { + const { sessionCache, contactType, fakeFormData, chtApi } = mockScenario(); + contactType.place_properties[0] = { + friendly_name: 'CHP Area Name', + property_name: 'name', + type: 'generated', + parameter: '{{ contact.dne }}', + required: true + }; + delete fakeFormData.place_name; - const createOne = PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); - await expect(createOne).to.eventually.be.rejectedWith('cannot be of type "generated"'); + const place: Place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); + expectInvalidProperties(place.validationErrors, ['place_name'], 'Required'); }); }); @@ -480,31 +493,28 @@ it('#165 - create a place when generated property is required', async () => { function mockScenario() { const contactType = mockValidContactType('string', undefined); - const remotePlace: RemotePlace = { - id: 'parent-id', + const parentDoc: ChtDoc = { + _id: 'parent-id', name: 'parent-name', - type: 'remote', - lineage: [], }; const sessionCache = new SessionCache(); const chtApi = { chtSession: mockChtSession(), - getPlacesWithType: sinon.stub().resolves([remotePlace]), + getPlacesWithType: sinon.stub().resolves([parentDoc]), createPlace: sinon.stub().resolves('created-place-id'), - updateContactParent: sinon.stub().resolves('created-contact-id'), createUser: sinon.stub().resolves(), }; const fakeFormData:any = { place_name: 'place', place_prop: 'foo', - hierarchy_PARENT: remotePlace.name, + hierarchy_PARENT: parentDoc.name, contact_name: 'contact', }; const parentContactType = mockValidContactType('string', undefined); parentContactType.name = contactType.hierarchy[0].contact_type; return { - remotePlace, + parentDoc, sessionCache, fakeFormData, parentContactType, diff --git a/test/services/place.spec.ts b/test/services/place.spec.ts index 4d172447..04f95898 100644 --- a/test/services/place.spec.ts +++ b/test/services/place.spec.ts @@ -2,28 +2,30 @@ import { expect } from 'chai'; import Place from '../../src/services/place'; import { mockSimpleContactType, mockValidContactType } from '../mocks'; -import RemotePlaceResolver from '../../src/lib/remote-place-resolver'; +import { UnvalidatedPropertyValue, ContactPropertyValue } from '../../src/property-value'; describe('services/place.ts', () => { it('setPropertiesFromFormData', () => { - const contactType = mockSimpleContactType('string', undefined); + const contactType = mockSimpleContactType('name', undefined); contactType.contact_properties = contactType.place_properties; const place = new Place(contactType); - place.properties.existing = 'existing'; + place.properties.existing = new ContactPropertyValue(place, contactType.place_properties[0], 'place_', 'existing'); const formData = { place_prop: 'abc', contact_prop: 'efg', garbage: 'ghj', }; - place.setPropertiesFromFormData(formData); + place.setPropertiesFromFormData(formData, 'hierarchy_'); - expect(place.properties).to.deep.eq({ - existing: 'existing', - prop: 'abc', + expect(place.properties).to.nested.include({ + 'existing.original': 'existing', + 'prop.original': 'abc', + 'prop.formattedValue': 'Abc', }); - expect(place.contact.properties).to.deep.eq({ - prop: 'efg', + expect(place.contact.properties).to.nested.include({ + 'prop.original': 'efg', + 'prop.formattedValue': 'Efg', }); }); @@ -31,13 +33,13 @@ describe('services/place.ts', () => { const contactType = mockSimpleContactType('string', undefined); contactType.contact_properties = contactType.place_properties; const place = new Place(contactType); - place.properties.existing = 'existing'; - place.properties.prop = 'abc'; - place.contact.properties.prop = 'efg'; - const actual = place.asFormData(); + place.properties.name = new UnvalidatedPropertyValue('name'); + place.properties.prop = new UnvalidatedPropertyValue('abc'); + place.contact.properties.prop = new UnvalidatedPropertyValue('efg'); + const actual = place.asFormData('hierachy_'); expect(actual).to.deep.eq({ - place_existing: 'existing', + place_name: 'name', place_prop: 'abc', contact_prop: 'efg', }); @@ -46,23 +48,23 @@ describe('services/place.ts', () => { it('basic asRemotePlace', () => { const contactType = mockSimpleContactType('string', undefined); const place = new Place(contactType); - place.properties.name = 'name'; + place.properties.name = new UnvalidatedPropertyValue('name'); place.resolvedHierarchy[0] = { id: 'to-replace', - name: 'replaced', + name: new UnvalidatedPropertyValue('replaced'), lineage: ['parent-id'], type: 'remote', }; place.resolvedHierarchy[1] = { id: 'parent-id', - name: 'parent', + name: new UnvalidatedPropertyValue('parent'), lineage: [], type: 'remote', }; const actual = place.asRemotePlace(); - expect(actual).to.deep.include({ - name: 'name', + expect(actual).to.deep.nested.include({ + 'name.original': 'name', type: 'local', lineage: ['parent-id'], }); @@ -71,40 +73,33 @@ describe('services/place.ts', () => { it('asRemotePlace with great grandfather (missing place in lineage)', () => { const contactType = mockSimpleContactType('string', undefined); const place = new Place(contactType); - place.properties.name = 'name'; + place.properties.name = new UnvalidatedPropertyValue('name'); place.resolvedHierarchy[0] = { id: 'to-replace', - name: 'replaced', + name: new UnvalidatedPropertyValue('replaced'), lineage: ['parent-id', 'grandparent-id', 'greatgrandparent-id'], type: 'remote', }; place.resolvedHierarchy[3] = { id: 'greatgrandparent-id', - name: 'greatgrandparent', + name: new UnvalidatedPropertyValue('greatgrandparent'), lineage: [], type: 'remote', }; const actual = place.asRemotePlace(); - expect(actual).to.deep.include({ - name: 'name', + expect(actual).to.deep.nested.include({ + 'name.original': 'name', type: 'local', lineage: ['parent-id', 'grandparent-id', 'greatgrandparent-id'], }); }); - it('asRemotePlace throws if hierarchy is invalid', () => { - const contactType = mockSimpleContactType('string', undefined); - const place = new Place(contactType); - place.resolvedHierarchy[1] = RemotePlaceResolver.Multiple; - expect(() => place.asRemotePlace()).to.throw('invalid hierarchy'); - }); - it('generateUsername shouldnt have double underscores', () => { const contactType = mockSimpleContactType('string', undefined); const place = new Place(contactType); - place.contact.properties.name = 'Migwani / Itoloni'; + place.contact.properties.name = new ContactPropertyValue(place, contactType.place_properties[0], 'place_', 'Migwani / Itoloni'); const actual = place.generateUsername(); expect(actual).to.eq('migwani_itoloni'); @@ -141,7 +136,6 @@ describe('services/place.ts', () => { contactType.user_role = ['role1', 'role2']; contactType.contact_properties = contactType.place_properties; const place = new Place(contactType); - place.properties.existing = 'existing'; const formData = { place_prop: 'abc', @@ -149,15 +143,8 @@ describe('services/place.ts', () => { garbage: 'ghj', user_role: 'role1 role2', }; - place.setPropertiesFromFormData(formData); + place.setPropertiesFromFormData(formData, 'hierarchy_'); - expect(place.properties).to.deep.eq({ - existing: 'existing', - prop: 'abc', - }); - expect(place.contact.properties).to.deep.eq({ - prop: 'efg', - }); expect(place.userRoles).to.deep.eq([ 'role1', 'role2', diff --git a/test/services/upload-manager.spec.ts b/test/services/upload-manager.spec.ts index f9a831d7..8c769d4d 100644 --- a/test/services/upload-manager.spec.ts +++ b/test/services/upload-manager.spec.ts @@ -3,10 +3,9 @@ import { expect } from 'chai'; import sinon from 'sinon'; import { UploadManager } from '../../src/services/upload-manager'; -import { mockValidContactType, mockParentPlace, mockChtSession, expectInvalidProperties } from '../mocks'; +import { mockValidContactType, mockParentPlace, mockChtSession, expectInvalidProperties, ChtDoc, createChu } from '../mocks'; import PlaceFactory from '../../src/services/place-factory'; import SessionCache from '../../src/services/session-cache'; -import { ChtApi, RemotePlace } from '../../src/lib/cht-api'; import RemotePlaceCache from '../../src/lib/remote-place-cache'; import { Config } from '../../src/config'; import RemotePlaceResolver from '../../src/lib/remote-place-resolver'; @@ -17,8 +16,8 @@ describe('services/upload-manager.ts', () => { RemotePlaceCache.clear({}); }); - it('mock data is properly sent to chtApi', async () => { - const { fakeFormData, contactType, chtApi, sessionCache, remotePlace } = await createMocks(); + it('mock data is properly sent to chtApi - standard', async () => { + const { fakeFormData, contactType, chtApi, sessionCache, subcounty } = await createMocks(); const place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); const uploadManager = new UploadManager(); @@ -31,11 +30,9 @@ describe('services/upload-manager.ts', () => { 'contact.name': 'contact', prop: 'foo', name: 'Place Community Health Unit', - parent: remotePlace.id, + parent: subcounty._id, contact_type: contactType.name, }); - expect(chtApi.updateContactParent.calledOnce).to.be.true; - expect(chtApi.updateContactParent.args[0]).to.deep.eq(['created-place-id']); expect(chtApi.createUser.calledOnce).to.be.true; const userPayload = chtApi.createUser.args[0][0]; @@ -49,19 +46,19 @@ describe('services/upload-manager.ts', () => { expect(place.isCreated).to.be.true; }); - it('mock data is properly sent to chtApi (sessionCache cache)', async () => { - const { fakeFormData, contactType, sessionCache, chtApi, remotePlace } = await createMocks(); + it('mock data is properly sent to chtApi - sessionCache cache', async () => { + const { fakeFormData, contactType, sessionCache, chtApi, subcounty } = await createMocks(); const parentContactType = mockValidContactType('string', undefined); - parentContactType.name = remotePlace.name; + parentContactType.name = subcounty.name; - const parentPlace = mockParentPlace(parentContactType, remotePlace.name); + const parentPlace = mockParentPlace(parentContactType, subcounty.name); sessionCache.savePlaces(parentPlace); const place = await PlaceFactory.createOne(fakeFormData, contactType, sessionCache, chtApi); const uploadManager = new UploadManager(); await uploadManager.doUpload([place], chtApi); - expect(chtApi.getPlacesWithType.calledTwice).to.be.true; + expect(chtApi.getPlacesWithType.callCount).to.eq(1); expect(chtApi.getPlacesWithType.args[0]).to.deep.eq(['parent']); expect(chtApi.deleteDoc.called).to.be.false; expect(place.isCreated).to.be.true; @@ -79,20 +76,19 @@ describe('services/upload-manager.ts', () => { }); it('required attributes can be inherited during replacement', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); + const { subcounty, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); fakeFormData.hierarchy_replacement = 'to-replace'; fakeFormData.place_prop = ''; // required during creation, but can be empty (ui) or undefined (csv) fakeFormData.place_name = undefined; - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: subcounty._id }, }; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([subcounty]) .onSecondCall() .resolves([toReplace]); @@ -109,21 +105,20 @@ describe('services/upload-manager.ts', () => { }); it('contact_type replacement with username_from_place:true', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); + const { subcounty, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); contactType.username_from_place = true; fakeFormData.hierarchy_replacement = 'replacement based username'; fakeFormData.place_name = ''; // optional due to replacement - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'replac"e$mENT baSed username', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: subcounty._id }, }; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([subcounty]) .onSecondCall() .resolves([toReplace]); @@ -139,21 +134,20 @@ describe('services/upload-manager.ts', () => { }); it('contact_type replacement with deactivate_users_on_replace:true', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); + const { subcounty, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); contactType.deactivate_users_on_replace = true; fakeFormData.hierarchy_replacement = 'deactivate me'; fakeFormData.place_name = ''; // optional due to replacement - const toReplace: RemotePlace = { - id: 'id-replace', + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'deactivate me', - lineage: [remotePlace.id], - type: 'remote', + parent: { _id: subcounty._id }, }; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([subcounty]) .onSecondCall() .resolves([toReplace]); @@ -163,10 +157,13 @@ describe('services/upload-manager.ts', () => { const uploadManager = new UploadManager(); await uploadManager.doUpload([place], chtApi); expect(chtApi.createUser.callCount).to.eq(1); - expect(chtApi.disableUsersWithPlace.called).to.be.false; + expect(chtApi.disableUser.called).to.be.false; expect(chtApi.deleteDoc.called).to.be.false; - expect(chtApi.deactivateUsersWithPlace.called).to.be.true; - expect(chtApi.deactivateUsersWithPlace.args[0][0]).to.eq('id-replace'); + expect(chtApi.updateUser.called).to.be.true; + expect(chtApi.updateUser.args[0][0]).to.deep.eq({ + username: 'user', + roles: ['deactivated'], + }); expect(place.isCreated).to.be.true; }); @@ -183,11 +180,11 @@ describe('services/upload-manager.ts', () => { }); it('uploading a chu and dependant chp where chp is created first', async () => { - const { remotePlace, sessionCache, chtApi } = await createMocks(); + const { subcounty, sessionCache, chtApi } = await createMocks(); chtApi.getPlacesWithType .resolves([]) // parent of chp - .onSecondCall().resolves([remotePlace]) // grandparent of chp (subcounty) + .onSecondCall().resolves([subcounty]) // grandparent of chp (subcounty) .onThirdCall().resolves([]); // chp replacements const chu_name = 'new chu'; @@ -203,7 +200,7 @@ describe('services/upload-manager.ts', () => { const chp = await PlaceFactory.createOne(chpData, chpType, sessionCache, chtApi); expectInvalidProperties(chp.validationErrors, ['hierarchy_CHU'], 'Cannot find'); - const chu = await createChu(remotePlace, chu_name, sessionCache, chtApi); + const chu = await createChu(subcounty, chu_name, sessionCache, chtApi); // refresh the chp await RemotePlaceResolver.resolveOne(chp, sessionCache, chtApi, { fuzz: true }); @@ -220,22 +217,17 @@ describe('services/upload-manager.ts', () => { // chu is created first expect(chtApi.createUser.args[0][0].roles).to.deep.eq(['community_health_assistant']); expect(chtApi.createUser.args[1][0].roles).to.deep.eq(['community_health_volunteer']); - - const cachedChus = await RemotePlaceCache.getPlacesWithType(chtApi, chu.type.name); - expect(cachedChus).to.have.property('length', 1); - const cachedChps = await RemotePlaceCache.getPlacesWithType(chtApi, chp.type.name); - expect(cachedChps).to.have.property('length', 1); }); it('failure to upload', async () => { - const { remotePlace, sessionCache, chtApi } = await createMocks(); + const { subcounty, sessionCache, chtApi } = await createMocks(); chtApi.createUser .throws({ response: { status: 404 }, toString: () => 'upload-error' }) .onSecondCall().resolves(); const chu_name = 'new chu'; - const chu = await createChu(remotePlace, chu_name, sessionCache, chtApi); + const chu = await createChu(subcounty, chu_name, sessionCache, chtApi); const uploadManager = new UploadManager(); await uploadManager.doUpload(sessionCache.getPlaces(), chtApi); @@ -258,23 +250,23 @@ describe('services/upload-manager.ts', () => { expect(chu.creationDetails.password).to.not.be.undefined; expect(chtApi.createPlace.callCount).to.eq(1); - expect(chtApi.updateContactParent.callCount).to.eq(1); expect(chtApi.createUser.callCount).to.eq(2); expect(chtApi.getParentAndSibling.called).to.be.false; expect(chtApi.createContact.called).to.be.false; expect(chtApi.updatePlace.called).to.be.false; expect(chtApi.deleteDoc.called).to.be.false; - expect(chtApi.disableUsersWithPlace.called).to.be.false; + expect(chtApi.disableUser.called).to.be.false; + expect(chtApi.updateUser.called).to.be.false; }); it('#146 - error details are clear when CHT returns a string', async () => { - const { remotePlace, sessionCache, chtApi } = await createMocks(); + const { subcounty, sessionCache, chtApi } = await createMocks(); const errorString = 'foo'; chtApi.createPlace.throws({ response: { data: errorString } }); const chu_name = 'new chu'; - const chu = await createChu(remotePlace, chu_name, sessionCache, chtApi); + const chu = await createChu(subcounty, chu_name, sessionCache, chtApi); const uploadManager = new UploadManager(); await uploadManager.doUpload(sessionCache.getPlaces(), chtApi); @@ -284,12 +276,12 @@ describe('services/upload-manager.ts', () => { }); it(`createUser is retried`, async() => { - const { remotePlace, sessionCache, chtApi } = await createMocks(); + const { subcounty, sessionCache, chtApi } = await createMocks(); chtApi.createUser.throws(UploadManagerRetryScenario.axiosError); const chu_name = 'new chu'; - const chu = await createChu(remotePlace, chu_name, sessionCache, chtApi); + const chu = await createChu(subcounty, chu_name, sessionCache, chtApi); const uploadManager = new UploadManager(); await uploadManager.doUpload(sessionCache.getPlaces(), chtApi); @@ -298,8 +290,8 @@ describe('services/upload-manager.ts', () => { expect(chu.uploadError).to.include('could not create user'); }); - it('mock data is properly sent to chtApi (multiple roles)', async () => { - const { fakeFormData, contactType, chtApi, sessionCache, remotePlace } = await createMocks(); + it('mock data is properly sent to chtApi - multiple roles', async () => { + const { fakeFormData, contactType, chtApi, sessionCache, subcounty } = await createMocks(); contactType.user_role = ['role1', 'role2']; fakeFormData.user_role = 'role1 role2'; @@ -316,11 +308,9 @@ describe('services/upload-manager.ts', () => { 'contact.name': 'contact', prop: 'foo', name: 'Place Community Health Unit', - parent: remotePlace.id, + parent: subcounty._id, contact_type: contactType.name, }); - expect(chtApi.updateContactParent.calledOnce).to.be.true; - expect(chtApi.updateContactParent.args[0]).to.deep.eq(['created-place-id']); expect(chtApi.createUser.calledOnce).to.be.true; const userPayload = chtApi.createUser.args[0][0]; @@ -334,19 +324,17 @@ describe('services/upload-manager.ts', () => { }); it('#173 - replacement when place has no primary contact', async () => { - const { remotePlace, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); - const toReplace: RemotePlace = { - id: 'id-replace', + const { subcounty, sessionCache, contactType, fakeFormData, chtApi } = await createMocks(); + const toReplace: ChtDoc = { + _id: 'id-replace', name: 'to-replace', - lineage: [remotePlace.id], - type: 'remote', }; chtApi.updatePlace.resolves({ _id: 'updated-place-id' }); fakeFormData.hierarchy_replacement = toReplace.name; chtApi.getPlacesWithType - .resolves([remotePlace]) + .resolves([subcounty]) .onSecondCall() .resolves([toReplace]); @@ -356,43 +344,31 @@ describe('services/upload-manager.ts', () => { const uploadManager = new UploadManager(); await uploadManager.doUpload([place], chtApi); expect(chtApi.deleteDoc.callCount).to.eq(0); + expect(chtApi.disableUser.callCount).to.eq(1); expect(place.isCreated).to.be.true; }); }); -async function createChu(remotePlace: RemotePlace, chu_name: string, sessionCache: any, chtApi: ChtApi) { - const chuType = Config.getContactType('c_community_health_unit'); - const chuData = { - hierarchy_SUBCOUNTY: remotePlace.name, - place_name: chu_name, - place_code: '676767', - place_link_facility_name: 'facility name', - place_link_facility_code: '23456', - contact_name: 'new cha', - contact_phone: '0712345678', - }; - const chu = await PlaceFactory.createOne(chuData, chuType, sessionCache, chtApi); - expect(chu.validationErrors).to.be.empty; - return chu; -} - async function createMocks() { const contactType = mockValidContactType('string', undefined); - const remotePlace: RemotePlace = { - id: 'parent-id', + const subcounty: ChtDoc = { + _id: 'parent-id', name: 'parent-name', - type: 'remote', - lineage: [], }; const sessionCache = new SessionCache(); const chtApi = { chtSession: mockChtSession(), - getPlacesWithType: sinon.stub().resolves([remotePlace]), - createPlace: sinon.stub().resolves('created-place-id'), - updateContactParent: sinon.stub().resolves('created-contact-id'), + getPlacesWithType: sinon.stub().resolves([subcounty]), + createPlace: sinon.stub().resolves({ placeId: 'created-place-id', contactId: 'created-contact-id' }), createUser: sinon.stub().resolves(), getParentAndSibling: sinon.stub().resolves({ parent: {}, sibling: {} }), + getUsersAtPlace: sinon.stub().resolves([{ + username: 'user', + place: [{ _id: 'id-replace' }] + }]), + disableUser: sinon.stub().resolves(), + updateUser: sinon.stub().resolves(), createContact: sinon.stub().resolves('replacement-contact-id'), updatePlace: sinon.stub().resolves({ _id: 'updated-place-id', @@ -401,16 +377,14 @@ async function createMocks() { }, }), deleteDoc: sinon.stub().resolves(), - disableUsersWithPlace: sinon.stub().resolves(['org.couchdb.user:disabled']), - deactivateUsersWithPlace: sinon.stub().resolves(), }; const fakeFormData: any = { place_name: 'place', place_prop: 'foo', - hierarchy_PARENT: remotePlace.name, + hierarchy_PARENT: subcounty.name, contact_name: 'contact' }; - return { fakeFormData, contactType, sessionCache, chtApi, remotePlace }; + return { fakeFormData, contactType, sessionCache, chtApi, subcounty }; } diff --git a/test/single.csv b/test/single.csv index 0989a531..36a37bc8 100644 --- a/test/single.csv +++ b/test/single.csv @@ -1,2 +1,2 @@ Outgoing CHP,CHU,CHP Area Name,CHP Name,CHP Phone -Bob,Chepalungu,Sally,Sally,0712345678 \ No newline at end of file +Bob,chepalungu,Sally,Sally,0712345678 \ No newline at end of file diff --git a/test/validation.spec.ts b/test/validation.spec.ts new file mode 100644 index 00000000..a85ee3a2 --- /dev/null +++ b/test/validation.spec.ts @@ -0,0 +1,206 @@ +import { DateTime } from 'luxon'; +import { expect } from 'chai'; + +import { mockPlace, mockSimpleContactType } from './mocks'; +import RemotePlaceResolver from '../src/lib/remote-place-resolver'; +import { UnvalidatedPropertyValue } from '../src/property-value'; + +type Scenario = { + type: string; + prop?: string; + isValid: boolean; + propertyParameter?: string | string[] | object; + formatted?: string; + propertyErrorDescription?: string; + error?: string; +}; + +const EMAIL_REGEX = '^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$'; +const GENDER_OPTIONS = { male: 'Male', female: 'Female' }; +const CANDIES_OPTIONS = { chocolate: 'Chocolate', strawberry: 'Strawberry' }; + +const scenarios: Scenario[] = [ + { type: 'string', prop: undefined, isValid: false, error: 'Required' }, + { type: 'string', prop: 'abc', isValid: true }, + { type: 'string', prop: ' ab\nc', isValid: true, formatted: 'abc' }, + { type: 'string', prop: 'Mr. Sand(m-a-n)', isValid: true, formatted: 'Mr. Sand(m-a-n)' }, + { type: 'string', prop: 'Université ', isValid: true, formatted: 'Université' }, + { type: 'string', prop: `Infirmière d'Etat`, isValid: true, formatted: `Infirmière d'Etat` }, + { type: 'string', prop: '', isValid: false, formatted: '', error: 'Required' }, + + { type: 'phone', prop: undefined, isValid: false, error: 'Required' }, + { type: 'phone', prop: '+254712345678', isValid: true, formatted: '0712 345678', propertyParameter: 'KE' }, + { type: 'phone', prop: '712345678', isValid: true, formatted: '0712 345678', propertyParameter: 'KE' }, + { type: 'phone', prop: '+254712345678', isValid: false, formatted: '0712 345678', propertyParameter: 'UG', error: 'Not a valid' }, + { type: 'phone', prop: '+17058772274', isValid: false, formatted: '(705) 877-2274', propertyParameter: 'KE', error: 'KE' }, + + { type: 'regex', prop: undefined, isValid: false, error: 'Required' }, + { type: 'regex', propertyParameter: '^\\d{6}$', prop: '123456', isValid: true }, + { type: 'regex', propertyParameter: '^\\d{6}$', prop: ' 123456 *&%', isValid: true, formatted: '123456' }, + { type: 'regex', propertyParameter: '^\\d{6}$', prop: '1234567', isValid: false, error: 'six digit', propertyErrorDescription: 'six digit number' }, + { type: 'regex', propertyParameter: EMAIL_REGEX, prop: 'email@address.com', isValid: true, formatted: 'email@address.com' }, + { type: 'regex', propertyParameter: EMAIL_REGEX, prop: '.com', isValid: false, propertyErrorDescription: 'valid email address', error: 'email' }, + { type: 'regex', propertyParameter: undefined, prop: 'abc', isValid: false, error: 'missing parameter' }, + + { type: 'name', prop: undefined, isValid: false, error: 'Required' }, + { type: 'name', prop: 'abc', isValid: true, formatted: 'Abc' }, + { type: 'name', prop: 'a b c', isValid: true, formatted: 'A B C' }, + { type: 'name', prop: 'Mr. Sand(m-a-n)', isValid: true, formatted: 'Mr Sand(m-a-n)' }, + { type: 'name', prop: 'WELDON KO(E)CH \n', isValid: true, formatted: 'Weldon Ko(e)ch' }, + { type: 'name', prop: 'S \'am \'s', isValid: true, formatted: 'S\'am\'s' }, + { type: 'name', prop: 'KYAMBOO/KALILUNI', isValid: true, formatted: 'Kyamboo / Kaliluni' }, + { type: 'name', prop: 'NZATANI / ILALAMBYU', isValid: true, formatted: 'Nzatani / Ilalambyu' }, + { type: 'name', prop: 'Sam\'s CHU', propertyParameter: ['CHU', 'Comm Unit'], isValid: true, formatted: 'Sam\'s' }, + { type: 'name', prop: 'Jonathan M.Barasa', isValid: true, formatted: 'Jonathan M Barasa' }, + { type: 'name', prop: 'Robert xiv', isValid: true, formatted: 'Robert XIV' }, + { type: 'name', prop: ' ', isValid: true, formatted: '' }, + + { type: 'dob', prop: undefined, isValid: false, error: 'Required' }, + { type: 'dob', prop: '', isValid: false }, + { type: 'dob', prop: '2016/05/25', isValid: false }, + { type: 'dob', prop: 'May 25, 2016', isValid: false }, + { type: 'dob', prop: '2030-05-25', isValid: false }, + { type: 'dob', prop: '2016-05-25', isValid: true, formatted: '2016-05-25' }, + { type: 'dob', prop: ' 20 16- 05- 25 ', isValid: true, formatted: '2016-05-25' }, + { type: 'dob', prop: '20', isValid: true, formatted: DateTime.now().minus({ years: 20 }).toISODate() }, + { type: 'dob', prop: ' 20 ', isValid: true, formatted: DateTime.now().minus({ years: 20 }).toISODate() }, + { type: 'dob', prop: 'abc', isValid: false, formatted: 'abc' }, + { type: 'dob', prop: ' 1 0 0 ', isValid: true, formatted: DateTime.now().minus({ years: 100 }).toISODate() }, + { type: 'dob', prop: '-1', isValid: false, formatted: '-1' }, + { type: 'dob', prop: '15/2/1985', isValid: true, formatted: '1985-02-15' }, + { type: 'dob', prop: '1/2/1 985', isValid: true, formatted: '1985-02-01' }, + { type: 'dob', prop: '1/13/1985', isValid: false }, + + { type: 'select_one', prop: undefined, isValid: false, error: 'Required' }, + { type: 'select_one', prop: ' male', isValid: true, propertyParameter: GENDER_OPTIONS }, + { type: 'select_one', prop: 'female ', isValid: true, propertyParameter: GENDER_OPTIONS }, + { type: 'select_one', prop: 'FeMale ', isValid: false, propertyParameter: GENDER_OPTIONS }, + { type: 'select_one', prop: 'f', isValid: false, propertyParameter: GENDER_OPTIONS }, + { type: 'select_one', prop: '', isValid: false, propertyParameter: GENDER_OPTIONS }, + + { type: 'select_multiple', prop: undefined, isValid: false, error: 'Required' }, + { type: 'select_multiple', prop: 'chocolate', isValid: true, propertyParameter: CANDIES_OPTIONS }, + { type: 'select_multiple', prop: 'chocolate strawberry', isValid: true, propertyParameter: CANDIES_OPTIONS }, + { type: 'select_multiple', prop: ' chocolate strawberry', isValid: true, propertyParameter: CANDIES_OPTIONS }, + { type: 'select_multiple', prop: 'c,s', isValid: false, propertyParameter: CANDIES_OPTIONS, error: 'Invalid values' }, + { type: 'select_multiple', prop: '', isValid: false, propertyParameter: CANDIES_OPTIONS, error: 'Required' }, + + { type: 'generated', prop: 'b', propertyParameter: 'a {{ place.prop }} c', isValid: true, formatted: 'a b c' }, + { type: 'generated', prop: 'b', propertyParameter: '{{ contact.name }} ({{ lineage.PARENT }})', isValid: true, formatted: 'Contact (Parent)' }, + { type: 'generated', prop: 'b', propertyParameter: 'x {{ contact.dne }}', isValid: true, formatted: 'x ' }, +]; + +describe('validation', () => { + for (const scenario of scenarios) { + it(`scenario: ${JSON.stringify(scenario)}`, () => { + const contactType = mockSimpleContactType(scenario.type, scenario.propertyParameter, scenario.propertyErrorDescription); + contactType.contact_properties = [contactType.place_properties[0]]; + const place = mockPlace(contactType, { place_prop: scenario.prop }); + + const actualValidity = Object.keys(place.validationErrors || {}); + expect(actualValidity).to.deep.eq(scenario.isValid ? [] : ['place_prop']); + + if (scenario.error) { + const firstError = Object.values(place.validationErrors || {})[0]; + expect(firstError).to.include(scenario.error); + } + + expect(place.properties.prop.formatted).to.eq(scenario.formatted ?? scenario.prop); + }); + } + + it('unknown property type throws', () => { + const contactType = mockSimpleContactType('unknown`', undefined); + expect(() => mockPlace(contactType)).to.throw('unvalidatable'); + }); + + it('property with required:false can be empty', () => { + const contactType = mockSimpleContactType('string', undefined); + contactType.place_properties[contactType.place_properties.length-1].required = false; + + const place = mockPlace(contactType); + place.properties = { name: new UnvalidatedPropertyValue('name') }; + place.hierarchyProperties = { PARENT: new UnvalidatedPropertyValue('parent', 'PARENT') }; + + place.validate(); + expect(place.validationErrors).to.be.empty; + }); + + it('#91 - parent is invalid when required:false but resolution is NoResult', () => { + const contactType = mockSimpleContactType('string', undefined); + contactType.hierarchy[0].required = false; + + const place = mockPlace(contactType); + place.resolvedHierarchy[1] = RemotePlaceResolver.NoResult; + + place.validate(); + expect(place.validationErrors).to.deep.eq({ + hierarchy_PARENT: `Cannot find 'parent' matching 'parent'` + }); + }); + + it('parent is invalid when missing but expected', () => { + const contactType = mockSimpleContactType('string', undefined); + const place = mockPlace(contactType); + delete place.resolvedHierarchy[1]; + + place.validate(); + expect(place.validationErrors).to.deep.eq({ + hierarchy_PARENT: `Cannot find 'parent' matching 'parent'`, + }); + }); + + it('parent is valid when missing and not expected', () => { + const contactType = mockSimpleContactType('string', undefined); + contactType.hierarchy[0].required = false; + + const place = mockPlace(contactType); + delete place.resolvedHierarchy[1]; + + place.validate(); + expect(place.validationErrors).to.be.empty; + }); + + it('replacement property is validated and formatted as property_name:name', () => { + const contactType = mockSimpleContactType('string', undefined); + + const place = mockPlace(contactType, { hierarchy_replacement: 'sin bad' }); + expect(place.hierarchyProperties.replacement.formatted).to.eq('Sin Bad'); + + place.validate(); + expect(place.validationErrors).to.deep.eq({ + hierarchy_replacement: `Cannot find 'contacttype-name' matching 'sin bad' under 'parent'`, + }); + }); + + it('user_role property empty throws', () => { + const contactType = mockSimpleContactType('string', undefined); + contactType.user_role = []; + + expect(() => mockPlace(contactType)).to.throw('unvalidatable'); + }); + + it('user_role property contains empty string throws', () => { + const contactType = mockSimpleContactType('string', undefined); + contactType.user_role = ['']; + + expect(() => mockPlace(contactType)).to.throw('unvalidatable'); + }); + + it('user role is invalid when not allowed', () => { + const contactType = mockSimpleContactType('string', undefined); + contactType.user_role = ['supervisor', 'stock_manager']; + + const place = mockPlace(contactType, { + place_prop: 'abc', + contact_prop: 'efg', + garbage: 'ghj', + user_role: 'supervisor stockmanager', + }); + + place.validate(); + expect(place.validationErrors).to.deep.eq({ + user_role: `Invalid values for property "Roles": stockmanager` + }); + }); +}); diff --git a/test/worker/cht-conf-worker.spec.ts b/test/worker/cht-conf-worker.spec.ts new file mode 100644 index 00000000..6f76f64c --- /dev/null +++ b/test/worker/cht-conf-worker.spec.ts @@ -0,0 +1,125 @@ +import Chai from 'chai'; +import Sinon from 'sinon'; +import chaiAsPromised from 'chai-as-promised'; +Chai.use(chaiAsPromised); + +import Auth from '../../src/lib/authentication'; +import { ChtConfWorker } from '../../src/worker/cht-conf-worker'; +import { HierarchyAction } from '../../src/lib/manage-hierarchy'; +import { mockChtSession } from '../mocks'; + +const { expect } = Chai; + +const mockMonitoringResponse = (backlog) => ({ data: { sentinel: { backlog } } }); +describe('worker/cht-conf-worker', () => { + let executeStub; + let monitoringStub; + + beforeEach(() => { + executeStub = Sinon.stub().resolves(true); + monitoringStub = Sinon.stub().resolves(mockMonitoringResponse(10)); + ChtConfWorker.fetchMonitoringApi = monitoringStub; + ChtConfWorker.executeCommand = executeStub; + + const now = new Date('1-1-2000'); + Sinon.useFakeTimers(now); + }); + + afterEach(() => { + Sinon.restore(); + }); + + describe('handleJob', () => { + it('move contacts', async () => { + const job = mockJob('move'); + await ChtConfWorker.handleJob(job); + + expect(executeStub.calledOnce).to.be.true; + expect(executeStub.args[0][1]).to.deep.eq([ + '--url=https://hostname', + '--session-token=session-token', + '--force', + 'move-contacts', + 'upload-docs', + '--', + '--contacts=sourceId', + '--parent=destinationId', + ]); + }); + + it('merge contacts', async () => { + const job = mockJob('merge'); + await ChtConfWorker.handleJob(job); + + expect(executeStub.calledOnce).to.be.true; + expect(executeStub.args[0][1]).to.deep.eq([ + '--url=https://hostname', + '--session-token=session-token', + '--force', + 'merge-contacts', + 'upload-docs', + '--', + '--sources=sourceId', + '--destination=destinationId', + '--merge-primary-contacts', + '--disable-users', + ]); + }); + + it('delete contacts', async () => { + const job = mockJob('delete'); + await ChtConfWorker.handleJob(job); + + expect(executeStub.calledOnce).to.be.true; + expect(executeStub.args[0][1]).to.deep.eq([ + '--url=https://hostname', + '--session-token=session-token', + '--force', + 'delete-contacts', + 'upload-docs', + '--', + '--contacts=sourceId', + '--disable-users', + ]); + }); + + it('log and throw when execution fails', async () => { + executeStub.rejects('failure'); + const job = mockJob('delete'); + const actual = ChtConfWorker.handleJob(job); + await expect(actual).to.eventually.be.rejectedWith('following error: failure'); + + expect(job.log.calledOnce).to.be.true; + expect(job.log.args[0][0]).to.include('following error: failure'); + }); + + it('sentinel backlog causes postpone', async () => { + monitoringStub.resolves(mockMonitoringResponse(10000)); + const job = mockJob('move'); + const actual = ChtConfWorker.handleJob(job); + await expect(actual).to.eventually.be.rejectedWith(); + expect(executeStub.callCount).to.eq(0); + + expect(job.log.calledOnce).to.be.true; + expect(job.log.args[0][0]).to.include('backlog too high'); + expect(job.log.args[0][0]).to.include('until 4:00 AM'); + }); + }); +}); + +function mockJob(action: HierarchyAction) { + const session = mockChtSession(); + + return { + log: Sinon.stub(), + moveToDelayed: Sinon.stub(), + data: { + sourceId: 'sourceId', + destinationId: 'destinationId', + action, + sessionToken: Auth.encodeTokenForWorker(session), + instanceUrl: 'https://hostname' + } + }; +} +